I’m currently developing a tic tac toe game as a college project in Java, but I’m encountering some issues with the AI functionality. The AI isn’t able to win effectively and tends to make predictable moves rather than random ones. My professor specified that the AI should be able to take a win if possible and also block the player’s chances of winning.
Moreover, I’m having trouble with the game logic—it doesn’t conclude after all the squares are filled; it keeps prompting for further moves.
I’d really appreciate any guidance on how to rectify these issues! Below is my main game implementation:
import java.util.Scanner;
public class GameRunner {
public static void main(String[] args) {
System.out.println("Welcome to Tic Tac Toe!");
String playerSymbol = "X";
String aiSymbol = "O";
boolean keepPlaying = true;
Scanner input = new Scanner(System.in);
PlayerHuman player = new PlayerHuman();
PlayerAI ai = new PlayerAI();
while(keepPlaying) {
GameBoard gameBoard = new GameBoard();
gameBoard.initializeBoard();
gameBoard.displayBoard();
System.out.println("Choose your symbol: 1 for X or 2 for O");
if(input.nextInt() == 1) {
player.setSymbol("X");
ai.setSymbol("O");
} else {
player.setSymbol("O");
ai.setSymbol("X");
}
int starter = (int)(Math.random() * 2);
boolean gameOver = false;
int moveCount = 0;
if(starter == 0) {
System.out.println("You start!");
while(!gameOver) {
player.makeMove(gameBoard.getGrid());
moveCount++;
gameBoard.displayBoard();
if(gameBoard.checkWinner(gameBoard.getGrid())) {
gameOver = true;
System.out.println("You win!");
}
if(moveCount == 9) {
gameOver = true;
System.out.println("It's a tie!");
break;
}
if(!gameOver) {
ai.makeMove(gameBoard.getGrid(), player);
moveCount++;
gameBoard.displayBoard();
if(gameBoard.checkWinner(gameBoard.getGrid())) {
gameOver = true;
System.out.println("Computer wins!");
}
}
}
}
System.out.println("Play again? 1 for yes, 2 for no");
if(input.nextInt() == 2) {
keepPlaying = false;
}
}
}
}
And this is how my AI class is structured:
class PlayerAI extends BasePlayer {
int gridSize = 3;
public void makeMove(String[][] grid, PlayerHuman opponent) {
boolean moveMade = false;
// Try to win horizontally
for(int row = 0; row < 3; row++) {
if(grid[0][row].equals(grid[1][row]) && grid[0][row].equals(symbol)) {
if(!grid[2][row].equals(opponent.getSymbol())) {
grid[2][row] = symbol;
return;
}
}
}
// Try to win vertically
for(int col = 0; col < 3; col++) {
if(grid[col][0].equals(grid[col][1]) && grid[col][0].equals(symbol)) {
if(!grid[col][2].equals(opponent.getSymbol())) {
grid[col][2] = symbol;
return;
}
}
}
// Try to win diagonally
if(grid[0][0].equals(grid[1][1]) && grid[0][0].equals(symbol)) {
if(!grid[2][2].equals(opponent.getSymbol())) {
grid[2][2] = symbol;
return;
}
}
// Block opponent horizontally
for(int row = 0; row < 3; row++) {
if(grid[0][row].equals(grid[1][row]) && grid[0][row].equals(opponent.getSymbol())) {
if(!grid[2][row].equals(symbol)) {
grid[2][row] = symbol;
return;
}
}
}
// Make random move
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
if(!grid[i][j].equals("X") && !grid[i][j].equals("O")) {
grid[i][j] = symbol;
return;
}
}
}
}
}