Pseudo legal move generation and mates
Posted: Sun Oct 22, 2017 8:20 pm
i'm converting some search code to use pseudo legal moves vs pre-determined legal moves
A problem occurs when there is a mate threat.
here is the pseudo code of the simple A/B method. is is just example code, without any bells/whistles. it uses copy/make rather than make/unmake.
The GetNextMove method will return the next available pseudo move and after the move is made on the new board, the IsSquareAttacked method is called, and if the king is in check, that move is skipped (non legal moves).
this code works fine. consider the following simplistic scenario...
the position to be analysed is a simple mate in one for the side to move.
6k1/1pp3pp/2n5/1P3p2/p2p4/P1qP1P2/KR3P1P/2b5 b - - 0 1
A call is made to AB with a depth of 1.
A white move is generated and made, and since the move doesn't leave the white in check (legal move), AB is called with depth 0, with black to move. well, since we are at depth 0, we normally call Eval(), but black is mated here. I don't have code in Eval to check for being in check, so I want to modify the search logic to deal with this situation.
One idea was to modify the top of the AB() code to read...
The logic is, if i'm at a leaf node, and i'm in check, don't call Eval(), but continue on (check extension?)
Is this the normal way to do this check (pardon the pun), or is there a better way? This looks like it could cause in-check runaway recursion.
A problem occurs when there is a mate threat.
here is the pseudo code of the simple A/B method. is is just example code, without any bells/whistles. it uses copy/make rather than make/unmake.
Code: Select all
VALUE AB(POSITION *b, int depth, VALUE alpha, VALUE beta)
{
if (depth == 0) return Eval(b);
POSITION b1;
MOVE move;
int score = -V_INF; // needs to be set as a sentinel
MoveList ml;
ml.Board(b);
ml.InitMoves();
while (move = ml.GetNextMove(&MoveType))
{
CopyBoard(&b1, b);
MakeMove(&b1, move); // make the move
if (b1.IsSquareAttacked(b1.KingLoc[b->SideToMove], b1.SideToMove))
continue; // not a legal move
score = -ABTT1(&b1, depth - 1, -beta, -alpha, &pv, NULL_OK, move);
if (score > alpha) {
if (score >= beta) // Beta cutoff?
return beta;
alpha = score;
}
} // end of move loop
if (score == -V_INF) // any valid moves?
{
// no legal moves, must be mate or stalemate
if ( b->IsSTMInCheck())
return -b->Mate;
else
return V_DRAWSCORE;
}
return alpha;
}
this code works fine. consider the following simplistic scenario...
the position to be analysed is a simple mate in one for the side to move.
6k1/1pp3pp/2n5/1P3p2/p2p4/P1qP1P2/KR3P1P/2b5 b - - 0 1
A call is made to AB with a depth of 1.
A white move is generated and made, and since the move doesn't leave the white in check (legal move), AB is called with depth 0, with black to move. well, since we are at depth 0, we normally call Eval(), but black is mated here. I don't have code in Eval to check for being in check, so I want to modify the search logic to deal with this situation.
One idea was to modify the top of the AB() code to read...
Code: Select all
bool IsKingInCheck = b->IsSTMInCheck();
if (!IsKingInCheck && (depth <= 0))
return Eval(b,false);
Is this the normal way to do this check (pardon the pun), or is there a better way? This looks like it could cause in-check runaway recursion.