X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=23402939a67bcea1ed663b821dd9fcecb742ec58;hp=c6b59b39b92afa07d0a82331f1d3bc6e367cec82;hb=2bceba7f5162198834ca9f3dca0258e7eac1f797;hpb=05f7d59a9a27d9f8bce8bde4e9fed7ecefeb03b9 diff --git a/src/search.cpp b/src/search.cpp index c6b59b39..23402939 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -73,10 +73,10 @@ namespace { // Futility and reductions lookup tables, initialized at startup int FutilityMoveCounts[2][16]; // [improving][depth] - int Reductions[2][2][64][64]; // [pv][improving][depth][moveNumber] + int Reductions[2][64][64]; // [improving][depth][moveNumber] template Depth reduction(bool i, Depth d, int mn) { - return Reductions[PvNode][i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] * ONE_PLY; + return (Reductions[i][std::min(d / ONE_PLY, 63)][std::min(mn, 63)] - PvNode) * ONE_PLY; } // History and stats update bonus, based on depth @@ -162,12 +162,11 @@ void Search::init() { { double r = log(d) * log(mc) / 1.95; - Reductions[NonPV][imp][d][mc] = int(std::round(r)); - Reductions[PV][imp][d][mc] = std::max(Reductions[NonPV][imp][d][mc] - 1, 0); + Reductions[imp][d][mc] = std::round(r); // Increase reduction for non-PV nodes when eval is not improving if (!imp && r > 1.0) - Reductions[NonPV][imp][d][mc]++; + Reductions[imp][d][mc]++; } for (int d = 0; d < 16; ++d) @@ -302,7 +301,7 @@ void Thread::search() { // The former is needed to allow update_continuation_histories(ss-1, ...), // which accesses its argument at ss-4, also near the root. // The latter is needed for statScores and killer initialization. - Stack stack[MAX_PLY+8], *ss = stack+5; + Stack stack[MAX_PLY+10], *ss = stack+7; Move pv[MAX_PLY+1]; Value bestValue, alpha, beta, delta; Move lastBestMove = MOVE_NONE; @@ -312,8 +311,8 @@ void Thread::search() { Color us = rootPos.side_to_move(); bool failedLow; - std::memset(ss-5, 0, 8 * sizeof(Stack)); - for (int i = 5; i > 0; i--) + std::memset(ss-7, 0, 10 * sizeof(Stack)); + for (int i = 7; i > 0; i--) (ss-i)->continuationHistory = &this->continuationHistory[NO_PIECE][0]; // Use as sentinel ss->pv = pv; @@ -570,7 +569,7 @@ namespace { Depth extension, newDepth; Value bestValue, value, ttValue, eval, maxValue, pureStaticEval; bool ttHit, ttPv, inCheck, givesCheck, improving; - bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture; + bool captureOrPromotion, doFullDepthSearch, moveCountPruning, ttCapture; Piece movedPiece; int moveCount, captureCount, quietCount; @@ -831,7 +830,7 @@ namespace { int probCutCount = 0; while ( (move = mp.next_move()) != MOVE_NONE - && probCutCount < 3) + && probCutCount < 2 + 2 * cutNode) if (move != excludedMove && pos.legal(move)) { probCutCount++; @@ -846,7 +845,7 @@ namespace { // Perform a preliminary qsearch to verify that the move holds value = -qsearch(pos, ss+1, -raisedBeta, -raisedBeta+1); - // If the qsearch held perform the regular search + // If the qsearch held, perform the regular search if (value >= raisedBeta) value = -search(pos, ss+1, -raisedBeta, -raisedBeta+1, depth - 4 * ONE_PLY, !cutNode); @@ -870,7 +869,9 @@ namespace { moves_loop: // When in check, search starts from here - const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, nullptr, (ss-4)->continuationHistory }; + const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, + nullptr, (ss-4)->continuationHistory, + nullptr, (ss-6)->continuationHistory }; Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq]; MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory, @@ -880,12 +881,12 @@ moves_loop: // When in check, search starts from here ss->killers); value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc - skipQuiets = false; + moveCountPruning = false; ttCapture = ttMove && pos.capture_or_promotion(ttMove); // Step 12. Loop through all pseudo-legal moves until no moves remain // or a beta cutoff occurs. - while ((move = mp.next_move(skipQuiets)) != MOVE_NONE) + while ((move = mp.next_move(moveCountPruning)) != MOVE_NONE) { assert(is_ok(move)); @@ -914,9 +915,6 @@ moves_loop: // When in check, search starts from here movedPiece = pos.moved_piece(move); givesCheck = gives_check(pos, move); - moveCountPruning = depth < 16 * ONE_PLY - && moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY]; - // Step 13. Extensions (~70 Elo) // Singular extension search (~60 Elo). If all moves but one fail low on a @@ -967,16 +965,17 @@ moves_loop: // When in check, search starts from here && pos.non_pawn_material(us) && bestValue > VALUE_MATED_IN_MAX_PLY) { + // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold + moveCountPruning = depth < 16 * ONE_PLY + && moveCount >= FutilityMoveCounts[improving][depth / ONE_PLY]; + if ( !captureOrPromotion && !givesCheck && !pos.advanced_pawn_push(move)) { // Move count based pruning (~30 Elo) if (moveCountPruning) - { - skipQuiets = true; continue; - } // Reduced depth of the next LMR search int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), DEPTH_ZERO) / ONE_PLY; @@ -1323,7 +1322,9 @@ moves_loop: // When in check, search starts from here futilityBase = bestValue + 128; } - const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, nullptr, (ss-4)->continuationHistory }; + const PieceToHistory* contHist[] = { (ss-1)->continuationHistory, (ss-2)->continuationHistory, + nullptr, (ss-4)->continuationHistory, + nullptr, (ss-6)->continuationHistory }; // Initialize a MovePicker object for the current position, and prepare // to search the moves. Because the depth is <= 0 here, only captures, @@ -1473,7 +1474,7 @@ 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}) + for (int i : {1, 2, 4, 6}) if (is_ok((ss-i)->currentMove)) (*(ss-i)->continuationHistory)[pc][to] << bonus; }