25 changed files with 288 additions and 145 deletions
+2
View File
@@ -86,3 +86,5 @@ dkms.conf
*.out *.out
*.app *.app
# Custom
bin/*
+6 -2
View File
@@ -1,7 +1,11 @@
FROM gcc:latest FROM gcc:latest
RUN g++ src/*.cpp -o Bowling
WORKDIR /app WORKDIR /app
COPY bin/Bowling /app/ COPY rolls.txt /app/
CMD ["./Bowling"] #RUN g++ src/*.cpp -o Bowling
CMD ["./Bowling", "rolls.txt"]
-13
View File
@@ -1,13 +0,0 @@
#ifndef FILEHELPER_H
#define FILEHELPER_H
class FileHelper {
public:
FileHelper();
~FileHelper();
static bool FileExists(char *path);
};
#endif
-16
View File
@@ -1,16 +0,0 @@
#ifndef FILEREADER_H
#define FILEREADER_H
#include <string>
#include <vector>
class FileReader {
public:
FileReader();
~FileReader();
static std::string GetFile(char *path);
};
#endif
-18
View File
@@ -1,18 +0,0 @@
#ifndef NUMBERHELPER_H
#define NUMBERHELPER_H
#include <string>
#include <vector>
using namespace std;
class NumberHelper {
public:
NumberHelper();
~NumberHelper();
static vector<int> GetNumbers(string csv);
};
#endif
-18
View File
@@ -1,18 +0,0 @@
#ifndef PRINTFRAMES_H
#define PRINTFRAMES_H
#include <vector>
using namespace std;
class PrintFrames {
public:
PrintFrames();
~PrintFrames();
static void PrintHeader(vector<int> rolls);
static void PrintValue(vector<int> rolls);
};
#endif
+7 -1
View File
@@ -1,3 +1,9 @@
# Bowling # Bowling
If you want to try out the project, please use git clone with the HTTPS link to the repo, and not the SSH link, as only the owner can pull and push via SSH. To run the project, simply follow these steps:
1. `git clone https://git.rbwr.dk/owner/Bowling.git`
2. `cd Bowling/`
2. `docker build -t bowling .`
3. `docker run --rm bowling`
To change bowling score, simply edit the `rolls.txt` file, and build the docker image again.
BIN
View File
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
#ifndef FILEHELPER_H
#define FILEHELPER_H
class FileHelper {
public:
FileHelper() = default;
~FileHelper() = default;
static bool fileExists(char *path);
};
#endif
+18
View File
@@ -0,0 +1,18 @@
#ifndef FILEREADER_H
#define FILEREADER_H
#include <string>
#include <vector>
using namespace std;
class FileReader {
public:
FileReader() = default;
~FileReader() = default;
static string getFile(char *path);
};
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef FRAME_H
#define FRAME_H
#include <vector>
using namespace std;
struct Frame {
vector<int> Roll;
};
#endif
+27
View File
@@ -0,0 +1,27 @@
#ifndef NUMBERHELPER_H
#define NUMBERHELPER_H
#include <string>
#include <vector>
#include "../include/Frame.h"
using namespace std;
class NumberHelper {
public:
NumberHelper() = default;
~NumberHelper() = default;
static vector<int> getRolls(string csv);
static bool validateRolls(vector<int> rolls);
static vector<Frame> createFrames(vector<int> rolls);
private:
static Frame CreateStrikeFrame(int i);
static Frame CreateFreeFrame(int i, int j);
static Frame CreateBonusFrame(int i, int j, int k);
};
#endif
+18
View File
@@ -0,0 +1,18 @@
#ifndef PRINTFRAMES_H
#define PRINTFRAMES_H
#include <vector>
using namespace std;
class PrintFrames {
public:
PrintFrames() = default;
~PrintFrames() = default;
static void printHeader(vector<int> rolls);
static void printValue(vector<int> rolls);
};
#endif
@@ -3,16 +3,17 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "../include/Frame.h"
using namespace std; using namespace std;
class ScoreCalculator { class ScoreCalculator {
public: public:
ScoreCalculator(); ScoreCalculator() = default;
~ScoreCalculator(); ~ScoreCalculator() = default;
static int GetScore(vector<int> rolls); static int getScore(vector<Frame> rolls);
}; };
#endif #endif
-3
View File
@@ -1,4 +1 @@
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 1
2, 3, 5, 4, 9, 1, 2, 5, 3, 2, 4, 2, 3, 3, 4, 6, 10, 3, 2 2, 3, 5, 4, 9, 1, 2, 5, 3, 2, 4, 2, 3, 3, 4, 6, 10, 3, 2
-1
View File
@@ -1 +0,0 @@
10, 3, 2, 2, 3, 5, 4, 9, 1, 2, 5, 3, 2, 4, 2, 3, 3, 4, 6
+1
View File
@@ -0,0 +1 @@
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
+1
View File
@@ -0,0 +1 @@
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+1
View File
@@ -0,0 +1 @@
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 5, 5
+2 -5
View File
@@ -1,10 +1,7 @@
#include "../Include/FileHelper.h" #include "../include/FileHelper.h"
#include <sys/stat.h> #include <sys/stat.h>
FileHelper::FileHelper() {}; bool FileHelper::fileExists(char *path){
FileHelper::~FileHelper() {};
bool FileHelper::FileExists(char *path){
struct stat s; struct stat s;
// Check if file exists, and if it isn't a folder. // Check if file exists, and if it isn't a folder.
+6 -8
View File
@@ -1,16 +1,14 @@
#include "../Include/FileReader.h" #include "../include/FileReader.h"
#include <string> #include <string>
#include <fstream> #include <fstream>
FileReader::FileReader() {}; string FileReader::getFile(char *path){
FileReader::~FileReader() {}; ifstream file(path);
std::string FileReader::GetFile(char *path){ string line;
std::ifstream file(path);
std::string line; // There is only one line in the file
getline(file, line);
std::getline(file, line);
file.close(); file.close();
+122 -10
View File
@@ -1,19 +1,131 @@
#include "../Include/NumberHelper.h" #include "../include/NumberHelper.h"
#include <iostream>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
NumberHelper::NumberHelper() {}; vector<int> NumberHelper::getRolls(string csv){
NumberHelper::~NumberHelper() {}; vector<int> rolls;
stringstream ss(csv);
string number;
std::vector<int> NumberHelper::GetNumbers(std::string csv){ // Get number from the CSV file, split by comma, and convert to int.
std::vector<int> rolls; while (getline(ss, number, ',')) {
std::stringstream ss(csv); rolls.push_back(stoi(number));
std::string number;
while (std::getline(ss, number, ',')) {
rolls.push_back(std::stoi(number));
} }
return rolls; return rolls;
} }
bool NumberHelper::validateRolls(vector<int> rolls){
int rollCount = rolls.size();
for(int i = 0; i < rollCount; ++i) {
if(rolls[i] > 10 || rolls[i] < 0) {
cerr << "Number: " << rolls[i] << " is invalid.";
return false;
}
}
// A game can not have less than 12 rolls, and more than 21.
if (rollCount < 12 || rollCount > 21) {
cerr << "Incorrect amount of rolls.";
return false;
}
// 10th frame rule.
if (rollCount == 21) {
if (rolls[18] != 10 && rolls[18] + rolls[19] != 10) {
return false;
}
}
return true;
}
vector<Frame> NumberHelper::createFrames(vector<int> rolls){
vector<Frame> frame;
int roll = 0;
while (roll != rolls.size())
{
// Strike
if (rolls[roll] == 10)
{
// If we're on our last frame, and roll a strike, we're given two bonus rolls.
if (roll + 3 == rolls.size() && rolls[roll - 3] == 10) {
frame.push_back(CreateBonusFrame(rolls[roll], rolls[roll + 1], rolls[roll + 2]));
break;
}
frame.push_back(CreateStrikeFrame(10));
roll += 1;
}
// Spare
else if (rolls[roll] + rolls[roll + 1] == 10)
{
// If we're on our last frame, and roll a spare, we're given a bonus roll.
if (roll + 3 == rolls.size() && rolls[roll] + rolls[roll + 1] == 10)
{
frame.push_back(CreateBonusFrame(rolls[roll], rolls[roll + 1], rolls[roll + 2]));
break;
}
frame.push_back(CreateFreeFrame(rolls[roll], rolls[roll + 1]));
roll += 2;
}
// Open Frame
else
{
frame.push_back(CreateFreeFrame(rolls[roll], rolls[roll + 1]));
roll += 2;
}
}
return frame;
}
Frame NumberHelper::CreateStrikeFrame(int i){
struct Frame frame = Frame();
vector<int> rolls;
rolls.push_back(i);
frame.Roll = rolls;
return frame;
}
Frame NumberHelper::CreateFreeFrame(int i, int j){
struct Frame frame = Frame();
vector<int> rolls;
rolls.push_back(i);
rolls.push_back(j);
frame.Roll = rolls;
return frame;
}
Frame NumberHelper::CreateBonusFrame(int i, int j, int k){
struct Frame frame = Frame();
vector<int> rolls;
rolls.push_back(i);
rolls.push_back(j);
rolls.push_back(k);
frame.Roll = rolls;
return frame;
}
+8 -8
View File
@@ -1,10 +1,7 @@
#include "../Include/PrintFrames.h" #include "../include/PrintFrames.h"
#include <iostream> #include <iostream>
PrintFrames::PrintFrames() {}; void PrintFrames::printHeader(vector<int> rolls){
PrintFrames::~PrintFrames() {};
void PrintFrames::PrintHeader(vector<int> rolls){
int frame = 0; int frame = 0;
int i = 1; int i = 1;
@@ -13,7 +10,7 @@ void PrintFrames::PrintHeader(vector<int> rolls){
// Strike // Strike
if (rolls[frame] == 10) { if (rolls[frame] == 10) {
// If we're on our last frame, and roll a 10. // If we're on our last frame, and roll a strike, we're given two bonus rolls.
if (frame + 3 == rolls.size() && rolls[frame - 3] == 10) { if (frame + 3 == rolls.size() && rolls[frame - 3] == 10) {
cout << " f" << i << " |" << endl; cout << " f" << i << " |" << endl;
break; break;
@@ -25,6 +22,7 @@ void PrintFrames::PrintHeader(vector<int> rolls){
// Spare // Spare
else if (rolls[frame] + rolls[frame + 1] == 10) { else if (rolls[frame] + rolls[frame + 1] == 10) {
// If we're on our last frame, and roll a spare, we're given a bonus roll.
if (frame + 3 == rolls.size() && rolls[frame] + rolls[frame + 1] == 10) if (frame + 3 == rolls.size() && rolls[frame] + rolls[frame + 1] == 10)
{ {
cout << " f" << i << " |" << endl; cout << " f" << i << " |" << endl;
@@ -43,6 +41,7 @@ void PrintFrames::PrintHeader(vector<int> rolls){
++i; ++i;
// No more frames
if (frame == rolls.size()) { if (frame == rolls.size()) {
cout << "|" << endl; cout << "|" << endl;
break; break;
@@ -50,7 +49,7 @@ void PrintFrames::PrintHeader(vector<int> rolls){
} }
} }
void PrintFrames::PrintValue(vector<int> rolls){ void PrintFrames::printValue(vector<int> rolls){
int frame = 0; int frame = 0;
while (true) { while (true) {
@@ -58,7 +57,7 @@ void PrintFrames::PrintValue(vector<int> rolls){
// Strike // Strike
if (rolls[frame] == 10) { if (rolls[frame] == 10) {
// If we're on our last frame, and roll a 10. // If we're on our last frame, and roll a strike, we're given two bonus rolls.
if (frame + 3 == rolls.size() && rolls[frame - 3] == 10) { if (frame + 3 == rolls.size() && rolls[frame - 3] == 10) {
if (rolls[frame + 1] == 10 && rolls[frame + 2] == 10) { if (rolls[frame + 1] == 10 && rolls[frame + 2] == 10) {
cout << "X, X, X|" << endl; cout << "X, X, X|" << endl;
@@ -85,6 +84,7 @@ void PrintFrames::PrintValue(vector<int> rolls){
// Spare // Spare
else if (rolls[frame] + rolls[frame + 1] == 10) { else if (rolls[frame] + rolls[frame + 1] == 10) {
// If we're on our last frame, and roll a spare, we're given a bonus roll.
if (frame + 3 == rolls.size() && rolls[frame] + rolls[frame + 1] == 10) if (frame + 3 == rolls.size() && rolls[frame] + rolls[frame + 1] == 10)
{ {
cout << rolls[frame] << ", /" << ", " << rolls[frame + 1] << "|" << endl; cout << rolls[frame] << ", /" << ", " << rolls[frame + 1] << "|" << endl;
+25 -29
View File
@@ -1,46 +1,42 @@
#include "../Include/ScoreCalculator.h" #include "../include/ScoreCalculator.h"
#include "../include/Frame.h"
ScoreCalculator::ScoreCalculator() {}; int ScoreCalculator::getScore(vector<Frame> frames) {
ScoreCalculator::~ScoreCalculator() {};
int ScoreCalculator::GetScore(vector<int> rolls) {
int score = 0; int score = 0;
int frame = 0;
while (true) { // There can only be 10 frames.
for (int i = 0; i < 10; i++) {
// Strike // Strike
if (rolls[frame] == 10) { if (frames[i].Roll[0] == 10) {
// If we're on our last frame, and roll a 10. if (frames[i].Roll.size() == 3) {
if (frame + 3 == rolls.size() && rolls[frame - 3] == 10) { score += frames[i].Roll[0] + frames[i].Roll[1] + frames[i].Roll[2];
score += 10 + rolls[frame + 1] + rolls[frame + 2]; continue;
break;
} }
score += 10 + rolls[frame + 1] + rolls[frame + 2]; // If the next frame has 3 or 2 rolls, then take those 2.
frame += 1; if (frames[i + 1].Roll.size() > 1) {
score += frames[i].Roll[0] + frames[i + 1].Roll[0] + frames[i + 1].Roll[1];
continue;
}
// [10] + [x] + [y]
score += frames[i].Roll[0] + frames[i + 1].Roll[0] + frames[i + 2].Roll[0];
continue; continue;
} }
// Spare // Spare
if (rolls[frame] + rolls[frame + 1] == 10) { if (frames[i].Roll[0] + frames[i].Roll[1] == 10) {
if (frame + 3 == rolls.size() && rolls[frame] + rolls[frame + 1] == 10) if (frames[i].Roll.size() == 3) {
{ score += frames[i].Roll[0] + frames[i].Roll[1] + frames[i].Roll[2];
score += 10 + rolls[frame + 1];
break;
}
score += 10 + rolls[frame + 2];
frame += 2;
continue; continue;
} }
// Open Frame score += 10 + frames[i + 1].Roll[0];
score += rolls[frame] + rolls[frame + 1]; continue;
frame += 2;
if (frame == rolls.size()) {
break;
} }
// Open frame
score += frames[i].Roll[0] + frames[i].Roll[1];
} }
return score; return score;
+17 -11
View File
@@ -1,10 +1,10 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "../Include/FileReader.h" #include "../include/FileReader.h"
#include "../Include/FileHelper.h" #include "../include/FileHelper.h"
#include "../Include/NumberHelper.h" #include "../include/NumberHelper.h"
#include "../Include/ScoreCalculator.h" #include "../include/ScoreCalculator.h"
#include "../Include/PrintFrames.h" #include "../include/PrintFrames.h"
using namespace std; using namespace std;
@@ -14,18 +14,24 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
if (!FileHelper::FileExists(argv[1])) { if (!FileHelper::fileExists(argv[1])) {
cerr << "Filepath: " << argv[1] << " doesn't exist."; cerr << "Filepath: " << argv[1] << " doesn't exist.";
return 0; return 0;
} }
string file = FileReader::GetFile(argv[1]); string file = FileReader::getFile(argv[1]);
vector<int> rolls = NumberHelper::GetNumbers(file); vector<int> rolls = NumberHelper::getRolls(file);
PrintFrames::PrintHeader(rolls); if (!NumberHelper::validateRolls(rolls)) {
PrintFrames::PrintValue(rolls); return 0;
}
int score = ScoreCalculator::GetScore(rolls); PrintFrames::printHeader(rolls);
PrintFrames::printValue(rolls);
vector<Frame> frames = NumberHelper::createFrames(rolls);
int score = ScoreCalculator::getScore(frames);
cout << "Score: " << score << endl; cout << "Score: " << score << endl;
return 0; return 0;