X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=fdef140026bd529a52390e8954f536eff42fa5ef;hp=44347f79f8b85ec1aee88b579c65c6f9d9b48908;hb=3a572ffb4840bfea3c587c9c81a0008515f02a32;hpb=5c4002aa827653a125130a0d01d0bb96dd2b8bae
diff --git a/src/search.cpp b/src/search.cpp
index 44347f79..fdef1400 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -18,6 +18,7 @@
along with this program. If not, see .
*/
+#include
#include
#include
#include // For std::memset
@@ -69,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) {
+ 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;
+ return ((r + 512) / 1024 + (!i && r > 1024)) * ONE_PLY;
}
constexpr int futility_move_count(bool improving, int depth) {
@@ -148,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(733.3 * std::log(i));
}
@@ -240,10 +241,8 @@ void MainThread::search() {
// Vote according to score and depth
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]];
@@ -405,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;
@@ -593,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
@@ -851,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.
@@ -894,7 +894,7 @@ moves_loop: // When in check, search starts from here
&& move == ttMove
&& !rootNode
&& !excludedMove // Avoid recursive singular search
- /* && ttValue != VALUE_NONE Already implicit in the next condition */
+ /* && ttValue != VALUE_NONE Already implicit in the next condition */
&& abs(ttValue) < VALUE_KNOWN_WIN
&& (tte->bound() & BOUND_LOWER)
&& tte->depth() >= depth - 3 * ONE_PLY
@@ -907,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
@@ -960,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)
@@ -1003,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)
{
@@ -1201,8 +1210,8 @@ moves_loop: // When in check, search starts from here
}
- // qsearch() is the quiescence search function, which is called by the main
- // search function with depth zero, or recursively with depth less than ONE_PLY.
+ // qsearch() is the quiescence search function, which is called by the main search
+ // function with zero depth, or recursively with further decreasing depth per call.
template
Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) {