Merlin
Merlin

Reputation: 185

how to select the correct buttons in tic tac toe game

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

Answers (2)

Chris
Chris

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

Sundeep
Sundeep

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

Related Questions