I have a chess game made and I’m trying to minimax it. For example, I have a mini version of 4×4 chess, but I can’t help minimax to find the optimal solution.
You will notice that the evaluate function returns +1000 if I checked checkmate, but, I have never received a value greater than +1000, I mean in the place where I list the val (best move), but for example I found the opponent’s checkmate ie values belove -1000.
I must have some error somewhere, but we are unable to detect it.
Controlling the program, alternating player and computer moves, I notice that I make a move on the copy and then take it to the minimaxAlg function, where the player starts
void CGame::minimaxAlphaBeta(int depth, Color color, bool random)
{
while(!isFinished())
{
if(color == m_Player)
{
if(random)
makeRandomMove(m_Player);
}
else
{
int bestVal = INT_MIN;
CPosition bestFromPosition;
CPosition bestToPosition;
auto& playableMoves = (m_Computer == Color::WHITE) ? m_WhitePlayable : m_BlackPlayable;
for(auto &[from, to] : playableMoves)
{
CGame gameCopy = *this;
gameCopy.makeMove(from, to, m_Computer, true);
int val = gameCopy.minimaxAlphaBetaAlg(gameCopy, depth, INT_MIN, INT_MAX, false, gameCopy.m_Player);
cout << "val: " << val << endl; // never + 1000
if(val > bestVal)
{
bestVal = val;
bestFromPosition = from;
bestToPosition = to;
}
}
makeMove(bestFromPosition, bestToPosition, m_Computer, true);
}
color = (color == Color::WHITE) ? Color::BLACK : Color::WHITE;
}
}
main part minimax
int CGame::minimaxAlphaBetaAlg(CGame& game, int depth, int alpha, int beta, bool isMaximizingComputer, Color playerColor)
{
if(game.isFinished() || depth == 0)
return game.evaluateBoard(playerColor);
if(isMaximizingComputer)
{
int maxEval = INT_MIN;
auto& playableMoves = (m_Computer == Color::WHITE) ? game.m_WhitePlayable : game.m_BlackPlayable;
for (auto& [from, to] : playableMoves)
{
CGame gameCopy = game;
gameCopy.makeMove(from, to, m_Computer, true);
int eval = gameCopy.minimaxAlphaBetaAlg(gameCopy, depth - 1, alpha, beta, false, m_Player);
maxEval = max(maxEval, eval);
alpha = max(alpha, maxEval);
if(beta <= alpha)
break;
}
return maxEval;
}
else
{
int minEval = INT_MAX;
auto& playableMoves = (m_Player == Color::WHITE) ? game.m_WhitePlayable : game.m_BlackPlayable;
for (auto &[from, to] : playableMoves)
{
CGame gameCopy = game;
gameCopy.makeMove(from, to, m_Player, true);
int eval = gameCopy.minimaxAlphaBetaAlg(gameCopy, depth - 1, alpha, beta, true, m_Computer);
minEval = min(minEval, eval);
beta = min(beta, minEval);
if(beta <= alpha)
break;
}
return minEval;
}
}
Eval function
int CGame::evaluateBoard(Color color)
{
int eval = 0;
for(long int i = 0; i < m_Board.getSize(); i++)
{
for (long int j = 0; j < m_Board.getSize(); j++)
{
if(m_Board[i][j].getType() == Type::QUEEN)
{
if(m_Board[i][j].getColor() == color)
eval += 50;
else
eval -= 50;
}
...
}
}
if(m_Board.isPieceUnderAttack(m_WhiteKing, Color::WHITE, m_WhitePlayable, m_BlackPlayable) && m_WhitePlayable.empty())
return (color == Color::BLACK) ? eval += 1000 : eval -= 1000;
if(m_Board.isPieceUnderAttack(m_BlackKing, Color::BLACK, m_WhitePlayable, m_BlackPlayable) && m_BlackPlayable.empty())
return (color == Color::WHITE) ? eval += 1000 : eval -= 1000;
return eval;
}
main
int main()
{
CGame game(4, Color::BLACK, Color::WHITE);
game.minimaxAlphaBeta(5, Color::WHITE, true); // true -> random moves player
}
Complet program:
https://onecompiler.com/cpp/42e7amrff
C++ mini Chess game minimax alg
C++ minimax mini chess
user24995323 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1