/// Position::pl_move_is_legal() tests whether a pseudo-legal move is legal
-bool Position::pl_move_is_legal(Move m) const {
-
- // If we're in check, all pseudo-legal moves are legal, because our
- // check evasion generator only generates true legal moves.
- return is_check() || pl_move_is_legal(m, pinned_pieces(side_to_move()));
-}
-
bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
assert(is_ok());
assert(move_is_ok(m));
assert(pinned == pinned_pieces(side_to_move()));
- assert(!is_check());
// Castling moves are checked for legality during move generation.
if (move_is_castle(m))
assert(color_of_piece_on(from) == us);
assert(piece_on(king_square(us)) == piece_of_color_and_type(us, KING));
- // En passant captures are a tricky special case. Because they are
+ // En passant captures are a tricky special case. Because they are
// rather uncommon, we do it simply by testing whether the king is attacked
// after the move is made
if (move_is_ep(m))
// pointer to point to the new, ready to be updated, state.
struct ReducedStateInfo {
Key key, pawnKey, materialKey;
- int castleRights, rule50;
+ int castleRights, rule50, pliesFromNull;
Square epSquare;
Value mgValue, egValue;
Value npMaterial[2];
// Increment the 50 moves rule draw counter. Resetting it to zero in the
// case of non-reversible moves is taken care of later.
st->rule50++;
+ st->pliesFromNull++;
if (move_is_castle(m))
{
// Note that differently from normal case here backupSt is actually used as
// a backup storage not as a new state to be used.
backupSt.key = st->key;
- backupSt.rule50 = st->rule50;
backupSt.epSquare = st->epSquare;
backupSt.mgValue = st->mgValue;
backupSt.egValue = st->egValue;
backupSt.previous = st->previous;
+ backupSt.pliesFromNull = st->pliesFromNull;
st->previous = &backupSt;
// Save the current key to the history[] array, in order to be able to
sideToMove = opposite_color(sideToMove);
st->epSquare = SQ_NONE;
- st->rule50 = 0;
+ st->rule50++;
+ st->pliesFromNull = 0;
gamePly++;
st->mgValue += (sideToMove == WHITE)? TempoValueMidgame : -TempoValueMidgame;
// Restore information from the our backup StateInfo object
StateInfo* backupSt = st->previous;
st->key = backupSt->key;
- st->rule50 = backupSt->rule50;
st->epSquare = backupSt->epSquare;
st->mgValue = backupSt->mgValue;
st->egValue = backupSt->egValue;
st->previous = backupSt->previous;
+ st->pliesFromNull = backupSt->pliesFromNull;
// Update the necessary information
sideToMove = opposite_color(sideToMove);
+ st->rule50--;
gamePly--;
}
Piece capture = piece_on(to);
Bitboard occ = occupied_squares();
+ // King cannot be recaptured
+ if (type_of_piece(piece) == KING)
+ return seeValues[capture];
+
// Handle en passant moves
if (st->epSquare == to && type_of_piece_on(from) == PAWN)
{
for (int i = 0; i < 64; i++)
board[i] = EMPTY;
- for (int i = 0; i < 7; i++)
- for (int j = 0; j < 8; j++)
+ for (int i = 0; i < 8; i++)
+ for (int j = 0; j < 16; j++)
pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE;
sideToMove = WHITE;
return true;
// Draw by repetition?
- for (int i = 2; i < Min(gamePly, st->rule50); i += 2)
+ for (int i = 2; i < Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2)
if (history[gamePly - i] == st->key)
return true;
bool Position::is_mate() const {
MoveStack moves[256];
-
- return is_check() && (generate_evasions(*this, moves, pinned_pieces(sideToMove)) == moves);
+ return is_check() && (generate_moves(*this, moves, false) == moves);
}
MoveStack mlist[120];
bool result = false;
- Bitboard dc = discovered_check_candidates(sideToMove);
Bitboard pinned = pinned_pieces(sideToMove);
// Generate pseudo-legal non-capture and capture check moves
- MoveStack* last = generate_non_capture_checks(*this, mlist, dc);
+ MoveStack* last = generate_non_capture_checks(*this, mlist);
last = generate_captures(*this, last);
// Loop through the moves, and see if one of them is mate