From dddaeff7d8d4a0c255310d054a53066296e71004 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Sat, 31 Oct 2009 11:16:40 +0100 Subject: [PATCH] Another see() shortcut Because we only generate legal moves we can assume a king cannot be recaptured, so we can safely return immediately with the captured piece score. If the move turns out to be illegal it will be pruned anyhow, independently from SEE value. This gives a good speed up especially now that we SEE-test all the evasions that are always legal and very often are king moves. Another optimization catches almost 15% of cases, unfortunatly we have already calculated the very expensive attacks, so benefits are not so big anyway. Signed-off-by: Marco Costalba --- src/position.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index b6a8d746..1fe723ae 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1337,6 +1337,7 @@ int Position::see(Square from, Square to, bool shortcut) const { }; Bitboard attackers, stmAttackers, b; + int pieceDiff = 0; assert(!shortcut || from != SQ_NONE); assert(square_is_ok(from) || from == SQ_NONE); @@ -1351,20 +1352,24 @@ int Position::see(Square from, Square to, bool shortcut) const { Piece capture = piece_on(to); Bitboard occ = occupied_squares(); + // King cannot be recaptured + 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 is not enough to compensate the lost of capturing one. + // when captured piece value does not compensate the lost of capturing one. if (shortcut) { - int diff = seeValues[piece] - seeValues[capture]; + pieceDiff = seeValues[piece] - seeValues[capture]; - if ( diff > seeValues[PAWN] + if ( pieceDiff > seeValues[PAWN] &&(attacks_from(to, us) & pieces(PAWN, them))) - return -(diff - seeValues[PAWN] / 2); + return -(pieceDiff - seeValues[PAWN] / 2); - if ( diff > seeValues[KNIGHT] + if ( pieceDiff > seeValues[KNIGHT] && pieces(KNIGHT, them) &&(pieces(KNIGHT, them) & attacks_from(to))) - return -(diff - seeValues[KNIGHT] / 2); + return -(pieceDiff - seeValues[KNIGHT] / 2); } // Handle en passant moves @@ -1437,6 +1442,15 @@ int Position::see(Square from, Square to, bool shortcut) const { 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); -- 2.39.2