From bb5589b829b79d7c60a820d4b1634dccbc4bbb3f Mon Sep 17 00:00:00 2001 From: pb00067 Date: Tue, 21 Apr 2020 20:55:41 +0200 Subject: [PATCH] continuation histories when in check If in check, don't write to continuation histories ss-4, ss-6. Adding inCheck to the stack was needed, and might be useful for future patches. Passed STC: https://tests.stockfishchess.org/tests/view/5e9ee24acaaff5d60a50b812 LLR: 2.94 (-2.94,2.94) {-0.50,1.50} Total: 61774 W: 11725 L: 11449 D: 38600 Ptnml(0-2): 971, 7211, 14322, 7337, 1046 Passed LTC: https://tests.stockfishchess.org/tests/view/5e9eecb7caaff5d60a50b831 LLR: 2.94 (-2.94,2.94) {0.25,1.75} Total: 250822 W: 32067 L: 31179 D: 187576 Ptnml(0-2): 1745, 23126, 74824, 23928, 1788 closes https://github.com/official-stockfish/Stockfish/pull/2645 bench: 4808463 --- src/search.cpp | 40 ++++++++++++++++++++++------------------ src/search.h | 1 + 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index a7e90a08..a3d4a329 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -626,14 +626,14 @@ namespace { Move ttMove, move, excludedMove, bestMove; Depth extension, newDepth; Value bestValue, value, ttValue, eval, maxValue; - bool ttHit, ttPv, formerPv, inCheck, givesCheck, improving, didLMR, priorCapture; + bool ttHit, ttPv, formerPv, givesCheck, improving, didLMR, priorCapture; bool captureOrPromotion, doFullDepthSearch, moveCountPruning, ttCapture, singularLMR; Piece movedPiece; int moveCount, captureCount, quietCount; // Step 1. Initialize node Thread* thisThread = pos.this_thread(); - inCheck = pos.checkers(); + ss->inCheck = pos.checkers(); priorCapture = pos.captured_piece(); Color us = pos.side_to_move(); moveCount = captureCount = quietCount = ss->moveCount = 0; @@ -654,7 +654,7 @@ namespace { if ( Threads.stop.load(std::memory_order_relaxed) || pos.is_draw(ss->ply) || ss->ply >= MAX_PLY) - return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos) + return (ss->ply >= MAX_PLY && !ss->inCheck) ? evaluate(pos) : value_draw(pos.this_thread()); // Step 3. Mate distance pruning. Even if we mate at the next move our score @@ -793,7 +793,7 @@ namespace { CapturePieceToHistory& captureHistory = thisThread->captureHistory; // Step 6. Static evaluation of the position - if (inCheck) + if (ss->inCheck) { ss->staticEval = eval = VALUE_NONE; improving = false; @@ -920,7 +920,7 @@ namespace { probCutCount++; ss->currentMove = move; - ss->continuationHistory = &thisThread->continuationHistory[inCheck] + ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck] [captureOrPromotion] [pos.moved_piece(move)] [to_sq(move)]; @@ -1030,7 +1030,7 @@ moves_loop: // When in check, search starts from here // Futility pruning: parent node (~5 Elo) if ( lmrDepth < 6 - && !inCheck + && !ss->inCheck && ss->staticEval + 235 + 172 * lmrDepth <= alpha && (*contHist[0])[movedPiece][to_sq(move)] + (*contHist[1])[movedPiece][to_sq(move)] @@ -1146,7 +1146,7 @@ moves_loop: // When in check, search starts from here // Update the current move (this must be done after singular extension search) ss->currentMove = move; - ss->continuationHistory = &thisThread->continuationHistory[inCheck] + ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck] [captureOrPromotion] [movedPiece] [to_sq(move)]; @@ -1365,11 +1365,11 @@ moves_loop: // When in check, search starts from here // must be a mate or a stalemate. If we are in a singular extension search then // return a fail low score. - assert(moveCount || !inCheck || excludedMove || !MoveList(pos).size()); + assert(moveCount || !ss->inCheck || excludedMove || !MoveList(pos).size()); if (!moveCount) bestValue = excludedMove ? alpha - : inCheck ? mated_in(ss->ply) : VALUE_DRAW; + : ss->inCheck ? mated_in(ss->ply) : VALUE_DRAW; else if (bestMove) update_all_stats(pos, ss, bestMove, bestValue, beta, prevSq, @@ -1413,7 +1413,7 @@ moves_loop: // When in check, search starts from here Move ttMove, move, bestMove; Depth ttDepth; Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha; - bool ttHit, pvHit, inCheck, givesCheck, captureOrPromotion; + bool ttHit, pvHit, givesCheck, captureOrPromotion; int moveCount; if (PvNode) @@ -1426,20 +1426,20 @@ moves_loop: // When in check, search starts from here Thread* thisThread = pos.this_thread(); (ss+1)->ply = ss->ply + 1; bestMove = MOVE_NONE; - inCheck = pos.checkers(); + ss->inCheck = pos.checkers(); moveCount = 0; // Check for an immediate draw or maximum ply reached if ( pos.is_draw(ss->ply) || ss->ply >= MAX_PLY) - return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos) : VALUE_DRAW; + return (ss->ply >= MAX_PLY && !ss->inCheck) ? evaluate(pos) : VALUE_DRAW; assert(0 <= ss->ply && ss->ply < MAX_PLY); // Decide whether or not to include checks: this fixes also the type of // TT entry depth that we are going to use. Note that in qsearch we use // only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS. - ttDepth = inCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS + ttDepth = ss->inCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS : DEPTH_QS_NO_CHECKS; // Transposition table lookup posKey = pos.key(); @@ -1457,7 +1457,7 @@ moves_loop: // When in check, search starts from here return ttValue; // Evaluate the position statically - if (inCheck) + if (ss->inCheck) { ss->staticEval = VALUE_NONE; bestValue = futilityBase = -VALUE_INFINITE; @@ -1520,7 +1520,7 @@ moves_loop: // When in check, search starts from here moveCount++; // Futility pruning - if ( !inCheck + if ( !ss->inCheck && !givesCheck && futilityBase > -VALUE_KNOWN_WIN && !pos.advanced_pawn_push(move)) @@ -1543,7 +1543,7 @@ moves_loop: // When in check, search starts from here } // Don't search moves with negative SEE values - if ( !inCheck && !pos.see_ge(move)) + if ( !ss->inCheck && !pos.see_ge(move)) continue; // Speculative prefetch as early as possible @@ -1557,7 +1557,7 @@ moves_loop: // When in check, search starts from here } ss->currentMove = move; - ss->continuationHistory = &thisThread->continuationHistory[inCheck] + ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck] [captureOrPromotion] [pos.moved_piece(move)] [to_sq(move)]; @@ -1591,7 +1591,7 @@ moves_loop: // When in check, search starts from here // All legal moves have been searched. A special case: If we're in check // and no legal moves were found, it is checkmate. - if (inCheck && bestValue == -VALUE_INFINITE) + if (ss->inCheck && bestValue == -VALUE_INFINITE) return mated_in(ss->ply); // Plies to mate from the root tte->save(posKey, value_to_tt(bestValue, ss->ply), pvHit, @@ -1710,8 +1710,12 @@ moves_loop: // When in check, search starts from here void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) { for (int i : {1, 2, 4, 6}) + { + if (ss->inCheck && i > 2) + break; if (is_ok((ss-i)->currentMove)) (*(ss-i)->continuationHistory)[pc][to] << bonus; + } } diff --git a/src/search.h b/src/search.h index a900d094..1653ce92 100644 --- a/src/search.h +++ b/src/search.h @@ -49,6 +49,7 @@ struct Stack { Value staticEval; int statScore; int moveCount; + bool inCheck; }; -- 2.39.2