From: Marco Costalba Date: Wed, 22 Jun 2011 22:04:57 +0000 (+0100) Subject: Fix move_is_capture() to detect capture promotions X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=6a1707889c19bf37a0ef84fb67ffc57e6168e34d Fix move_is_capture() to detect capture promotions We miss to account as a capture a promotion capture ! Incredible bug in this critical function that is here since a long time (b50921fd5c3e1753 of 21/10/2009 !!) This patch fixes the bug and readds the faster move_is_capture_or_promotion() that slightly increases overall speed. Signed-off-by: Marco Costalba --- diff --git a/src/movepick.cpp b/src/movepick.cpp index 71c9810d..1a8f5bf6 100644 --- a/src/movepick.cpp +++ b/src/movepick.cpp @@ -103,7 +103,7 @@ MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const History& h, S // Skip TT move if is not a capture or a promotion, this avoids // qsearch tree explosion due to a possible perpetual check or // similar rare cases when TT table is full. - if (ttm != MOVE_NONE && !pos.move_is_capture(ttm) && !move_is_promotion(ttm)) + if (ttm != MOVE_NONE && !pos.move_is_capture_or_promotion(ttm)) ttm = MOVE_NONE; } else diff --git a/src/position.h b/src/position.h index 84602552..9b7ce5a4 100644 --- a/src/position.h +++ b/src/position.h @@ -189,6 +189,7 @@ public: bool move_is_pl(const Move m) const; bool move_gives_check(Move m, const CheckInfo& ci) const; bool move_is_capture(Move m) const; + bool move_is_capture_or_promotion(Move m) const; bool move_is_passed_pawn_push(Move m) const; bool move_attacks_square(Move m, Square s) const; @@ -534,10 +535,18 @@ inline bool Position::is_chess960() const { return chess960; } +inline bool Position::move_is_capture_or_promotion(Move m) const { + + assert(m != MOVE_NONE && m != MOVE_NULL); + return move_is_special(m) ? !move_is_castle(m) : !square_is_empty(move_to(m)); +} + inline bool Position::move_is_capture(Move m) const { - assert (m != MOVE_NONE && m != MOVE_NULL); - return !move_is_special(m) ? !square_is_empty(move_to(m)) : move_is_ep(m); + assert(m != MOVE_NONE && m != MOVE_NULL); + + // Note that castle is coded as "king captures the rook" + return (!square_is_empty(move_to(m)) && !move_is_castle(m)) || move_is_ep(m); } inline PieceType Position::captured_piece_type() const { diff --git a/src/search.cpp b/src/search.cpp index 6208da61..53deb0f2 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1013,7 +1013,7 @@ split_point_start: // At split points actual search starts from here // At Root and at first iteration do a PV search on all the moves to score root moves isPvMove = (PvNode && moveCount <= (RootNode ? depth <= ONE_PLY ? MAX_MOVES : MultiPV : 1)); givesCheck = pos.move_gives_check(move, ci); - captureOrPromotion = pos.move_is_capture(move) || move_is_promotion(move); + captureOrPromotion = pos.move_is_capture_or_promotion(move); // Step 12. Decide the new search depth ext = extension(pos, move, captureOrPromotion, givesCheck, &dangerous); @@ -1279,8 +1279,7 @@ split_point_start: // At split points actual search starts from here // Update killers and history only for non capture moves that fails high if ( bestValue >= beta - && !pos.move_is_capture(move) - && !move_is_promotion(move)) + && !pos.move_is_capture_or_promotion(move)) { if (move != ss->killers[0]) { @@ -1450,8 +1449,7 @@ split_point_start: // At split points actual search starts from here && !inCheck && givesCheck && move != ttMove - && !pos.move_is_capture(move) - && !move_is_promotion(move) + && !pos.move_is_capture_or_promotion(move) && ss->eval + PawnValueMidgame / 4 < beta && !check_is_dangerous(pos, move, futilityBase, beta, &bestValue)) { @@ -1650,7 +1648,7 @@ split_point_start: // At split points actual search starts from here assert(move_is_ok(m)); assert(threat && move_is_ok(threat)); - assert(!pos.move_is_capture(m) && !move_is_promotion(m)); + assert(!pos.move_is_capture_or_promotion(m)); assert(!pos.move_is_passed_pawn_push(m)); Square mfrom, mto, tfrom, tto;