HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Tic Tac Toe computer AI

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
tacticcomputertoe

Problem

I am creating a TicTacToe game for my college project, and when I finished the code for computer AI, I ended up with a big chunk of code.

It allows the computer to make the winning move, stopping the player from winning and making a random move if the computer can't make any winning move or stop the player from winning. The code I have contains a series of if and else if statements.

I was wondering if it would be possible to reduce this amount of code in any way. I have tried putting one of the if statements in a method and then calling the method several times, but this does not work because the else statement does not run.

```
public void AI(){
count++;
if(buttons[1].getText().equals("O") && buttons[2].getText().equals("O") && buttons[3].getText().equals("")){
buttons[3].setText("O");
buttons[3].setEnabled(false);
} else if(buttons[4].getText().equals("O") && buttons[5].getText().equals("O") && buttons[6].getText().equals("")){
buttons[6].setText("O");
buttons[6].setEnabled(false);
} else if(buttons[7].getText().equals("O") && buttons[8].getText().equals("O") && buttons[9].getText().equals("")){
buttons[9].setText("O");
buttons[9].setEnabled(false);
}

else if(buttons[2].getText().equals("O") && buttons[3].getText().equals("O") && buttons[1].getText().equals("")){
buttons[1].setText("O");
buttons[1].setEnabled(false);
} else if(buttons[5].getText().equals("O") && buttons[6].getText().equals("O") && buttons[4].getText().equals("")){
buttons[4].setText("O");
buttons[4].setEnabled(false);
} else if(buttons[8].getText().equals("O") && buttons[9].getText().equals("O") && buttons[7].getText().equals("")){
buttons[7].setText("O");
buttons[7].setEnabled(false);
}

else if(butt

Solution

Yes, you really need to use loops and generalize this!

In order for you to learn the most, I won't give any exact code but I will tell you a bit about what you need to do

-
Your array seems to be index 1-9 based, I would recommend using index 0 to 8 instead. Array index always start at zero, it just seem like you're just not using it. Instead, use it.

-
Use for-loops to iterate through rows, columns and the diagonals of your game board. 3 rows, 3 columns, and 2 diagonals. for (int x = 0; x

-
Hint: The row and column of a button can be calculated by using either
index / 3 or index % 3 (% is the 'modulo'-operator). This is a reason for why you should use zero-index based arrays. It makes it so much easier to do this calculation.

-
You might want to use an
enum for UNPLAYED, X and O. Using an appropriate enum can really help clean up your code massively.

public enum PlayedBy {
UNPLAYED, X, O;
}

-
Decoupling. This is a bit more advanced and nothing you should be focusing on primarily. But in the future, it will help you greatly. Right now your AI knows everything about your view (view = the objects that the user sees). What if you wanted to make two AIs play against each other and only output to the console? What if you wanted to make an Android app of this? What if you wanted to make a Web application with GWT? (In the future you might want this!) You should look into the MVC pattern and/or use interfaces! to decouple your code.

You repeat this part very often

buttons[x].setText("O");
buttons[x].setEnabled(false);


That is something that should be put into a method:

void setButtonPlayer(JButton position, String player) {
    position.setText(player);
    position.setEnabled(false);
}


Now you only have to use
setButtonPlayer(buttons[4], "O"); to make a move on button 4. If you use an enum, you could use setButtonPlayer(JButton button, PlayedBy player)`.

Once you have cleaned this up a bit, I recommend you post a follow-up question, as there is likely more things that can be cleaned up then.

Code Snippets

buttons[x].setText("O");
buttons[x].setEnabled(false);
void setButtonPlayer(JButton position, String player) {
    position.setText(player);
    position.setEnabled(false);
}

Context

StackExchange Code Review Q#44608, answer score: 15

Revisions (0)

No revisions yet.