Reputation: 185
I have a method which tries to determine a AI's move in tic tac toe. Currently I have a method where the computer selects a button randomly but I want it to be a little bit smarter. I have an idea on how to do this but need a little guidence in implementation.
Basically I want the computer to know that if there is either a posibility or win or lose then it will place their counter on the square which will help them win or prevent the player from winning. Here is an example using a grid of coordinates for a 3x3 tic tac toe board:
00 01 02
10 11 12 -- coordinates of all of the buttons in a tic tac toe board
20 21 22
if 00 is not empty and 01 is same as 00, then place 'O' on 02 -- helps win or prevent a win for 3 in a row
if 01 is not empty and 02 is same as 01, then place 'O' on 00 -- helps win or prevent a win for 3 in a row
if 01 is not empty and 21 is same as 01, then place 'O' on 11 -- helps win or prevent a win for 3 in a column
if 20 is not empty and 02 is same as 20, then place 'O' on 11 -- helps win or prevent a win for 3 in a diaganol
As you can tell there are many more scenarios but the main aim is if there is a chance to win or chance to prevent a win then the computer will need to place their 'O'. If the condition doesn't meet then basically select a random button.
So I know I need a bunch of else if but how can this be implemented to do what it needs to do?
Below is a skeleton of what I am trying to do to prevent win/win for 3 in a row for rows and selecting any random button if any of the above conditions do not match:
private void computerMove() {
String[][] field = new String[3][3];
Random random = new Random(); //you may want to declare this as a class field
List<Button> emptyButtons = new ArrayList<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
field[i][j] = buttons[i][j].getText().toString();
if (field[i][j].equals("")) {
emptyButtons.add(buttons[i][j]);
}
}
}
Button selectButton;
for (int i = 0; i < 3; i++) {
if (field[i][0].equals(field[i][1])
&& field[i][2].equals("")){
//prevent win/win on rows by selecting the correct button here
}
else if (field[i][0].equals(field[i][2])
&& field[i][1].equals("")){
//prevent win/win on rows by selecting the correct button here
}
else if (field[i][1].equals(field[i][2])
&& field[i][0].equals("")){
//prevent win/win on rows by selecting the correct button here
}
else {
selectButton = emptyButtons.get(random.nextInt(emptyButtons.size()));
}
selectButton.setText("O");
selectButton.setTextColor(playerO);
turnsCount++;
isGameOver();
}
Upvotes: 0
Views: 298
Reputation: 449
To avoid long if-else statements you could represent the 'O's and 'X's using integers, so that the sum of any combination would be unique.
E.g., if '0' was 1 and 'X' was 10, given:
| 11
|----
X X . | 20
O X O | 12
O O . | 2
---------|----
12 21 1 | 20
That is, the columns would sum to: 12, 21, 1
,
and the rows would sum to: 20, 12, 2
.
The diagonals sum to: 20, 11
.
Using this summing method you can calculate if either player has a 1 move win.
If sum == 20
, 'X' can win by placing a piece on the zero-valued index of that row/column/diagonal.
If sum == 2
, O
can win by placing a piece on the zero-valued index of that row/column/diagonal.
To get the diagonal sums, simply sum the indices where i==j
.
Edit: i==j
gives you one diagonal. In the general case, the other is given traversing the indices of the two loops (row vs column) in reverse order. Or for a 3x3 game, is just (1,3), (2,2), (3,1).
Upvotes: 1
Reputation: 472
A tic tac toe game has 8 possible winning position (3 rows, 3 columns and 2 diagonals).
Store point for computer referring the row, column or diagonal
100 for 3 in row
10 for 2 in a row (with a empty cell)
1 for 1 in a row (with two empty cell)
now you have enough data to ensure next best possible move.
NOTE: You can also use Minimax with Alpha-beta Pruning Technique.
Upvotes: 0