/// 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))
}
+/// Position::pl_move_is_evasion() tests whether a pseudo-legal move is a legal evasion
+
+bool Position::pl_move_is_evasion(Move m, Bitboard pinned) const
+{
+ assert(is_check());
+
+ Color us = side_to_move();
+ Square from = move_from(m);
+ Square to = move_to(m);
+
+ // King moves and en-passant captures are verified in pl_move_is_legal()
+ if (type_of_piece_on(from) == KING || move_is_ep(m))
+ return pl_move_is_legal(m, pinned);
+
+ Bitboard target = checkers();
+ Square checksq = pop_1st_bit(&target);
+
+ if (target) // double check ?
+ return false;
+
+ // Our move must be a blocking evasion or a capture of the checking piece
+ target = squares_between(checksq, king_square(us)) | checkers();
+ return bit_is_set(target, to) && pl_move_is_legal(m, pinned);
+}
+
+
/// Position::move_is_check() tests whether a pseudo-legal move is a check
bool Position::move_is_check(Move m) const {
int Position::see(Square to) const {
assert(square_is_ok(to));
- return see(SQ_NONE, to, false);
+ return see(SQ_NONE, to);
}
int Position::see(Move m) const {
assert(move_is_ok(m));
- return see(move_from(m), move_to(m), false);
+ return see(move_from(m), move_to(m));
}
int Position::see_sign(Move m) const {
&& type_of_piece_on(from) != KING)
return 1;
- return see(from, to, true);
+ return see(from, to);
}
-int Position::see(Square from, Square to, bool shortcut) const {
+int Position::see(Square from, Square to) const {
// Material values
static const int seeValues[18] = {
};
Bitboard attackers, stmAttackers, b;
- int pieceDiff = 0;
- assert(!shortcut || from != SQ_NONE);
assert(square_is_ok(from) || from == SQ_NONE);
assert(square_is_ok(to));
if (type_of_piece(piece) == KING)
return seeValues[capture];
- // If captured piece is defended by enemy pawns or knights then SEE is negative
- // when captured piece value does not compensate the lost of capturing one.
- if (shortcut)
- {
- pieceDiff = seeValues[piece] - seeValues[capture];
-
- if ( pieceDiff > seeValues[PAWN]
- &&(attacks_from<PAWN>(to, us) & pieces(PAWN, them)))
- return -(pieceDiff - seeValues[PAWN] / 2);
-
- if ( pieceDiff > seeValues[KNIGHT]
- && pieces(KNIGHT, them)
- &&(pieces(KNIGHT, them) & attacks_from<KNIGHT>(to)))
- return -(pieceDiff - seeValues[KNIGHT] / 2);
- }
-
// Handle en passant moves
if (st->epSquare == to && type_of_piece_on(from) == PAWN)
{
for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
assert(pt < KING);
- // If captured piece is defended by an enemy piece then SEE is negative
- // if captured piece value does not compensate the lost of capturing one.
- if (pieceDiff > seeValues[pt])
- {
- assert(shortcut);
- return -(pieceDiff - seeValues[pt] / 2);
- } else
- pieceDiff = 0; // Only first cycle
-
// Remove the attacker we just found from the 'attackers' bitboard,
// and scan for new X-ray attacks behind the attacker.
b = stmAttackers & pieces(pt);
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