|
@@ -6,7 +6,7 @@
|
|
|
std::array<Vector, 8> Game::neighbours;
|
|
|
std::array<Vector, 9 * 5> Game::fieldVectors;
|
|
|
|
|
|
-Game::Game() : active(-1, -1), direction(0, 0), mustTake(false), lastLocation(0) {
|
|
|
+Game::Game() : active(-1, -1), mustTake(false) {
|
|
|
std::cout << "0\n1\n0\n";
|
|
|
|
|
|
neighbours[0].set(1, 0);
|
|
@@ -26,72 +26,75 @@ Game::Game() : active(-1, -1), direction(0, 0), mustTake(false), lastLocation(0)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Game::print(String& s) const {
|
|
|
+char Game::getChar(int x, int y) const {
|
|
|
+ if(active.compare(x, y)) {
|
|
|
+ return '*';
|
|
|
+ }
|
|
|
+ static const char map[] = {'#', 'O', '.'};
|
|
|
+ return map[fields[x][y]];
|
|
|
+}
|
|
|
+
|
|
|
+void Game::toString(String& s) const {
|
|
|
s.append(" 0 1 2 3 4 5 6 7 8\n");
|
|
|
- printLine(s, 0);
|
|
|
+ lineToString(s, 0);
|
|
|
s.append(" |\\|/|\\|/|\\|/|\\|/|\n");
|
|
|
- printLine(s, 1);
|
|
|
+ lineToString(s, 1);
|
|
|
s.append(" |/|\\|/|\\|/|\\|/|\\|\n");
|
|
|
- printLine(s, 2);
|
|
|
+ lineToString(s, 2);
|
|
|
s.append(" |\\|/|\\|/|\\|/|\\|/|\n");
|
|
|
- printLine(s, 3);
|
|
|
+ lineToString(s, 3);
|
|
|
s.append(" |/|\\|/|\\|/|\\|/|\\|\n");
|
|
|
- printLine(s, 4);
|
|
|
+ lineToString(s, 4);
|
|
|
s.append("\n");
|
|
|
}
|
|
|
|
|
|
-void Game::printLine(String& s, int y) const {
|
|
|
- static const char map[] = {
|
|
|
- '#', 'O', '.'
|
|
|
- };
|
|
|
+void Game::lineToString(String& s, int y) const {
|
|
|
s.append(y + '0').append(' ');
|
|
|
for(int x = 0; x < 8; x++) {
|
|
|
- if(active.compare(x, y)) {
|
|
|
- s.append("*-");
|
|
|
- continue;
|
|
|
- }
|
|
|
- s.append(map[fields[x][y]]).append('-');
|
|
|
- }
|
|
|
- if(active.compare(8, y)) {
|
|
|
- s.append('*');
|
|
|
- } else {
|
|
|
- s.append(map[fields[8][y]]);
|
|
|
+ s.append(getChar(x, y)).append('-');
|
|
|
}
|
|
|
- s.append("\n\r");
|
|
|
+ s.append(getChar(8, y)).append("\n\r");
|
|
|
}
|
|
|
|
|
|
-void Game::parse() {
|
|
|
- String s;
|
|
|
+void Game::readLine() {
|
|
|
+ String line;
|
|
|
while(true) {
|
|
|
char c = std::cin.get();
|
|
|
- if(c == '\r') {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(c != '\n') {
|
|
|
- s.append(c);
|
|
|
- continue;
|
|
|
- }
|
|
|
- if(s == " 0 1 2 3 4 5 6 7 8") {
|
|
|
- parseFields();
|
|
|
- } else if(s == "Please enter origin x-axis") {
|
|
|
- makeSelection();
|
|
|
- } else if(s == "Please enter destination x-axis") {
|
|
|
- makeMove();
|
|
|
- } else if(s == "Please enter wether you want to Withdraw or Approach [W/A]") {
|
|
|
- takeStone();
|
|
|
- } else if(s == "Do you want to continue with your turn [Y/N]?") {
|
|
|
- std::cout << "Y\n";
|
|
|
- } else if(s == "************************Player 1 won!**********************" ||
|
|
|
- s == "************************Player 2 won!**********************") {
|
|
|
- std::cerr << s << "\n";
|
|
|
- return;
|
|
|
+ if(c == '\n') {
|
|
|
+ if(parseLine(line)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ line.clear();
|
|
|
+ } else if(c != '\r') {
|
|
|
+ line.append(c);
|
|
|
}
|
|
|
- s.clear();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+bool Game::parseLine(const String& line) {
|
|
|
+ if(line == " 0 1 2 3 4 5 6 7 8") {
|
|
|
+ readFields();
|
|
|
+ printFields();
|
|
|
+ } else if(line == "Please enter origin x-axis") {
|
|
|
+ makeSelection();
|
|
|
+ } else if(line == "Please enter destination x-axis") {
|
|
|
+ makeMove();
|
|
|
+ } else if(line == "Please enter wether you want to Withdraw or Approach [W/A]") {
|
|
|
+ takeStone();
|
|
|
+ } else if(line == "Do you want to continue with your turn [Y/N]?") {
|
|
|
+ std::cout << "Y\n";
|
|
|
+ } else if(line == "************************Player 1 won!**********************" ||
|
|
|
+ line == "************************Player 2 won!**********************") {
|
|
|
+ std::cerr << line << "\n";
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
void Game::consumeLine() const {
|
|
|
+ // skip until newline
|
|
|
while(std::cin.get() != '\n');
|
|
|
+ // skip any trailing line carriage
|
|
|
while(true) {
|
|
|
char c = std::cin.peek();
|
|
|
if(c != '\r') {
|
|
@@ -101,11 +104,13 @@ void Game::consumeLine() const {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Game::consumeLine(uint y) {
|
|
|
+void Game::readLine(uint y) {
|
|
|
+ // skip line heading
|
|
|
std::cin.get();
|
|
|
std::cin.get();
|
|
|
std::cin.get();
|
|
|
for(uint x = 0; x < 9; x++) {
|
|
|
+ // read field state
|
|
|
char c = std::cin.get();
|
|
|
if(c == '2') {
|
|
|
fields[x][y] = BLACK;
|
|
@@ -116,19 +121,23 @@ void Game::consumeLine(uint y) {
|
|
|
} else {
|
|
|
std::cerr << "game field parsing error\n";
|
|
|
}
|
|
|
+ // skip " - " until the next field (or the next line for x = 8)
|
|
|
std::cin.get();
|
|
|
std::cin.get();
|
|
|
std::cin.get();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Game::parseFields() {
|
|
|
+void Game::readFields() {
|
|
|
for(uint i = 0; i < 5; i++) {
|
|
|
consumeLine();
|
|
|
- consumeLine(i);
|
|
|
+ readLine(i);
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+void Game::printFields() const {
|
|
|
String s;
|
|
|
- print(s);
|
|
|
+ toString(s);
|
|
|
std::cerr << s;
|
|
|
}
|
|
|
|
|
@@ -175,24 +184,8 @@ uint Game::getRank(const Vector& from, const Vector& to, FieldState state) const
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Game::addLocation(const Vector& v) {
|
|
|
- if(lastLocation < lastLocations.size()) {
|
|
|
- lastLocations[lastLocation] = v;
|
|
|
- lastLocation++;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-bool Game::isInQueue(const Vector& v) const {
|
|
|
- for(uint i = 0; i < lastLocation; i++) {
|
|
|
- if(lastLocations[i] == v) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
-}
|
|
|
-
|
|
|
uint Game::getStoneTakes(const Vector& from, const Vector& to) const {
|
|
|
- if(!isInRange(to) || !hasState(to, EMPTY) || !areNeighbours(from, to) || isInQueue(to) || (to - from) == direction) {
|
|
|
+ if(!isInRange(to) || !hasState(to, EMPTY) || !areNeighbours(from, to) || lastLocations.contains(to) || (to - from) == direction) {
|
|
|
return 0;
|
|
|
}
|
|
|
FieldState enemy = (hasState(from, BLACK) ? WHITE : BLACK);
|
|
@@ -211,7 +204,7 @@ uint Game::getStoneTakes(const Vector& from, const Vector& to) const {
|
|
|
copy.removeLine(to, from, enemy);
|
|
|
rank = rankB;
|
|
|
}
|
|
|
- copy.addLocation(from);
|
|
|
+ copy.lastLocations.add(from);
|
|
|
copy.move(from, to);
|
|
|
|
|
|
uint maxRank = 0;
|
|
@@ -269,7 +262,7 @@ void Game::move(const Vector& from, const Vector& to) {
|
|
|
}
|
|
|
|
|
|
void Game::makeSelection() {
|
|
|
- lastLocation = 0;
|
|
|
+ lastLocations.clear();
|
|
|
direction.set(0, 0);
|
|
|
|
|
|
mustTake = isTakingPossible();
|
|
@@ -296,12 +289,12 @@ void Game::makeSelection() {
|
|
|
}
|
|
|
}
|
|
|
active = selection;
|
|
|
-
|
|
|
+
|
|
|
std::cerr << "Selecting (" << selection.x << ", " << selection.y << ")\n";
|
|
|
String s;
|
|
|
- print(s);
|
|
|
+ toString(s);
|
|
|
std::cerr << s;
|
|
|
-
|
|
|
+
|
|
|
std::cout << selection.x << "\n" << selection.y << "\n";
|
|
|
}
|
|
|
|
|
@@ -310,10 +303,10 @@ void Game::makeMove() {
|
|
|
int maxRank = -100000;
|
|
|
for(Vector& m : neighbours) {
|
|
|
Vector to = active + m;
|
|
|
- if(!isInRange(to) || !hasState(to, EMPTY) || isInQueue(to) || !areNeighbours(active, to) || m == direction) {
|
|
|
+ if(!isInRange(to) || !hasState(to, EMPTY) || lastLocations.contains(to) || !areNeighbours(active, to) || m == direction) {
|
|
|
continue;
|
|
|
}
|
|
|
- if(lastLocation > 0 || mustTake) {
|
|
|
+ if(!lastLocations.isEmpty() || mustTake) {
|
|
|
int rank = getRank(active, to, BLACK) + getRank(to, active, BLACK);
|
|
|
if(rank == 0) {
|
|
|
continue;
|
|
@@ -325,7 +318,7 @@ void Game::makeMove() {
|
|
|
maxTo = to;
|
|
|
}
|
|
|
}
|
|
|
- addLocation(active);
|
|
|
+ lastLocations.add(active);
|
|
|
direction = maxTo - active;
|
|
|
active = maxTo;
|
|
|
std::cerr << "Move to (" << maxTo.x << ", " << maxTo.y << ")\n";
|
|
@@ -354,7 +347,7 @@ int Game::getQuality(const Vector& from, const Vector& to) const {
|
|
|
} else {
|
|
|
copy.removeLine(to, from, BLACK);
|
|
|
}
|
|
|
- copy.lastLocation = 0;
|
|
|
+ copy.lastLocations.clear();
|
|
|
copy.direction.set(0, 0);
|
|
|
|
|
|
int whiteFreedom = copy.getFreedom(WHITE);
|