X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=72b257cb30b4138a74aba2088e8a310f04747240;hp=f47507f7e39b6ad6ba7a7ffaf3ebe2f17e1cd6e0;hb=cb1324312d051269700b74cb59759a12530d0b7a;hpb=44a7db0f9ac02d2461aff39e25f1ac9107ffbfac diff --git a/src/search.cpp b/src/search.cpp index f47507f7..72b257cb 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -107,7 +107,6 @@ namespace { void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus); void update_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus); void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus); - bool pv_is_draw(Position& pos); // perft() is our utility to verify move generation. All the leaf nodes up // to the given depth are generated and counted, and the sum is returned. @@ -192,11 +191,6 @@ void MainThread::search() { Time.init(Limits, us, rootPos.game_ply()); TT.new_search(); - int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns - - Eval::Contempt = (us == WHITE ? make_score(contempt, contempt / 2) - : -make_score(contempt, contempt / 2)); - if (rootMoves.empty()) { rootMoves.emplace_back(MOVE_NONE); @@ -283,6 +277,7 @@ void Thread::search() { Depth lastBestMoveDepth = DEPTH_ZERO; MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr); double timeReduction = 1.0; + Color us = rootPos.side_to_move(); std::memset(ss-4, 0, 7 * sizeof(Stack)); for (int i = 4; i > 0; i--) @@ -297,7 +292,7 @@ void Thread::search() { mainThread->bestMoveChanges = 0; } - multiPV = Options["MultiPV"]; + size_t multiPV = Options["MultiPV"]; Skill skill(Options["Skill Level"]); // When playing with strength handicap enable MultiPV search that we will @@ -307,6 +302,10 @@ void Thread::search() { multiPV = std::min(multiPV, rootMoves.size()); + int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns + Eval::Contempt = (us == WHITE ? make_score(contempt, contempt / 2) + : -make_score(contempt, contempt / 2)); + // Iterative deepening loop until requested to stop or the target depth is reached while ( (rootDepth += ONE_PLY) < DEPTH_MAX && !Threads.stop @@ -341,6 +340,15 @@ void Thread::search() { delta = Value(18); alpha = std::max(rootMoves[PVIdx].previousScore - delta,-VALUE_INFINITE); beta = std::min(rootMoves[PVIdx].previousScore + delta, VALUE_INFINITE); + + // Adjust contempt based on current situation + contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns + contempt += bestValue > 500 ? 50: // Dynamic contempt + bestValue < -500 ? -50: + bestValue / 10; + + Eval::Contempt = (us == WHITE ? make_score(contempt, contempt / 2) + : -make_score(contempt, contempt / 2)); } // Start with a small aspiration window and, in the case of a fail @@ -435,24 +443,19 @@ void Thread::search() { bestValue - mainThread->previousScore }; int improvingFactor = std::max(229, std::min(715, 357 + 119 * F[0] - 6 * F[1])); - Color us = rootPos.side_to_move(); - bool thinkHard = bestValue == VALUE_DRAW - && Limits.time[us] - Time.elapsed() > Limits.time[~us] - && ::pv_is_draw(rootPos); - - double unstablePvFactor = 1 + mainThread->bestMoveChanges + thinkHard; + double unstablePvFactor = 1 + mainThread->bestMoveChanges; // if the bestMove is stable over several iterations, reduce time for this move, // the longer the move has been stable, the more. // Use part of the gained time from a previous stable move for the current move. timeReduction = 1; for (int i : {3, 4, 5}) - if (lastBestMoveDepth * i < completedDepth && !thinkHard) + if (lastBestMoveDepth * i < completedDepth ) timeReduction *= 1.3; unstablePvFactor *= std::pow(mainThread->previousTimeReduction, 0.51) / timeReduction; if ( rootMoves.size() == 1 - || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 628) + || Time.elapsed() > Time.optimum() * unstablePvFactor * improvingFactor / 605) { // If we are allowed to ponder do not stop the search now but // keep pondering until the GUI sends "ponderhit" or "stop". @@ -802,20 +805,12 @@ moves_loop: // When in check search starts from here if (move == excludedMove) continue; - if (rootNode) - { - // At root obey the "searchmoves" option and skip moves not listed in Root - // Move List. As a consequence any illegal move is also skipped. - if (!std::count(thisThread->rootMoves.begin() + thisThread->PVIdx, - thisThread->rootMoves.end(), move)) - continue; - - // In MultiPV mode we not only skip PV moves which have already been searched, - // but also any other move except we have reached the last PV line. - if ( thisThread->PVIdx + 1 < thisThread->multiPV - && move != ttMove) - continue; - } + // At root obey the "searchmoves" option and skip moves not listed in Root + // Move List. As a consequence any illegal move is also skipped. In MultiPV + // mode we also skip PV moves which have been already searched. + if (rootNode && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx, + thisThread->rootMoves.end(), move)) + continue; ss->moveCount = ++moveCount; @@ -1438,25 +1433,6 @@ moves_loop: // When in check search starts from here } } - - // Is the PV leading to a draw position? Assumes all pv moves are legal - bool pv_is_draw(Position& pos) { - - StateInfo st[MAX_PLY]; - auto& pv = pos.this_thread()->rootMoves[0].pv; - - for (size_t i = 0; i < pv.size(); ++i) - pos.do_move(pv[i], st[i]); - - bool isDraw = pos.is_draw(pv.size()); - - for (size_t i = pv.size(); i > 0; --i) - pos.undo_move(pv[i-1]); - - return isDraw; - } - - // When playing with strength handicap, choose best move among a set of RootMoves // using a statistical rule dependent on 'level'. Idea by Heinz van Saanen. @@ -1535,7 +1511,7 @@ string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) { int elapsed = Time.elapsed() + 1; const RootMoves& rootMoves = pos.this_thread()->rootMoves; size_t PVIdx = pos.this_thread()->PVIdx; - size_t multiPV = pos.this_thread()->multiPV; + size_t multiPV = std::min((size_t)Options["MultiPV"], rootMoves.size()); uint64_t nodesSearched = Threads.nodes_searched(); uint64_t tbHits = Threads.tb_hits() + (TB::RootInTB ? rootMoves.size() : 0);