X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=f52351920a369831119c2fecc65d483e626dfd9a;hp=549f19e211caecc575a10eb6fda327a6986e1d06;hb=1c087dd806b65c5d6668706f0c8fddf14f6fcd41;hpb=ca4e78db8db1288eb5c8deecb9bdf402f53fdc98 diff --git a/src/search.cpp b/src/search.cpp index 549f19e2..f5235192 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -121,6 +121,9 @@ namespace { // Depth limit for selective search: Depth SelectiveDepth = 7*OnePly; + // Use dynamic LMR? + const bool UseDynamicLMR = false; + // Use internal iterative deepening? const bool UseIIDAtPVNodes = true; const bool UseIIDAtNonPVNodes = false; @@ -193,7 +196,6 @@ namespace { // Iteration counters int Iteration; - bool LastIterations; BetaCounterType BetaCounter; // Scores and number of times the best move changed for each iteration: @@ -207,7 +209,7 @@ namespace { int SearchStartTime; int MaxNodes, MaxDepth; int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime; - Move BestRootMove, PonderMove, EasyMove; + Move EasyMove; int RootMoveNumber; bool InfiniteSearch; bool PonderSearch; @@ -369,8 +371,6 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move, // Initialize global search variables Idle = false; SearchStartTime = get_system_time(); - BestRootMove = MOVE_NONE; - PonderMove = MOVE_NONE; EasyMove = MOVE_NONE; for (int i = 0; i < THREAD_MAX; i++) { @@ -661,7 +661,6 @@ namespace { ValueByIteration[0] = Value(0); ValueByIteration[1] = rml.get_move_score(0); Iteration = 1; - LastIterations = false; EasyMove = rml.scan_for_easy_move(); @@ -716,9 +715,6 @@ namespace { ExtraSearchTime = BestMoveChangesByIteration[Iteration] * (MaxSearchTime / 2) + BestMoveChangesByIteration[Iteration-1] * (MaxSearchTime / 3); - // Try to guess if the current iteration is the last one or the last two - LastIterations = (current_search_time() > ((MaxSearchTime + ExtraSearchTime)*58) / 128); - // Stop search if most of MaxSearchTime is consumed at the end of the // iteration. We probably don't have enough time to search the first // move at the next iteration anyway. @@ -755,6 +751,11 @@ namespace { << " hashfull " << TT.full() << std::endl; // Print the best move and the ponder move to the standard output + if (ss[0].pv[0] == MOVE_NONE) + { + ss[0].pv[0] = rml.get_move(0); + ss[0].pv[1] = MOVE_NONE; + } std::cout << "bestmove " << ss[0].pv[0]; if (ss[0].pv[1] != MOVE_NONE) std::cout << " ponder " << ss[0].pv[1]; @@ -1247,8 +1248,8 @@ namespace { { Value v = qsearch(pos, ss, beta-1, beta, Depth(0), ply, threadID); if ( (v < beta - RazorMargin - RazorMargin / 4) - || (depth < 3*OnePly && v < beta - RazorMargin) - || (depth < 2*OnePly && v < beta - RazorMargin / 2)) + || (depth <= 2*OnePly && v < beta - RazorMargin) + || (depth <= OnePly && v < beta - RazorMargin / 2)) return v; } @@ -1334,8 +1335,13 @@ namespace { && !move_is_castle(move) && !move_is_killer(move, ss[ply])) { - ss[ply].reduction = OnePly; - value = -search(pos, ss, -(beta-1), newDepth-OnePly, ply+1, true, threadID); + // LMR dynamic reduction + Depth R = UseDynamicLMR + && moveCount >= 2 * LMRNonPVMoves + && depth > 7*OnePly ? 2*OnePly : OnePly; + + ss[ply].reduction = R; + value = -search(pos, ss, -(beta-1), newDepth-R, ply+1, true, threadID); } else value = beta; // Just to trigger next condition @@ -1396,6 +1402,9 @@ namespace { } TT.store(pos, value_to_tt(bestValue, ply), depth, m, VALUE_TYPE_LOWER); } + + assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); + return bestValue; } @@ -1424,10 +1433,14 @@ namespace { if (pos.is_draw()) return VALUE_DRAW; - // Transposition table lookup - const TTEntry* tte = TT.retrieve(pos); - if (tte && ok_to_use_TT(tte, depth, beta, ply)) - return value_from_tt(tte->value(), ply); + // Transposition table lookup, only when not in PV + bool pvNode = (beta - alpha != 1); + if (!pvNode) + { + const TTEntry* tte = TT.retrieve(pos); + if (tte && ok_to_use_TT(tte, depth, beta, ply)) + return value_from_tt(tte->value(), ply); + } // Evaluate the position statically EvalInfo ei; @@ -1442,7 +1455,11 @@ namespace { Value bestValue = staticValue; if (bestValue >= beta) + { + // Update transposition table before to leave + TT.store(pos, value_to_tt(bestValue, ply), depth, MOVE_NONE, VALUE_TYPE_EXACT); return bestValue; + } if (bestValue > alpha) alpha = bestValue; @@ -1450,7 +1467,6 @@ 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. - bool pvNode = (beta - alpha != 1); MovePicker mp = MovePicker(pos, pvNode, MOVE_NONE, EmptySearchStack, depth, isCheck ? NULL : &ei); Move move; int moveCount = 0; @@ -1527,9 +1543,6 @@ namespace { assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); - // Update transposition table - TT.store(pos, value_to_tt(bestValue, ply), depth, MOVE_NONE, VALUE_TYPE_EXACT); - // 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 @@ -2405,7 +2418,7 @@ namespace { || ( !FailHigh && !fail_high_ply_1() && !Problem && t > 6*(MaxSearchTime + ExtraSearchTime)); - if ( (Iteration >= 2 && (!InfiniteSearch && overTime)) + if ( (Iteration >= 3 && (!InfiniteSearch && overTime)) || (ExactMaxTime && t >= ExactMaxTime) || (Iteration >= 3 && MaxNodes && nodes_searched() >= MaxNodes)) AbortSearch = true; @@ -2419,7 +2432,7 @@ namespace { void ponderhit() { int t = current_search_time(); PonderSearch = false; - if(Iteration >= 2 && + if(Iteration >= 3 && (!InfiniteSearch && (StopOnPonderhit || t > AbsoluteMaxSearchTime || (RootMoveNumber == 1 &&