|
@@ -20,6 +20,10 @@ void Game::reset() {
|
|
|
fields[4][2] = EMPTY;
|
|
|
fields[5][2] = WHITE;
|
|
|
fields[7][2] = WHITE;
|
|
|
+
|
|
|
+ fields[2][0] = WHITE;
|
|
|
+ fields[1][0] = EMPTY;
|
|
|
+ fields[1][1] = EMPTY;
|
|
|
}
|
|
|
|
|
|
void Game::reset(String& output) {
|
|
@@ -72,7 +76,7 @@ bool Game::parseLocation(const String& input, int& x, int& y) {
|
|
|
return x >= 9 || y >= 6;
|
|
|
}
|
|
|
|
|
|
-void Game::parse(const String& input, String& output) {
|
|
|
+bool Game::parse(const String& input, String& output) {
|
|
|
switch(state) {
|
|
|
case SELECTION:
|
|
|
parseSelection(input, output);
|
|
@@ -83,7 +87,11 @@ void Game::parse(const String& input, String& output) {
|
|
|
case ANOTHER_MOVE:
|
|
|
parseAnotherMove(input, output);
|
|
|
break;
|
|
|
+ case REMOVE_SELECTION:
|
|
|
+ parseRemoveSelection(input, output);
|
|
|
+ break;
|
|
|
}
|
|
|
+ return shouldEnd();
|
|
|
}
|
|
|
|
|
|
void Game::parseSelection(const String& input, String& output) {
|
|
@@ -124,6 +132,14 @@ void Game::parseMove(const String& input, String& output) {
|
|
|
output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rselect location to move: ");
|
|
|
return;
|
|
|
}
|
|
|
+ directionX = x - activeX;
|
|
|
+ directionY = y - activeY;
|
|
|
+ if(markHitSides(activeX, activeY, x, y, BLACK)) {
|
|
|
+ state = REMOVE_SELECTION;
|
|
|
+ print(output);
|
|
|
+ output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rselect stone to take: ");
|
|
|
+ return;
|
|
|
+ }
|
|
|
lastLocation = 0;
|
|
|
move(activeX, activeY, x, y);
|
|
|
|
|
@@ -157,6 +173,14 @@ void Game::parseAnotherMove(const String& input, String& output) {
|
|
|
output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rselect location to move: ");
|
|
|
return;
|
|
|
}
|
|
|
+ directionX = x - activeX;
|
|
|
+ directionY = y - activeY;
|
|
|
+ if(markHitSides(activeX, activeY, x, y, BLACK)) {
|
|
|
+ state = REMOVE_SELECTION;
|
|
|
+ print(output);
|
|
|
+ output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rselect stone to take: ");
|
|
|
+ return;
|
|
|
+ }
|
|
|
move(activeX, activeY, x, y);
|
|
|
|
|
|
bool removed = false;
|
|
@@ -179,10 +203,43 @@ void Game::parseAnotherMove(const String& input, String& output) {
|
|
|
botMove(output);
|
|
|
}
|
|
|
|
|
|
+void Game::parseRemoveSelection(const String& input, String& output) {
|
|
|
+ int x;
|
|
|
+ int y;
|
|
|
+ if(parseLocation(input, x, y) || !((hitA.x == x && hitA.y == y) || (hitB.x == x && hitB.y == y))) {
|
|
|
+ output.append("invalid take location.\n\r");
|
|
|
+ print(output);
|
|
|
+ output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rselect stone to take: ");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int mx = activeX + directionX;
|
|
|
+ int my = activeY + directionY;
|
|
|
+
|
|
|
+ move(activeX, activeY, mx, my);
|
|
|
+
|
|
|
+ if(mx + directionX == x && my + directionY == y) {
|
|
|
+ removeLine(activeX, activeY, mx, my, BLACK);
|
|
|
+ } else {
|
|
|
+ removeLine(mx, my, activeX, activeY, BLACK);
|
|
|
+ }
|
|
|
+
|
|
|
+ activeX = mx;
|
|
|
+ activeY = my;
|
|
|
+ print(output);
|
|
|
+ if(isAnotherTurnPossible()) {
|
|
|
+ state = ANOTHER_MOVE;
|
|
|
+ output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rselect location to move: ");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ state = SELECTION;
|
|
|
+ output.append("Human Color: White(O)\n\rAIColor: Black(#)\n\rAI turn\n\r");
|
|
|
+ activeX = -1;
|
|
|
+ activeY = -1;
|
|
|
+ botMove(output);
|
|
|
+}
|
|
|
+
|
|
|
void Game::move(int fromX, int fromY, int toX, int toY) {
|
|
|
addLocation(fromX, fromY);
|
|
|
- directionX = toX - fromX;
|
|
|
- directionY = toY - fromY;
|
|
|
fields[fromX][fromY] = EMPTY;
|
|
|
fields[toX][toY] = WHITE;
|
|
|
}
|
|
@@ -233,6 +290,9 @@ bool Game::removeLine(int x, int y, int x2, int y2, FieldState remove) {
|
|
|
}
|
|
|
|
|
|
void Game::botMove(String& output) {
|
|
|
+ if(shouldEnd()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
while(true) {
|
|
|
int x = 0;
|
|
|
int y = 0;
|
|
@@ -299,4 +359,26 @@ bool Game::isAnotherTurnPossible() const {
|
|
|
return canMoveActiveStoneTo(-1, -1) || canMoveActiveStoneTo(0, -1) || canMoveActiveStoneTo(1, -1) ||
|
|
|
canMoveActiveStoneTo(-1, 0) || canMoveActiveStoneTo(1, 0) ||
|
|
|
canMoveActiveStoneTo(-1, 1) || canMoveActiveStoneTo(0, 1) || canMoveActiveStoneTo(1, 1);
|
|
|
+}
|
|
|
+
|
|
|
+bool Game::markHitSides(int x1, int y1, int x2, int y2, FieldState state) {
|
|
|
+ hitA.x = x1 + (x1 - x2);
|
|
|
+ hitA.y = y1 + (y1 - y2);
|
|
|
+ hitB.x = x2 + (x2 - x1);
|
|
|
+ hitB.y = y2 + (y2 - y1);
|
|
|
+ return isInRange(hitA.x, hitA.y) && isInRange(hitB.x, hitB.y) &&
|
|
|
+ areNeighbours(x1, y1, hitA.x, hitA.y) && areNeighbours(x2, y2, hitB.x, hitB.y) &&
|
|
|
+ fields[hitA.x][ hitA.y] == state && fields[hitB.x][ hitB.y] == state;
|
|
|
+}
|
|
|
+
|
|
|
+bool Game::shouldEnd() const {
|
|
|
+ int player = 0;
|
|
|
+ int ai = 0;
|
|
|
+ for(uint x = 0; x < 9; x++) {
|
|
|
+ for(uint y = 0; y < 5; y++) {
|
|
|
+ player += fields[x][y] == WHITE;
|
|
|
+ ai += fields[x][y] == BLACK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return player == 0 || ai == 0;
|
|
|
}
|