So I've been looking into creating a simple tic-tac-toe game where the human player plays against an ai run by the minimax algorithm. I have spent the last few days trying to figure these two bugs out but I cant for the life of me seem to. for one, the ai seems sort of predictable and not very good. Secondly, the only way it seems to work is if the ai goes first, if I have the human player go first, the ai just continues to fill the next available spot. Any help would be super appreciated.
Here's my code:
import java.util.Scanner;
public class Game
{
static String player = "X";
static String opponent = "O";
int row;
int col;
public Game(int x, int y)
{
row = x;
col = y;
}
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String [][] board = new String [3][3];
fillBoard(board);
while(true) //Infinite loop only for testing, will change back
{
getBestMove(board);
printBoard(board);
playerTurn(board, input);
printBoard(board);
//System.out.println("Best move: " + bestMove.row + " " + bestMove.col);
}
//input.close();
}
static int checkState(String [][] board)
{
for (int row = 0; row<3; row++) //Rows
{
if (board[row][0] == board[row][1] &&
board[row][1] == board[row][2])
{
if (board[row][0]==player)
return -10;
else if (board[row][0]==opponent)
return +10;
}
}
for (int col = 0; col<3; col++) //Columns
{
if (board[0][col]==board[1][col] &&
board[1][col]==board[2][col])
{
if (board[0][col]==player)
return -10;
else if (board[0][col]==opponent)
return +10;
}
}
if (board[0][0]==board[1][1] && board[1][1]==board[2][2]) //Diagonal
{
if (board[0][0]==player)
return -10;
else if (board[0][0]==opponent)
return +10;
}
else if (board[0][2]==board[1][1] && board[1][1]==board[2][0]) //Diagonal
{
if (board[0][2]==player)
return -10;
else if (board[0][2]==opponent)
return +10;
}
return 0;
}
public static void getBestMove(String[][] board)
{
int bestValue = -1000;
Game bestMove = new Game(-1,-1);
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(board[i][j] == "-")
{
board[i][j] = player;
int currentValue = minimax(board, 0, false);
board[i][j] = "-";
if(currentValue > bestValue)
{
bestMove.row = i;
bestMove.col = j;
bestValue = currentValue;
}
}
}
}
board[bestMove.row][bestMove.col]= opponent;
}
public static int minimax(String [][] board, int depth, boolean isMaximizer)
{
if(checkState(board) != 0)
return checkState(board);
if(checkRemainingPlays(board) == false)
return 0;
if(isMaximizer)
{
int highest = -1000;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(board[i][j] == "-")
{
board[i][j] = player;
highest = Math.max(highest, minimax(board, depth + 1, !isMaximizer));
board[i][j] = "-";
}
}
}
return highest;
}
else
{
int lowest = 1000;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(board[i][j] == "-")
{
board[i][j] = opponent;
lowest = Math.min(lowest, minimax(board, depth + 1, !isMaximizer));
board[i][j] = "-";
}
}
}
return lowest;
}
}
public static void playerTurn(String [][] board , Scanner input)
{
input = new Scanner(System.in);
System.out.println("Player 1: ");
System.out.println("Please enter the index of desired spot (I) ");
int desiredIndexI = input.nextInt();
System.out.println("Please enter the index of desired spot (J) ");
int desiredIndexJ = input.nextInt();
while(board[desiredIndexI][desiredIndexJ] != "-")
{
System.out.println("Please enter the index of desired spot (I) ");
desiredIndexI = input.nextInt();
System.out.println("Please enter the index of desired spot (J) ");
desiredIndexJ = input.nextInt();
}
board[desiredIndexI][desiredIndexJ] = player;
}
public static boolean checkRemainingPlays(String [][] board)
{
for(int i = 0; i < board.length; i++)
{
for(int j = 0; j < board[i].length; j++)
{
if (board[i][j] == "-")
return true;
}
}
return false;
}
public static void printBoard(String [][] board)
{
for(int i = 0; i < board.length; i++)
{
if(i <= 2 && i > 0)
System.out.println("----------");
for(int j = 0; j < board[i].length; j++)
{
if(j < 2)
System.out.print(board[i][j] + " | ");
if(j == 2)
System.out.println(board[i][j]);
}
}
}
public static void fillBoard(String [][] board)
{
for(int i = 0; i < board.length; i++)
{
for(int j = 0; j < board[i].length; j++)
{
board[i][j] = "-";
}
}
}
}