Assumption: The code generates LEGAL moves, not pseudo legal, so if the move generator returns 0 moves, it does mean checkmate or stalemate.
TheGame.StartDepth is the original "depth" from the start of the search.
Evaluate() calculates the game from WHITES (=1) perspective.
MATESCORE is big, but not as big as INFSCORE.
GetNextMove() handles the move ordering returning the next best move to try.
TheGame has the position info. everything is updated incrementally when doing make/unmake moves.
MOVES is an array of MOVE structures with some additional housekeeping info.
the move/unmove code passes all PERFT tests i've thrown at it.
i removed some code not associated with the problem such as the history heuristic update in the Alpha/Beta comparison.
given the following negamax() framework:
Code: Select all
int NegaMax(int depth, int Alpha, int Beta)
{
MOVES ms;
MOVE *m;
int NumMoves;
int BestValue;
int Value;
NumMoves = TheGame.GenerateLegalMoves(&ms);
if (NumMoves == 0) {
if (ms.IsInCheck == true)
return (-MATESCORE + (TheGame.StartDepth - depth));
else
return (0); // draw
}
else {
if (depth == 0)
return (TheGame.Evaluate() * TheGame.GetSideToMove());
}
BestValue = -INFSCORE;
m = ms.GetNextMove();
while (m != NULL) {
TheGame.MakeMove(m);
Value = -NegaMax(depth - 1, -Beta, -Alpha);
TheGame.UnMakeMove(m);
BestValue = max(Alpha, Value);
Alpha = max(Alpha, Value);
if (Alpha >= Beta)
break;
m = ms.GetNextMove();
}
return (BestValue);
}
-MATESCORE + (TheGame.StartDepth - depth)
i've seen so many variations during my research that i can't tell which is correct.
also, i saw some code that is used to modify Alpha/Beta when a mate is detected. Should that code be placed in the same code block prior to returning the mate value?