I was trying to write a tic-tac-toe game where you can play against someone else on local or you can play against a bot. Bot uses the minimax algorithm. However, there is something wrong with what i have written. Bot can counterattack the player but when given the chance it does not play the winning move. I could not understand why.
Basically I have only a problem in the main->GameAgainstComputer->findBestMove->miniMax
(Board is a 2d char vector array)
whole code:
#include <iostream>
#include <vector>
#include <string>
#include <limits.h>
using namespace std;
#define INFINITY INT_MAX
bool GameIsOver(vector<vector<char>>& board, char& winner)
{
for(int i = 0 ; i < 3 ; i++)
{
if(board[i][0] == board[i][1] && board[i][1] == board[i][2])
{
winner = board[i][0];
return true;
}
}
for(int i = 0 ; i < 3 ; i++)
{
if(board[0][i] == board[1][i] && board[1][i] == board[2][i])
{
winner = board[0][i];
return true;
}
}
if(board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
winner = board[0][0];
return true;
}
else if(board[2][0] == board[1][1] && board[1][1] == board[0][2])
{
winner = board[2][0];
return true;
}
return false;
}
bool isMovesLeft(vector<vector<char>>& board)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[i][j] != 'X' && board[i][j] != 'O')
return true;
return false;
}
int evaluate(vector<vector<char>>& board)
{
char winner = ' ';
if (GameIsOver(board, winner))
{
if (winner == 'X')
return 10;
else if (winner == 'O')
return -10;
}
return 0;
}
int miniMax(vector<vector<char>>& board, int depth, bool isMaximising)
{
int score = evaluate(board);
if (score >= 10 || score <= -10)
return score;
if (!isMovesLeft(board))
return 0;
if (isMaximising)
{
int best = -INFINITY;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board[i][j] != 'X' && board[i][j] != 'O')
{
char backup = board[i][j];
board[i][j] = 'X';
best = max(best, miniMax(board, depth + 1, !isMaximising));
board[i][j] = backup;
}
}
}
return best;
}
else
{
int best = INFINITY;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board[i][j] != 'X' && board[i][j] != 'O')
{
char backup = board[i][j];
board[i][j] = 'O';
best = min(best, miniMax(board, depth + 1, isMaximising));
board[i][j] = backup;
}
}
}
return best;
}
}
pair<int, int> findBestMove(vector<vector<char>>& board)
{
int bestVal = -INFINITY;
pair<int, int> bestMove = {-1, -1};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (board[i][j] != 'X' && board[i][j] != 'O')
{
char backup = board[i][j];
board[i][j] = 'X';
int moveVal = miniMax(board, 0, false);
board[i][j] = backup;
if (moveVal > bestVal)
{
bestMove = {i, j};
bestVal = moveVal;
}
}
}
}
return bestMove;
}
Fatih Bastan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.