X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=4a541c5b90697137371c47cfb53662d066472e27;hp=5b6a048500b0842c1b59a97f7913532139ae54e0;hb=f7e14f8032cd390610d8a0a7d7e5cbcb6743bc65;hpb=4e2bb8fa44fe03a2fdb2d3448ac93986354bf9ae diff --git a/src/search.cpp b/src/search.cpp index 5b6a0485..4a541c5b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -254,7 +254,7 @@ void MainThread::search() { && !Skill(Options["Skill Level"]).enabled() && rootMoves[0].pv[0] != MOVE_NONE) { - std::map votes; + std::map votes; Value minScore = this->rootMoves[0].score; // Find out minimum score and reset votes for moves which can be voted @@ -265,12 +265,13 @@ void MainThread::search() { } // Vote according to score and depth + auto square = [](int64_t x) { return x * x; }; for (Thread* th : Threads) - votes[th->rootMoves[0].pv[0]] += int(th->rootMoves[0].score - minScore) - + int(th->completedDepth); + votes[th->rootMoves[0].pv[0]] += 200 + (square(th->rootMoves[0].score - minScore + 1) + * int64_t(th->completedDepth)); // Select best thread - int bestVote = votes[this->rootMoves[0].pv[0]]; + int64_t bestVote = votes[this->rootMoves[0].pv[0]]; for (Thread* th : Threads) { if (votes[th->rootMoves[0].pv[0]] > bestVote) @@ -302,7 +303,11 @@ void MainThread::search() { void Thread::search() { - Stack stack[MAX_PLY+7], *ss = stack+4; // To reference from (ss-4) to (ss+2) + // To allow access to (ss-5) up to (ss+2), the stack must be oversized. + // 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; Move pv[MAX_PLY+1]; Value bestValue, alpha, beta, delta; Move lastBestMove = MOVE_NONE; @@ -312,8 +317,8 @@ void Thread::search() { Color us = rootPos.side_to_move(); bool failedLow; - std::memset(ss-4, 0, 7 * sizeof(Stack)); - for (int i = 4; i > 0; i--) + std::memset(ss-5, 0, 8 * sizeof(Stack)); + for (int i = 5; i > 0; i--) (ss-i)->continuationHistory = &this->continuationHistory[NO_PIECE][0]; // Use as sentinel ss->pv = pv; @@ -655,9 +660,10 @@ namespace { if (!pos.capture_or_promotion(ttMove)) update_quiet_stats(pos, ss, ttMove, nullptr, 0, stat_bonus(depth)); - // Extra penalty for a quiet TT move in previous ply when it gets refuted - if ((ss-1)->moveCount == 1 && !pos.captured_piece()) - update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY)); + // Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted + if ( ((ss-1)->moveCount == 1 || (ss-1)->currentMove == (ss-1)->killers[0]) + && !pos.captured_piece()) + update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY)); } // Penalty for a quiet ttMove that fails low else if (!pos.capture_or_promotion(ttMove)) @@ -1189,16 +1195,14 @@ moves_loop: // When in check, search starts from here update_capture_stats(pos, bestMove, capturesSearched, captureCount, stat_bonus(depth + ONE_PLY)); // Extra penalty for a quiet TT or main killer move in previous ply when it gets refuted - if ( (ss-1)->moveCount == 1 - || ((ss-1)->currentMove == (ss-1)->killers[0] && (ss-1)->killers[0])) - if (!pos.captured_piece()) + if ( ((ss-1)->moveCount == 1 || ((ss-1)->currentMove == (ss-1)->killers[0])) + && !pos.captured_piece()) update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, -stat_bonus(depth + ONE_PLY)); } // Bonus for prior countermove that caused the fail low else if ( (depth >= 3 * ONE_PLY || PvNode) - && !pos.captured_piece() - && is_ok((ss-1)->currentMove)) + && !pos.captured_piece()) update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth)); if (PvNode)