X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=6bd84226d3bde3aa954fe3363a166742a3cc41d3;hp=11dcdb34f13840a1b8ff43a7b08df4273fe972f9;hb=45e254a0a0d4cbc574e5a65bd4584036b01091b6;hpb=750dfa0521472e86c67f870fe7ca413d670cafe2 diff --git a/src/search.cpp b/src/search.cpp index 11dcdb34..6bd84226 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -154,6 +154,32 @@ 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); + // 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. + template + uint64_t perft(Position& pos, Depth depth) { + + StateInfo st; + uint64_t cnt, nodes = 0; + const bool leaf = (depth == 2 * ONE_PLY); + + for (const auto& m : MoveList(pos)) + { + if (Root && depth <= ONE_PLY) + cnt = 1, nodes++; + else + { + pos.do_move(m, st); + cnt = leaf ? MoveList(pos).size() : perft(pos, depth - ONE_PLY); + nodes += cnt; + pos.undo_move(m); + } + if (Root) + sync_cout << UCI::move(m, pos.is_chess960()) << ": " << cnt << sync_endl; + } + return nodes; + } + } // namespace @@ -209,40 +235,18 @@ void Search::clear() { } -/// Search::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. -template -uint64_t Search::perft(Position& pos, Depth depth) { - - StateInfo st; - uint64_t cnt, nodes = 0; - const bool leaf = (depth == 2 * ONE_PLY); - - for (const auto& m : MoveList(pos)) - { - if (Root && depth <= ONE_PLY) - cnt = 1, nodes++; - else - { - pos.do_move(m, st); - cnt = leaf ? MoveList(pos).size() : perft(pos, depth - ONE_PLY); - nodes += cnt; - pos.undo_move(m); - } - if (Root) - sync_cout << UCI::move(m, pos.is_chess960()) << ": " << cnt << sync_endl; - } - return nodes; -} - -template uint64_t Search::perft(Position&, Depth); - - /// MainThread::search() is called by the main thread when the program receives /// the UCI 'go' command. It searches from the root position and outputs the "bestmove". void MainThread::search() { + if (Limits.perft) + { + nodes = perft(rootPos, Limits.perft * ONE_PLY); + sync_cout << "\nNodes searched: " << nodes << "\n" << sync_endl; + return; + } + Color us = rootPos.side_to_move(); Time.init(Limits, us, rootPos.game_ply()); TT.new_search(); @@ -253,7 +257,7 @@ void MainThread::search() { if (rootMoves.empty()) { - rootMoves.push_back(RootMove(MOVE_NONE)); + rootMoves.emplace_back(MOVE_NONE); sync_cout << "info depth 0 score " << UCI::value(rootPos.checkers() ? -VALUE_MATE : VALUE_DRAW) << sync_endl; @@ -277,13 +281,13 @@ void MainThread::search() { // the UCI protocol states that we shouldn't print the best move before the // GUI sends a "stop" or "ponderhit" command. We therefore simply wait here // until the GUI sends one of those commands (which also raises Threads.stop). - if (!Threads.stop && (Limits.ponder || Limits.infinite)) - { - Threads.stopOnPonderhit = true; - wait(Threads.stop); - } + Threads.stopOnPonderhit = true; + + while (!Threads.stop && (Threads.ponder || Limits.infinite)) + {} // Busy wait for a stop or a ponder reset - // Stop the threads if not already stopped + // Stop the threads if not already stopped (also raise the stop if + // "ponderhit" just reset Threads.ponder). Threads.stop = true; // Wait until all threads have finished @@ -341,7 +345,6 @@ void Thread::search() { bestValue = delta = alpha = -VALUE_INFINITE; beta = VALUE_INFINITE; - completedDepth = DEPTH_ZERO; if (mainThread) { @@ -499,7 +502,7 @@ void Thread::search() { { // If we are allowed to ponder do not stop the search now but // keep pondering until the GUI sends "ponderhit" or "stop". - if (Limits.ponder) + if (Threads.ponder) Threads.stopOnPonderhit = true; else Threads.stop = true; @@ -1489,10 +1492,10 @@ moves_loop: // When in check search starts from here } // An engine may not stop pondering until told so by the GUI - if (Limits.ponder) + if (Threads.ponder) return; - if ( (Limits.use_time_management() && elapsed > Time.maximum() - 10) + if ( (Limits.use_time_management() && elapsed > Time.maximum()) || (Limits.movetime && elapsed >= Limits.movetime) || (Limits.nodes && Threads.nodes_searched() >= (uint64_t)Limits.nodes)) Threads.stop = true;