X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fposition.cpp;h=10c9d6796311fd5bf061d6d1bbac4b15686a56c5;hb=06f06a9be8b888c540e95bbc35a84b541fef4a34;hp=b6a8d7465d5911a84b06f52e5e48edfec5e86965;hpb=941d923bf81128e5420ffe3dcf0116bf7758f430;p=stockfish diff --git a/src/position.cpp b/src/position.cpp index b6a8d746..10c9d679 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -458,19 +458,11 @@ void Position::find_checkers() { /// 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)) @@ -482,7 +474,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { 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)) @@ -519,6 +511,32 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { } +/// 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 { @@ -1300,13 +1318,13 @@ void Position::undo_null_move() { 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 { @@ -1322,10 +1340,10 @@ 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] = { @@ -1338,7 +1356,6 @@ int Position::see(Square from, Square to, bool shortcut) const { Bitboard attackers, stmAttackers, b; - assert(!shortcut || from != SQ_NONE); assert(square_is_ok(from) || from == SQ_NONE); assert(square_is_ok(to)); @@ -1351,21 +1368,9 @@ int Position::see(Square from, Square to, bool shortcut) const { Piece capture = piece_on(to); Bitboard occ = occupied_squares(); - // If captured piece is defended by enemy pawns or knights then SEE is negative - // when captured piece value is not enough to compensate the lost of capturing one. - if (shortcut) - { - int diff = seeValues[piece] - seeValues[capture]; - - if ( diff > seeValues[PAWN] - &&(attacks_from(to, us) & pieces(PAWN, them))) - return -(diff - seeValues[PAWN] / 2); - - if ( diff > seeValues[KNIGHT] - && pieces(KNIGHT, them) - &&(pieces(KNIGHT, them) & attacks_from(to))) - return -(diff - seeValues[KNIGHT] / 2); - } + // 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) @@ -1718,8 +1723,7 @@ bool Position::is_draw() const { 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); } @@ -1740,11 +1744,10 @@ bool Position::has_mate_threat(Color c) { 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