From 96d3b1c92b8db7d2238fc4993a4f3da49f04d614 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Wed, 7 Nov 2012 18:20:39 +0100 Subject: [PATCH] Don't prune discovered checks Don't prune and eventually extend check moves of type DISCO_CHECK (pun intended, Lucas will understand :-) ). Patch from Lucas Braesch that has also tested it: Result: 879-661-2137, score=52.96%, LOS=100.00% (time 10"+0.1") I have started a verification test right now. bench: 6004966 --- src/position.cpp | 16 ++++++++-------- src/position.h | 2 +- src/search.cpp | 10 +++++++--- src/types.h | 6 ++++++ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/position.cpp b/src/position.cpp index 004d6994..9f2ee197 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -657,7 +657,7 @@ bool Position::is_pseudo_legal(const Move m) const { /// Position::move_gives_check() tests whether a pseudo-legal move gives a check -bool Position::move_gives_check(Move m, const CheckInfo& ci) const { +CheckType Position::move_gives_check(Move m, const CheckInfo& ci) const { assert(is_ok(m)); assert(ci.dcCandidates == discovered_check_candidates()); @@ -669,7 +669,7 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { // Direct check ? if (ci.checkSq[pt] & to) - return true; + return DIRECT_CHECK; // Discovery check ? if (ci.dcCandidates && (ci.dcCandidates & from)) @@ -677,19 +677,19 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { // For pawn and king moves we need to verify also direction if ( (pt != PAWN && pt != KING) || !squares_aligned(from, to, king_square(~sideToMove))) - return true; + return DISCO_CHECK; } // Can we skip the ugly special cases ? if (type_of(m) == NORMAL) - return false; + return NO_CHECK; Color us = sideToMove; Square ksq = king_square(~us); // Promotion with check ? if (type_of(m) == PROMOTION) - return attacks_from(Piece(promotion_type(m)), to, pieces() ^ from) & ksq; + return attacks_from(Piece(promotion_type(m)), to, pieces() ^ from) & ksq ? DIRECT_CHECK : NO_CHECK; // En passant capture with check ? We have already handled the case // of direct checks and ordinary discovered check, the only case we @@ -701,7 +701,7 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { Bitboard b = (pieces() ^ from ^ capsq) | to; return (attacks_bb< ROOK>(ksq, b) & pieces(us, QUEEN, ROOK)) - | (attacks_bb(ksq, b) & pieces(us, QUEEN, BISHOP)); + | (attacks_bb(ksq, b) & pieces(us, QUEEN, BISHOP)) ? DISCO_CHECK : NO_CHECK; } // Castling with check ? @@ -713,10 +713,10 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { Square rto = relative_square(us, rfrom > kfrom ? SQ_F1 : SQ_D1); Bitboard b = (pieces() ^ kfrom ^ rfrom) | rto | kto; - return attacks_bb(rto, b) & ksq; + return attacks_bb(rto, b) & ksq ? DIRECT_CHECK : NO_CHECK; } - return false; + return NO_CHECK; } diff --git a/src/position.h b/src/position.h index d09dce08..813cd010 100644 --- a/src/position.h +++ b/src/position.h @@ -136,7 +136,7 @@ public: template Bitboard attacks_from(Square s, Color c) const; // Properties of moves - bool move_gives_check(Move m, const CheckInfo& ci) const; + CheckType move_gives_check(Move m, const CheckInfo& ci) const; bool move_is_legal(const Move m) const; bool pl_move_is_legal(Move m, Bitboard pinned) const; bool is_pseudo_legal(const Move m) const; diff --git a/src/search.cpp b/src/search.cpp index 3ffd8ae4..35a39681 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -483,7 +483,8 @@ namespace { Depth ext, newDepth; Value bestValue, value, ttValue; Value eval, nullValue, futilityValue; - bool inCheck, givesCheck, pvMove, singularExtensionNode; + CheckType givesCheck; + bool inCheck, pvMove, singularExtensionNode; bool captureOrPromotion, dangerous, doFullDepthSearch; int moveCount, playedMoveCount; @@ -815,7 +816,7 @@ split_point_start: // At split points actual search starts from here if (PvNode && dangerous) ext = ONE_PLY; - else if (givesCheck && pos.see_sign(move) >= 0) + else if (givesCheck && (givesCheck == DISCO_CHECK || pos.see_sign(move) >= 0)) ext = ONE_PLY / 2; // Singular extension search. If all moves but one fail low on a search of @@ -882,6 +883,7 @@ split_point_start: // At split points actual search starts from here // Prune moves with negative SEE at low depths if ( predictedDepth < 2 * ONE_PLY + && givesCheck != DISCO_CHECK && pos.see_sign(move) < 0) { if (SpNode) @@ -1102,7 +1104,8 @@ split_point_start: // At split points actual search starts from here Key posKey; Move ttMove, move, bestMove; Value bestValue, value, ttValue, futilityValue, futilityBase; - bool givesCheck, enoughMaterial, evasionPrunable, fromNull; + CheckType givesCheck; + bool enoughMaterial, evasionPrunable, fromNull; Depth ttDepth; ss->currentMove = bestMove = MOVE_NONE; @@ -1234,6 +1237,7 @@ split_point_start: // At split points actual search starts from here if ( !PvNode && (!InCheck || evasionPrunable) && move != ttMove + && givesCheck != DISCO_CHECK && type_of(move) != PROMOTION && pos.see_sign(move) < 0) continue; diff --git a/src/types.h b/src/types.h index 9b36fd89..eea31e3b 100644 --- a/src/types.h +++ b/src/types.h @@ -130,6 +130,12 @@ enum MoveType { CASTLE = 3 << 14 }; +enum CheckType { + NO_CHECK, + DIRECT_CHECK, + DISCO_CHECK +}; + enum CastleRight { // Defined as in PolyGlot book hash key CASTLES_NONE = 0, WHITE_OO = 1, -- 2.39.2