Browse Source

tictactoe: hard ai checks for own opportunity to win first

tictactoe
Tobias Krause 3 years ago
committed by Lorenz Hohmann
parent
commit
9111545ec3
  1. 62
      src/main/java/de/tims/tictactoe/ai/AIHard.java
  2. 11
      src/test/java/de/tims/tictactoe/ai/AIHardTest.java

62
src/main/java/de/tims/tictactoe/ai/AIHard.java

@ -19,60 +19,34 @@ public class AIHard implements TicTacToeAI {
@Override
public void calculateNextMove() {
int ownCharsInRow = 0;
int ownCharsInCol = 0;
int ownCharsInDiag = 0;
int charsOfOpponentInRow = 0;
int charsOfOpponentInCol = 0;
int charsOfOpponentInDiag = 0;
int charsInRow = 0;
int charsInCol = 0;
int charsInDiag = 0;
char[][] board = gl.getBoard();
for (int i = 0; i < BOARD_SIZE; i++) {
ownCharsInRow = countCharsInRow(i, AI_CHAR);
ownCharsInCol = countCharsInCol(i, AI_CHAR);
charsOfOpponentInRow = countCharsInRow(i, PLAYER_CHAR);
charsOfOpponentInCol = countCharsInCol(i, PLAYER_CHAR);
if (i < 2) {
ownCharsInDiag = countCharsInDiag(i, AI_CHAR);
charsOfOpponentInDiag = countCharsInDiag(i, PLAYER_CHAR);
}
for (int i = 0; i < 2; i++) {
char actualChar = (i == 0) ? AI_CHAR : PLAYER_CHAR;
if (ownCharsInRow == BOARD_SIZE - 1 || ownCharsInCol == BOARD_SIZE - 1) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (ownCharsInRow == BOARD_SIZE - 1) {
if (board[i][j] == EMPTY_CHAR) {
gl.setField(i, j, AI_CHAR);
return;
}
} else if (ownCharsInCol == BOARD_SIZE - 1) {
if (board[j][i] == EMPTY_CHAR) {
gl.setField(j, i, AI_CHAR);
return;
}
} else if (ownCharsInDiag == BOARD_SIZE - 1) {
if (board[j][(i == 1) ? i : BOARD_SIZE - 1 - j] == EMPTY_CHAR) {
gl.setField(j, (i == 1) ? j : BOARD_SIZE - 1 - j, AI_CHAR);
charsInRow = countCharsInRow(j, actualChar);
charsInCol = countCharsInCol(j, actualChar);
if (j < 2) {
charsInDiag = countCharsInDiag(j, actualChar);
if (charsInDiag == BOARD_SIZE - 1) {
for (int k = 0; k < BOARD_SIZE; k++) {
if (board[k][(j == 0) ? k : BOARD_SIZE - 1 - k] == EMPTY_CHAR) {
gl.setField(k, (j == 0) ? k : BOARD_SIZE - 1 -k, AI_CHAR);
return;
}
}
}
}
if (charsOfOpponentInRow == BOARD_SIZE - 1 || charsOfOpponentInCol == BOARD_SIZE - 1 || charsOfOpponentInDiag == BOARD_SIZE - 1) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (charsOfOpponentInRow == BOARD_SIZE - 1) {
if (board[i][j] == EMPTY_CHAR) {
gl.setField(i, j, AI_CHAR);
return;
}
} else if (charsOfOpponentInCol == BOARD_SIZE - 1) {
if (board[j][i] == EMPTY_CHAR) {
gl.setField(j, i, AI_CHAR);
return;
}
} else if (charsOfOpponentInDiag == BOARD_SIZE - 1) {
if (board[j][(i == 0) ? j : BOARD_SIZE - 1 - j] == EMPTY_CHAR) {
gl.setField(j, (i == 0) ? j : BOARD_SIZE - 1 - j, AI_CHAR);
if (charsInRow == BOARD_SIZE - 1 || charsInCol == BOARD_SIZE - 1) {
for (int k = 0; k < BOARD_SIZE; k++) {
if (board[(charsInRow == BOARD_SIZE - 1) ? j : k][(charsInRow == BOARD_SIZE - 1) ? k : j] == EMPTY_CHAR) {
gl.setField((charsInRow == BOARD_SIZE - 1) ? j : k, (charsInRow == BOARD_SIZE - 1) ? k : j, AI_CHAR);
return;
}
}

11
src/test/java/de/tims/tictactoe/ai/AIHardTest.java

@ -132,6 +132,17 @@ class AIHardTest {
verify(gl, times(1)).setField(2, 2, realChar);
}
@Test
void opportunityToWinIsMoreImportantThanPreventingOpponentsWinInNextRound() {
char realChar = 'o';
doReturn(new char[][] { {'x', '-', 'o'}, {'-', 'o', '-'}, {'x', 'x', 'o'} }).when(gl).getBoard();
TicTacToeAI ai = new AIHard(gl);
ai.calculateNextMove();
verify(gl, times(1)).setField(1, 2, realChar);
}
@ParameterizedTest
@MethodSource("testCasesForCountCharsInRow")
void countCharsInRowTest(String testName, char[][] board, int rowNum, char charToCount, int expectedResult) {

Loading…
Cancel
Save