X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=8d713fb86448f5b7fadcd1e472ba0b68fe70af44;hp=8099787ec71980751e8fa826f641e058326e0609;hb=1b0df1ae141be1461e3fbe809b5b27c3e360753f;hpb=d29a68f5854d0b529f2e0447fddcc6a61200c5aa diff --git a/src/search.cpp b/src/search.cpp index 8099787e..8d713fb8 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -116,28 +116,26 @@ namespace { void Search::init() { - int d; // depth (ONE_PLY == 2) - int hd; // half depth (ONE_PLY == 1) - int mc; // moveCount - // Init reductions array - for (hd = 1; hd < 64; ++hd) for (mc = 1; mc < 64; ++mc) - { - double pvRed = 0.00 + log(double(hd)) * log(double(mc)) / 3.00; - double nonPVRed = 0.33 + log(double(hd)) * log(double(mc)) / 2.25; + for (int d = 1; d < 64; ++d) + for (int mc = 1; mc < 64; ++mc) + { + double pvRed = 0.00 + log(double(d)) * log(double(mc)) / 3.00; + double nonPVRed = 0.33 + log(double(d)) * log(double(mc)) / 2.25; - Reductions[1][1][hd][mc] = int8_t( pvRed >= 1.0 ? pvRed + 0.5: 0); - Reductions[0][1][hd][mc] = int8_t(nonPVRed >= 1.0 ? nonPVRed + 0.5: 0); + Reductions[1][1][d][mc] = int8_t( pvRed >= 1.0 ? pvRed + 0.5: 0); + Reductions[0][1][d][mc] = int8_t(nonPVRed >= 1.0 ? nonPVRed + 0.5: 0); - Reductions[1][0][hd][mc] = Reductions[1][1][hd][mc]; - Reductions[0][0][hd][mc] = Reductions[0][1][hd][mc]; + Reductions[1][0][d][mc] = Reductions[1][1][d][mc]; + Reductions[0][0][d][mc] = Reductions[0][1][d][mc]; - if (Reductions[0][0][hd][mc] >= 2) - Reductions[0][0][hd][mc] += 1; - } + // Increase reduction when eval is not improving + if (Reductions[0][0][d][mc] >= 2) + Reductions[0][0][d][mc] += 1; + } // Init futility move count array - for (d = 0; d < 32; ++d) + for (int d = 0; d < 32; ++d) { FutilityMoveCounts[0][d] = int(2.4 + 0.773 * pow(d + 0.00, 1.8)); FutilityMoveCounts[1][d] = int(2.9 + 1.045 * pow(d + 0.49, 1.8)); @@ -322,18 +320,21 @@ namespace { // re-search, otherwise exit the loop. if (bestValue <= alpha) { + beta = (alpha + beta) / 2; alpha = std::max(bestValue - delta, -VALUE_INFINITE); Signals.failedLowAtRoot = true; Signals.stopOnPonderhit = false; } else if (bestValue >= beta) + { + alpha = (alpha + beta) / 2; beta = std::min(bestValue + delta, VALUE_INFINITE); - + } else break; - delta += 3 * delta / 8; + delta += delta / 2; assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE); } @@ -406,7 +407,7 @@ namespace { Move ttMove, move, excludedMove, bestMove; Depth ext, newDepth, predictedDepth; Value bestValue, value, ttValue, eval, nullValue, futilityValue; - bool inCheck, givesCheck, pvMove, singularExtensionNode, improving; + bool inCheck, givesCheck, singularExtensionNode, improving; bool captureOrPromotion, dangerous, doFullDepthSearch; int moveCount, quietCount; @@ -747,7 +748,6 @@ moves_loop: // When in check and at SpNode search starts from here && !captureOrPromotion && !inCheck && !dangerous - /* && move != ttMove Already implicit in the next condition */ && bestValue > VALUE_MATED_IN_MAX_PLY) { // Move count based pruning @@ -802,7 +802,6 @@ moves_loop: // When in check and at SpNode search starts from here continue; } - pvMove = PvNode && moveCount == 1; ss->currentMove = move; if (!SpNode && !captureOrPromotion && quietCount < 64) quietsSearched[quietCount++] = move; @@ -813,9 +812,8 @@ moves_loop: // When in check and at SpNode search starts from here // Step 15. Reduced depth search (LMR). If the move fails high it will be // re-searched at full depth. if ( depth >= 3 * ONE_PLY - && !pvMove + && moveCount > 1 && !captureOrPromotion - && move != ttMove && move != ss->killers[0] && move != ss->killers[1]) { @@ -852,7 +850,7 @@ moves_loop: // When in check and at SpNode search starts from here ss->reduction = DEPTH_ZERO; } else - doFullDepthSearch = !pvMove; + doFullDepthSearch = !PvNode || moveCount > 1; // Step 16. Full depth search, when LMR is skipped or fails high if (doFullDepthSearch) @@ -869,7 +867,7 @@ moves_loop: // When in check and at SpNode search starts from here // For PV nodes only, do a full PV search on the first move or after a fail // high (in the latter case search only if value < beta), otherwise let the // parent node fail low with value <= alpha and to try another move. - if (PvNode && (pvMove || (value > alpha && (RootNode || value < beta)))) + if (PvNode && (moveCount == 1 || (value > alpha && (RootNode || value < beta)))) value = newDepth < ONE_PLY ? givesCheck ? -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO) : -qsearch(pos, ss+1, -beta, -alpha, DEPTH_ZERO) @@ -898,7 +896,7 @@ moves_loop: // When in check and at SpNode search starts from here RootMove& rm = *std::find(RootMoves.begin(), RootMoves.end(), move); // PV move or new best move ? - if (pvMove || value > alpha) + if (moveCount == 1 || value > alpha) { rm.score = value; rm.extract_pv_from_tt(pos); @@ -906,7 +904,7 @@ moves_loop: // When in check and at SpNode search starts from here // We record how often the best move has been changed in each // iteration. This information is used for time management: When // the best move changes frequently, we allocate some more time. - if (!pvMove) + if (moveCount > 1) ++BestMoveChanges; } else @@ -1111,7 +1109,6 @@ moves_loop: // When in check and at SpNode search starts from here if ( !PvNode && !InCheck && !givesCheck - && move != ttMove && futilityBase > -VALUE_KNOWN_WIN && !pos.advanced_pawn_push(move)) { @@ -1141,7 +1138,6 @@ moves_loop: // When in check and at SpNode search starts from here // Don't search moves with negative SEE values if ( !PvNode && (!InCheck || evasionPrunable) - && move != ttMove && type_of(move) != PROMOTION && pos.see_sign(move) < VALUE_ZERO) continue; @@ -1566,7 +1562,7 @@ void check_time() { { Threads.mutex.lock(); - int nodes = RootPos.nodes_searched(); + int64_t nodes = RootPos.nodes_searched(); // Loop across all split points and sum accumulated SplitPoint nodes plus // all the currently active positions nodes.