I've made a Minimax algorithm to determine the best position in Tic Tac Toe. I want it to play for both 'x' and 'o'. For the most part, it works great; it's unbeatable. But as we all know, when starting the game, the strongest position to hold is the middle of the board. For some reason, my AI seems to go to the top left consistently (when it plays 'x' and has the first go)...
Now to be clear: this isn't a bug, I just want some clarification as to why it does this. Does it see no difference between top left and middle? or is there a bug somewhere in my code?
minimax(char board[9], bool is_maximizing, char computer)
int minimax(char board[9], bool is_maximizing, char computer)
{
char winner = check_winner(board);
int free_spaces = check_free_spaces(board);
char player = computer == 'x' ? 'o' : 'x';
if (free_spaces <= 1)
return 0;
else if (winner == computer)
return 1;
else if (winner == player)
return -1;
if (is_maximizing)
{
int best_score = INT_MIN;
for (int i = 0; i < 9; i )
{
if (board[i] == ' ')
{
board[i] = computer;
int score = minimax(board, false, computer);
board[i] = ' ';
if (score > best_score)
{
best_score = score;
}
}
}
return best_score;
}
else
{
int best_score = INT_MAX;
for (int i = 0; i < 9; i )
{
if (board[i] == ' ')
{
board[i] = player;
int score = minimax(board, true, computer);
board[i] = ' ';
if (score < best_score)
{
best_score = score;
}
}
}
return best_score;
}
}
computer_turn(char board[9], char computer)
void computer_turn(char board[9], char computer)
{
printf("%c's turn.\n", computer);
int best_score = INT_MIN;
int best_pos = -1;
int free_spaces = check_free_spaces(board);
for (int i = 0; i < 9; i )
{
if (board[i] == ' ')
{
if (free_spaces == 1)
{
best_pos = i;
}
else
{
board[i] = computer;
int score = minimax(board, 0, 10, false, computer);
board[i] = ' ';
if (score > best_score)
{
best_score = score;
best_pos = i;
}
}
}
}
board[best_pos] = computer;
}
also new to C from typescript so if you have suggestions to shorten my code it's much appreciated :)
CodePudding user response:
Minimax assumes best play from both players, that is the core of the algorithm. Tic Tac Toe will always be a draw no matter starting position, if both players play the best moves. Therefore the algorithm will think each move from the starting position is equally good (a score of 0, a draw).
So when you do this check:
score > best_score
The score will never be better than the first possible place you check, which I assume is the top left corner. If you for example try and change this to score >= best_score
it will pick the bottom right corner (the last item in the list of possible moves).
So regarding your question, it isn't a bug. And it does actually pick the best move, given the nature of the algorithm. If you want it to play in the middle in the first move you need to force it to do so by hard coding it and bypassing the minimax algorithm.