X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=a3ce4c2d3a49c2a257dc9a74a35e5e3f3a2aa7bf;hp=082be4f25587a7ec4d0e329b14890ae3c9446bb2;hb=190f38a7c2a64f7e89f06871533d87ba7b287fdc;hpb=4e72e2a964754611de85536c13ae069f85839b85 diff --git a/src/search.cpp b/src/search.cpp index 082be4f2..a3ce4c2d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -70,9 +70,9 @@ namespace { // Reductions lookup table, initialized at startup int Reductions[MAX_MOVES]; // [depth or moveNumber] - template Depth reduction(bool i, Depth d, int mn) { - int r = Reductions[d / ONE_PLY] * Reductions[mn] / 1024; - return ((r + 512) / 1024 + (!i && r > 1024) - PvNode) * ONE_PLY; + Depth reduction(bool i, Depth d, int mn) { + int r = Reductions[d / ONE_PLY] * Reductions[mn]; + return ((r + 512) / 1024 + (!i && r > 1024)) * ONE_PLY; } constexpr int futility_move_count(bool improving, int depth) { @@ -149,7 +149,7 @@ namespace { void Search::init() { for (int i = 1; i < MAX_MOVES; ++i) - Reductions[i] = int(1024 * std::log(i) / std::sqrt(1.95)); + Reductions[i] = int(22.9 * std::log(i)); } @@ -239,21 +239,19 @@ void MainThread::search() { for (Thread* th: Threads) minScore = std::min(minScore, th->rootMoves[0].score); - // Vote according to score and depth + // Vote according to score and depth, and select the best thread + int64_t bestVote = 0; for (Thread* th : Threads) { - int64_t s = th->rootMoves[0].score - minScore + 1; - votes[th->rootMoves[0].pv[0]] += 200 + s * s * int(th->completedDepth); - } + votes[th->rootMoves[0].pv[0]] += + (th->rootMoves[0].score - minScore + 14) * int(th->completedDepth); - // Select best thread - auto bestVote = votes[this->rootMoves[0].pv[0]]; - for (Thread* th : Threads) if (votes[th->rootMoves[0].pv[0]] > bestVote) { bestVote = votes[th->rootMoves[0].pv[0]]; bestThread = th; } + } } previousScore = bestThread->rootMoves[0].score; @@ -406,17 +404,14 @@ void Thread::search() { beta = (alpha + beta) / 2; alpha = std::max(bestValue - delta, -VALUE_INFINITE); + failedHighCnt = 0; if (mainThread) - { - failedHighCnt = 0; mainThread->stopOnPonderhit = false; - } } else if (bestValue >= beta) { beta = std::min(bestValue + delta, VALUE_INFINITE); - if (mainThread) - ++failedHighCnt; + ++failedHighCnt; } else break; @@ -594,7 +589,10 @@ namespace { // starts with statScore = 0. Later grandchildren start with the last calculated // statScore of the previous grandchild. This influences the reduction rules in // LMR which are based on the statScore of parent position. - (ss+2)->statScore = 0; + if (rootNode) + (ss + 4)->statScore = 0; + else + (ss + 2)->statScore = 0; // Step 4. Transposition table lookup. We don't want the score of a partial // search to overwrite a previous full search TT value, so we use a different @@ -852,6 +850,7 @@ moves_loop: // When in check, search starts from here value = bestValue; // Workaround a bogus 'uninitialized' warning under gcc moveCountPruning = false; ttCapture = ttMove && pos.capture_or_promotion(ttMove); + int singularExtensionLMRmultiplier = 0; // Step 12. Loop through all pseudo-legal moves until no moves remain // or a beta cutoff occurs. @@ -908,7 +907,12 @@ moves_loop: // When in check, search starts from here ss->excludedMove = MOVE_NONE; if (value < singularBeta) + { extension = ONE_PLY; + singularExtensionLMRmultiplier++; + if (value < singularBeta - std::min(3 * depth / ONE_PLY, 39)) + singularExtensionLMRmultiplier++; + } // Multi-cut pruning // Our ttMove is assumed to fail high, and now we failed high also on a reduced @@ -961,7 +965,7 @@ moves_loop: // When in check, search starts from here continue; // Reduced depth of the next LMR search - int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), DEPTH_ZERO); + int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), DEPTH_ZERO); lmrDepth /= ONE_PLY; // Countermoves based pruning (~20 Elo) @@ -1004,18 +1008,22 @@ moves_loop: // When in check, search starts from here // Step 16. Reduced depth search (LMR). If the move fails high it will be // re-searched at full depth. if ( depth >= 3 * ONE_PLY - && moveCount > 1 - && (!captureOrPromotion || moveCountPruning)) + && moveCount > 1 + 3 * rootNode + && ( !captureOrPromotion + || moveCountPruning + || ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha)) { - Depth r = reduction(improving, depth, moveCount); + Depth r = reduction(improving, depth, moveCount); // Decrease reduction if position is or has been on the PV if (ttPv) - r -= ONE_PLY; + r -= 2 * ONE_PLY; // Decrease reduction if opponent's move count is high (~10 Elo) if ((ss-1)->moveCount > 15) r -= ONE_PLY; + // Decrease reduction if move has been singularly extended + r -= singularExtensionLMRmultiplier * ONE_PLY; if (!captureOrPromotion) {