Use do_uci_async_cmd() instead of process input commands
directly and clarify that what we are waiting for is
something that is able to raise StopRequest flag.
Also fix some stale comments in do_uci_async_cmd(). Here
we need to reset Limits.ponder only upon receiving "ponderhit".
In the case of "quit" or "stop" resetting Limits.ponder has no
effect because the search is going to be stopped anyway.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) {
bool think(Position& pos, const SearchLimits& limits, Move searchMoves[]) {
- static Book book; // Define static to initialize the PRNG only once
+ static Book book; // Defined static to initialize the PRNG only once
// Initialize global search-related variables
StopOnPonderhit = StopRequest = QuitRequest = AspirationFailLow = false;
// Initialize global search-related variables
StopOnPonderhit = StopRequest = QuitRequest = AspirationFailLow = false;
Limits = limits;
TimeMgr.init(Limits, pos.startpos_ply_counter());
Limits = limits;
TimeMgr.init(Limits, pos.startpos_ply_counter());
- // Set output steram in normal or chess960 mode
+ // Set output stream in normal or chess960 mode
cout << set960(pos.is_chess960());
// Look for a book move
cout << set960(pos.is_chess960());
// Look for a book move
- // Set best timer interval to avoid lagging under time pressure
+ // Set best timer interval to avoid lagging under time pressure. Timer is
+ // used to check for remaining available thinking time.
if (TimeMgr.available_time())
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 8, 20)));
else
if (TimeMgr.available_time())
Threads.set_timer(std::min(100, std::max(TimeMgr.available_time() / 8, 20)));
else
- // Write to log file and keep it open to be accessed during the search
+ // Start async mode to catch UCI commands sent to us while searching,
+ // like "quit", "stop", etc.
+ Threads.start_listener();
+
+ // Write current search header to log file
if (Options["Use Search Log"].value<bool>())
{
Log log(Options["Search Log Filename"].value<string>());
if (Options["Use Search Log"].value<bool>())
{
Log log(Options["Search Log Filename"].value<string>());
- // Start async mode to catch UCI commands sent to us while searching,
- // like "quit", "stop", etc.
- Threads.start_listener();
-
// We're ready to start thinking. Call the iterative deepening loop function
Move ponderMove = MOVE_NONE;
Move bestMove = id_loop(pos, searchMoves, &ponderMove);
// We're ready to start thinking. Call the iterative deepening loop function
Move ponderMove = MOVE_NONE;
Move bestMove = id_loop(pos, searchMoves, &ponderMove);
- Threads.set_timer(0);
-
- // Write final search statistics and close log file
+ // Write current search final statistics to log file
if (Options["Use Search Log"].value<bool>())
{
int e = elapsed_search_time();
if (Options["Use Search Log"].value<bool>())
{
int e = elapsed_search_time();
// From now on any UCI command will be read in-sync with Threads.getline()
Threads.stop_listener();
// From now on any UCI command will be read in-sync with Threads.getline()
Threads.stop_listener();
+ // Stop timer, no need to check for available time any more
+ Threads.set_timer(0);
+
// If we are pondering or in infinite search, we shouldn't print the
// best move before we are told to do so.
// If we are pondering or in infinite search, we shouldn't print the
// best move before we are told to do so.
- if (!StopRequest && (Limits.ponder || Limits.infinite))
+ if (Limits.ponder || Limits.infinite)
wait_for_stop_or_ponderhit();
// Could be MOVE_NONE when searching on a stalemate position
wait_for_stop_or_ponderhit();
// Could be MOVE_NONE when searching on a stalemate position
// while the program is pondering. The point is to work around a wrinkle in
// the UCI protocol: When pondering, the engine is not allowed to give a
// "bestmove" before the GUI sends it a "stop" or "ponderhit" command.
// while the program is pondering. The point is to work around a wrinkle in
// the UCI protocol: When pondering, the engine is not allowed to give a
// "bestmove" before the GUI sends it a "stop" or "ponderhit" command.
- // We simply wait here until one of these commands is sent, and return,
- // after which the bestmove and pondermove will be printed.
+ // We simply wait here until one of these commands (that raise StopRequest) is
+ // sent, and return, after which the bestmove and pondermove will be printed.
void wait_for_stop_or_ponderhit() {
string cmd;
void wait_for_stop_or_ponderhit() {
string cmd;
+ StopOnPonderhit = true;
- // Wait for a command from stdin
- while (cmd != "ponderhit" && cmd != "stop" && cmd != "quit")
+ while (!StopRequest)
+ {
-
- if (cmd == "quit")
- QuitRequest = true;
+ do_uci_async_cmd(cmd);
+ }
void do_uci_async_cmd(const std::string& cmd) {
if (cmd == "quit")
void do_uci_async_cmd(const std::string& cmd) {
if (cmd == "quit")
- {
- // Quit the program as soon as possible
- Limits.ponder = false;
QuitRequest = StopRequest = true;
QuitRequest = StopRequest = true;
- {
- // Stop calculating as soon as possible, but still send the "bestmove"
- // and possibly the "ponder" token when finishing the search.
- Limits.ponder = false;
else if (cmd == "ponderhit")
{
// The opponent has played the expected move. GUI sends "ponderhit" if
else if (cmd == "ponderhit")
{
// The opponent has played the expected move. GUI sends "ponderhit" if