X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=5ccc72c890cb263dd40dadd102bf0f8e248493ae;hp=21aa4f92069dbcbbf7997b73364b641444fc9ed2;hb=d20e0cf048c7e901f422f61259cd2fbfdba0b209;hpb=e30720b0bf10a91c04fcd5d881a728a3d97e850f diff --git a/src/search.cpp b/src/search.cpp index 21aa4f92..5ccc72c8 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -23,6 +23,7 @@ //// #include +#include #include #include #include @@ -128,18 +129,17 @@ namespace { }; - /// Constants and variables + /// Constants and variables initialized from UCI options // Minimum number of full depth (i.e. non-reduced) moves at PV and non-PV - // nodes: - int LMRPVMoves = 15; - int LMRNonPVMoves = 4; + // nodes + int LMRPVMoves, LMRNonPVMoves; - // Depth limit for use of dynamic threat detection: - Depth ThreatDepth = 5*OnePly; + // Depth limit for use of dynamic threat detection + Depth ThreatDepth; - // Depth limit for selective search: - Depth SelectiveDepth = 7*OnePly; + // Depth limit for selective search + Depth SelectiveDepth; // Use internal iterative deepening? const bool UseIIDAtPVNodes = true; @@ -176,33 +176,35 @@ namespace { const bool PruneBlockingMoves = false; // Use futility pruning? - bool UseQSearchFutilityPruning = true; - bool UseFutilityPruning = true; + bool UseQSearchFutilityPruning, UseFutilityPruning; // Margins for futility pruning in the quiescence search, and at frontier // and near frontier nodes - Value FutilityMarginQS = Value(0x80); - Value FutilityMargins[6] = { Value(0x100), Value(0x200), Value(0x250), - Value(0x2A0), Value(0x340), Value(0x3A0) }; + const Value FutilityMarginQS = Value(0x80); + + //remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply + const Value FutilityMargins[12] = { Value(0x100), Value(0x120), Value(0x200), Value(0x220), Value(0x250), Value(0x270), + // 4 ply 4.5 ply 5 ply 5.5 ply 6 ply 6.5 ply + Value(0x2A0), Value(0x2C0), Value(0x340), Value(0x360), Value(0x3A0), Value(0x3C0)}; // Razoring - const bool RazorAtDepthOne = false; - Depth RazorDepth = 4*OnePly; - Value RazorMargin = Value(0x300); + const Depth RazorDepth = 4*OnePly; + + //remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply + const Value RazorMargins[6] = { Value(0x180), Value(0x300), Value(0x300), Value(0x3C0), Value(0x3C0), Value(0x3C0) }; + + //remaining depth: 1 ply 1.5 ply 2 ply 2.5 ply 3 ply 3.5 ply + const Value RazorApprMargins[6] = { Value(0x520), Value(0x300), Value(0x300), Value(0x300), Value(0x300), Value(0x300) }; // Last seconds noise filtering (LSN) - bool UseLSNFiltering = false; + bool UseLSNFiltering; bool looseOnTime = false; - int LSNTime = 4 * 1000; // In milliseconds - Value LSNValue = Value(0x200); + int LSNTime; // In milliseconds + Value LSNValue; - // Extensions. Array index 0 is used at non-PV nodes, index 1 at PV nodes. - Depth CheckExtension[2] = {OnePly, OnePly}; - Depth SingleReplyExtension[2] = {OnePly / 2, OnePly / 2}; - Depth PawnPushTo7thExtension[2] = {OnePly / 2, OnePly / 2}; - Depth PassedPawnExtension[2] = {Depth(0), Depth(0)}; - Depth PawnEndgameExtension[2] = {OnePly, OnePly}; - Depth MateThreatExtension[2] = {Depth(0), Depth(0)}; + // Extensions. Array index 0 is used at non-PV nodes, index 1 at PV nodes. + Depth CheckExtension[2], SingleReplyExtension[2], PawnPushTo7thExtension[2]; + Depth PassedPawnExtension[2], PawnEndgameExtension[2], MateThreatExtension[2]; // Search depth at iteration 1 const Depth InitialDepth = OnePly /*+ OnePly/2*/; @@ -220,7 +222,7 @@ namespace { int BestMoveChangesByIteration[PLY_MAX_PLUS_2]; // MultiPV mode - int MultiPV = 1; + int MultiPV; // Time managment variables int SearchStartTime; @@ -240,15 +242,15 @@ namespace { int ExactMaxTime; // Show current line? - bool ShowCurrentLine = false; + bool ShowCurrentLine; // Log file - bool UseLogFile = false; + bool UseLogFile; std::ofstream LogFile; // MP related variables - Depth MinimumSplitDepth = 4*OnePly; - int MaxThreadsPerSplitPoint = 4; + Depth MinimumSplitDepth; + int MaxThreadsPerSplitPoint; Thread Threads[THREAD_MAX]; Lock MPLock; bool AllThreadsShouldExit = false; @@ -442,13 +444,13 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move, UseQSearchFutilityPruning = get_option_value_bool("Futility Pruning (Quiescence Search)"); UseFutilityPruning = get_option_value_bool("Futility Pruning (Main Search)"); - FutilityMarginQS = value_from_centipawns(get_option_value_int("Futility Margin (Quiescence Search)")); - int fmScale = get_option_value_int("Futility Margin Scale Factor (Main Search)"); - for (int i = 0; i < 6; i++) - FutilityMargins[i] = (FutilityMargins[i] * fmScale) / 100; + //FutilityMarginQS = value_from_centipawns(get_option_value_int("Futility Margin (Quiescence Search)")); + //int fmScale = get_option_value_int("Futility Margin Scale Factor (Main Search)"); + //for (int i = 0; i < 6; i++) + // FutilityMargins[i] = (FutilityMargins[i] * fmScale) / 100; - RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly; - RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin")); + //RazorDepth = (get_option_value_int("Maximum Razoring Depth") + 1) * OnePly; + //RazorMargin = value_from_centipawns(get_option_value_int("Razoring Margin")); UseLSNFiltering = get_option_value_bool("LSN filtering"); LSNTime = get_option_value_int("LSN Time Margin (sec)") * 1000; @@ -1315,17 +1317,14 @@ namespace { } // Null move search not allowed, try razoring else if ( !value_is_mate(beta) - && approximateEval < beta - RazorMargin && depth < RazorDepth - && (RazorAtDepthOne || depth > OnePly) + && approximateEval < beta - RazorApprMargins[int(depth) - 2] && ttMove == MOVE_NONE && !pos.has_pawn_on_7th(pos.side_to_move())) { Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID); - if ( (v < beta - RazorMargin - RazorMargin / 4) - || (depth <= 2*OnePly && v < beta - RazorMargin) - || (depth <= OnePly && v < beta - RazorMargin / 2)) - return v; + if (v < beta - RazorMargins[int(depth) - 2]) + return v; } // Go with internal iterative deepening if we don't have a TT move @@ -1384,8 +1383,7 @@ namespace { { if (futilityValue == VALUE_NONE) futilityValue = evaluate(pos, ei, threadID) - + FutilityMargins[int(depth)/2 - 1] - + 32 * (depth & 1); + + FutilityMargins[int(depth) - 2]; if (futilityValue < beta) { @@ -1516,6 +1514,7 @@ namespace { return value_from_tt(tte->value(), ply); } } + Move ttMove = (tte ? tte->move() : MOVE_NONE); // Evaluate the position statically EvalInfo ei; @@ -1559,7 +1558,7 @@ namespace { // Initialize a MovePicker object for the current position, and prepare // to search the moves. Because the depth is <= 0 here, only captures, // queen promotions and checks (only if depth == 0) will be generated. - MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth); + MovePicker mp = MovePicker(pos, pvNode, ttMove, EmptySearchStack, depth); Move move; int moveCount = 0; Bitboard dcCandidates = mp.discovered_check_candidates(); @@ -1636,22 +1635,20 @@ namespace { assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); // Update transposition table + Move m = ss[ply].pv[ply]; if (!pvNode) { Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1)); if (bestValue < beta) TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_UPPER); else - TT.store(pos, value_to_tt(bestValue, ply), d, MOVE_NONE, VALUE_TYPE_LOWER); + TT.store(pos, value_to_tt(bestValue, ply), d, m, VALUE_TYPE_LOWER); } // Update killers only for good check moves - Move m = ss[ply].currentMove; if (alpha >= beta && ok_to_history(pos, m)) // Only non capture moves are considered - { - // Wrong to update history when depth is <= 0 update_killers(m, ss[ply]); - } + return bestValue; }