I'm trying to implement a TicTacToe AI using a minimax algorithm.
When it's the AI's turn to play, I call ComputerTurn (which takes in the board state, an array of ints that tracks whether a square is X, O, or empty). ComputerTurn then calls minimax (the minimax algorithm) and win (which checks for 3 in a row).
When I run the script, the algorithm always decides to return the lowest legal play. IE, as long as the top left square (tile 0) is available, it will always return it first. If that square is taken, it will return the top middle (tile 1) etc.
I'm not sure what's happening here and my traditional debugging technique (Debug.Log or print) is causing Unity to crash at many points I want to look at.
void ComputerTurn(int[] board)
{
int move = -1;
int score = -2;
int i;
for (i = 0; i < 9; ++i)
{
if (board[i] == 0)
{
board[i] = 1;
int tempScore = -minimax(board, -1);
board[i] = 0;
if (tempScore > score)
{
score = tempScore;
move = i;
}
}
}
board[move] = 1;
if (PlayerTurn == 1)
{
//Draw an O
Board[move] = -1;
}
else
{
//Draw an X
Board[move] = 1;
}
//Changes to player's turn
}
int minimax(int[] board, int player)
{
int winner = win(board);
if (winner != 0) return winner * player;
int move = -1;
int score = -2;//Losing moves are preferred to no move
int i;
for (i = 0; i < 9; ++i)
{//For all moves,
if (board[i] == 0)
{//If legal,
board[i] = player;//Try the move
int thisScore = -minimax(board, player * -1);
if (thisScore > score)
{
score = thisScore;
move = i;
}//Pick the one that's worst for the opponent
board[i] = 0;//Reset board after try
}
}
if (move == -1) return 0;
return score;
}
int win(int[] board)
{
//determines if a player has won, returns 0 otherwise.
int[,] wins = new int[8, 3] { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 }, { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 }, { 2, 4, 6 } };
int i;
for (i = 0; i< 8; ++i)
{
if (board[wins[i, 0]] != 0 &&
board[wins[i, 0]] == board[wins[i, 1]] &&
board[wins[i, 0]] == board[wins[i, 2]])
{
return board[wins[i, 2]];
}
}
return 0;
}