X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=77acd89e39b12310d5333708de19c5c85c7a883f;hp=6615a1efacbc2bc1454ad0732568ab3c2716a8c1;hb=5b8ca1eee77b736c35b418b1cb11da9fc66f83e0;hpb=ffa75215cc06d105bc2b43ddb8ed5d4deccd8988 diff --git a/src/search.cpp b/src/search.cpp index 6615a1ef..77acd89e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -30,7 +30,6 @@ #include "evaluate.h" #include "history.h" #include "misc.h" -#include "move.h" #include "movegen.h" #include "movepick.h" #include "search.h" @@ -39,20 +38,19 @@ #include "tt.h" #include "ucioption.h" -using std::cout; -using std::endl; -using std::string; -using Search::Signals; -using Search::Limits; - namespace Search { volatile SignalsType Signals; LimitsType Limits; std::vector RootMoves; - Position* RootPosition; + Position RootPosition; } +using std::cout; +using std::endl; +using std::string; +using namespace Search; + namespace { // Set to true to force running with one thread. Used for debugging @@ -187,10 +185,10 @@ namespace { Move id_loop(Position& pos, Move rootMoves[], Move* ponderMove); template - Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth); + Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth); template - Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth); + Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth); bool check_is_dangerous(Position &pos, Move move, Value futilityBase, Value beta, Value *bValue); bool connected_moves(const Position& pos, Move m1, Move m2); @@ -202,7 +200,7 @@ namespace { void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount); void do_skill_level(Move* best, Move* ponder); - int elapsed_search_time(int set = 0); + int elapsed_time(bool reset = false); string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE); string speed_to_uci(int64_t nodes); string pv_to_uci(const Move pv[], int pvNum, bool chess960); @@ -214,14 +212,14 @@ namespace { // we simply create and use a standard MovePicker object. template struct MovePickerExt : public MovePicker { - MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss, Value b) + MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, Stack* ss, Value b) : MovePicker(p, ttm, d, h, ss, b) {} }; // In case of a SpNode we use split point's shared MovePicker object as moves source template<> struct MovePickerExt : public MovePicker { - MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, SearchStack* ss, Value b) + MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, Stack* ss, Value b) : MovePicker(p, ttm, d, h, ss, b), mp(ss->sp->mp) {} Move get_next_move() { return mp->get_next_move(); } @@ -353,19 +351,18 @@ int64_t Search::perft(Position& pos, Depth depth) { } -/// think() is the external interface to Stockfish's search, and is called when -/// the program receives the UCI 'go' command. It initializes various global -/// variables, and calls id_loop(). It returns false when a "quit" command is -/// received during the search. +/// think() is the external interface to Stockfish's search, and is called by the +/// main thread when the program receives the UCI 'go' command. It searches from +/// RootPosition and at the end prints the "bestmove" to output. void Search::think() { static Book book; // Defined static to initialize the PRNG only once - Position& pos = *RootPosition; + Position& pos = RootPosition; - // Save "search start" time and reset elapsed time to zero - elapsed_search_time(get_system_time()); + // Reset elapsed search time + elapsed_time(true); // Set output stream mode: normal or chess960. Castling notation is different cout << set960(pos.is_chess960()); @@ -450,7 +447,7 @@ void Search::think() { // Write current search final statistics to log file if (Options["Use Search Log"].value()) { - int e = elapsed_search_time(); + int e = elapsed_time(); Log log(Options["Search Log Filename"].value()); log << "Nodes: " << pos.nodes_searched() @@ -489,7 +486,7 @@ namespace { Move id_loop(Position& pos, Move rootMoves[], Move* ponderMove) { - SearchStack ss[PLY_MAX_PLUS_2]; + Stack ss[PLY_MAX_PLUS_2]; Value bestValues[PLY_MAX_PLUS_2]; int bestMoveChanges[PLY_MAX_PLUS_2]; int depth, aspirationDelta; @@ -498,7 +495,7 @@ namespace { bool bestMoveNeverChanged = true; // Initialize stuff before a new search - memset(ss, 0, 4 * sizeof(SearchStack)); + memset(ss, 0, 4 * sizeof(Stack)); TT.new_search(); H.clear(); *ponderMove = bestMove = skillBest = skillPonder = MOVE_NONE; @@ -585,7 +582,7 @@ namespace { // if we have a fail high/low and we are deep in the search. UCI // protocol requires to send all the PV lines also if are still // to be searched and so refer to the previous search's score. - if ((bestValue > alpha && bestValue < beta) || elapsed_search_time() > 2000) + if ((bestValue > alpha && bestValue < beta) || elapsed_time() > 2000) for (int i = 0; i < std::min(UCIMultiPV, (int)Rml.size()); i++) { bool updated = (i <= MultiPVIdx); @@ -638,7 +635,7 @@ namespace { if (Options["Use Search Log"].value()) { Log log(Options["Search Log Filename"].value()); - log << pretty_pv(pos, depth, bestValue, elapsed_search_time(), &Rml[0].pv[0]) << endl; + log << pretty_pv(pos, depth, bestValue, elapsed_time(), &Rml[0].pv[0]) << endl; } // Filter out startup noise when monitoring best move stability @@ -656,14 +653,14 @@ namespace { // Stop search if most of available time is already consumed. We probably don't // have enough time to search the first move at the next iteration anyway. - if (elapsed_search_time() > (TimeMgr.available_time() * 62) / 100) + if (elapsed_time() > (TimeMgr.available_time() * 62) / 100) stop = true; // Stop search early if one move seems to be much better than others if ( depth >= 10 && !stop && ( bestMoveNeverChanged - || elapsed_search_time() > (TimeMgr.available_time() * 40) / 100)) + || elapsed_time() > (TimeMgr.available_time() * 40) / 100)) { Value rBeta = bestValue - EasyMoveMargin; (ss+1)->excludedMove = bestMove; @@ -680,7 +677,7 @@ namespace { { // If we are allowed to ponder do not stop the search now but // keep pondering until GUI sends "ponderhit" or "stop". - if (Limits.ponder) // FIXME racing + if (Limits.ponder) Signals.stopOnPonderhit = true; else Signals.stop = true; @@ -710,7 +707,7 @@ namespace { // here: This is taken care of after we return from the split point. template - Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) { + Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) { const bool PvNode = (NT == PV || NT == Root || NT == SplitPointPV || NT == SplitPointRoot); const bool SpNode = (NT == SplitPointPV || NT == SplitPointNonPV || NT == SplitPointRoot); @@ -1028,7 +1025,7 @@ split_point_start: // At split points actual search starts from here nodes = pos.nodes_searched(); // For long searches send current move info to GUI - if (pos.thread() == 0 && elapsed_search_time() > 2000) + if (pos.thread() == 0 && elapsed_time() > 2000) cout << "info" << depth_to_uci(depth) << " currmove " << move << " currmovenumber " << moveCount + MultiPVIdx << endl; @@ -1299,7 +1296,7 @@ split_point_start: // At split points actual search starts from here // less than ONE_PLY). template - Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth) { + Value qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth) { const bool PvNode = (NT == PV); @@ -1734,12 +1731,12 @@ split_point_start: // At split points actual search starts from here // current_search_time() returns the number of milliseconds which have passed // since the beginning of the current search. - int elapsed_search_time(int set) { + int elapsed_time(bool reset) { static int searchStartTime; - if (set) - searchStartTime = set; + if (reset) + searchStartTime = get_system_time(); return get_system_time() - searchStartTime; } @@ -1773,7 +1770,7 @@ split_point_start: // At split points actual search starts from here string speed_to_uci(int64_t nodes) { std::stringstream s; - int t = elapsed_search_time(); + int t = elapsed_time(); s << " nodes " << nodes << " nps " << (t > 0 ? int(nodes * 1000 / t) : 0) @@ -2103,11 +2100,11 @@ void Thread::idle_loop(SplitPoint* sp) { assert(!do_terminate); // Copy split point position and search stack and call search() - SearchStack ss[PLY_MAX_PLUS_2]; + Stack ss[PLY_MAX_PLUS_2]; SplitPoint* tsp = splitPoint; Position pos(*tsp->pos, threadID); - memcpy(ss, tsp->ss - 1, 4 * sizeof(SearchStack)); + memcpy(ss, tsp->ss - 1, 4 * sizeof(Stack)); (ss+1)->sp = tsp; if (tsp->nodeType == Root) @@ -2150,7 +2147,7 @@ void Thread::idle_loop(SplitPoint* sp) { void do_timer_event() { static int lastInfoTime; - int e = elapsed_search_time(); + int e = elapsed_time(); // Print debug information every one second if (!lastInfoTime || get_system_time() - lastInfoTime >= 1000)