1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-17 07:59:36 +00:00

Fix sending of best move during an infinite search

According to UCI standard once engine receives 'go infinite'
command it should search until the "stop" command and do not exit
the search without being told so, even if PLY_MAX has been reached.

Patch is quite invasive because it cleanups some hacks used
by fixed depth and fixed nodes modes, mainly during benchmarks.

Bug found by Pascal Georges.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2010-01-10 12:38:59 +01:00
parent b67146b100
commit 2af986bf31
2 changed files with 84 additions and 63 deletions

View file

@ -155,7 +155,7 @@ void benchmark(const string& commandLine) {
cerr << "\nBench position: " << cnt << '/' << positions.size() << endl << endl; cerr << "\nBench position: " << cnt << '/' << positions.size() << endl << endl;
if (limitType == "perft") if (limitType == "perft")
totalNodes += perft(pos, maxDepth * OnePly); totalNodes += perft(pos, maxDepth * OnePly);
else if (!think(pos, true, false, 0, dummy, dummy, 0, maxDepth, maxNodes, secsPerPos, moves)) else if (!think(pos, false, false, 0, dummy, dummy, 0, maxDepth, maxNodes, secsPerPos, moves))
break; break;
totalNodes += nodes_searched(); totalNodes += nodes_searched();
} }

View file

@ -227,14 +227,9 @@ namespace {
int MaxNodes, MaxDepth; int MaxNodes, MaxDepth;
int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime; int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime;
int RootMoveNumber; int RootMoveNumber;
bool InfiniteSearch; bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit;
bool PonderSearch; bool AbortSearch, Quit;
bool StopOnPonderhit; bool FailHigh, FailLow, Problem;
bool AbortSearch; // heavy SMP read access
bool Quit;
bool FailHigh;
bool FailLow;
bool Problem;
// Show current line? // Show current line?
bool ShowCurrentLine; bool ShowCurrentLine;
@ -368,8 +363,20 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
int time[], int increment[], int movesToGo, int maxDepth, int time[], int increment[], int movesToGo, int maxDepth,
int maxNodes, int maxTime, Move searchMoves[]) { int maxNodes, int maxTime, Move searchMoves[]) {
// Look for a book move // Initialize global search variables
if (!infinite && !ponder && get_option_value_bool("OwnBook")) Idle = StopOnPonderhit = AbortSearch = Quit = false;
FailHigh = FailLow = Problem = false;
NodesSincePoll = 0;
SearchStartTime = get_system_time();
ExactMaxTime = maxTime;
MaxDepth = maxDepth;
MaxNodes = maxNodes;
InfiniteSearch = infinite;
PonderSearch = ponder;
UseTimeManagement = !ExactMaxTime && !MaxDepth && !MaxNodes && !InfiniteSearch;
// Look for a book move, only during games, not tests
if (UseTimeManagement && !ponder && get_option_value_bool("OwnBook"))
{ {
Move bookMove; Move bookMove;
if (get_option_value_string("Book File") != OpeningBook.file_name()) if (get_option_value_string("Book File") != OpeningBook.file_name())
@ -384,8 +391,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
} }
// Initialize global search variables // Initialize global search variables
Idle = false;
SearchStartTime = get_system_time();
for (int i = 0; i < THREAD_MAX; i++) for (int i = 0; i < THREAD_MAX; i++)
{ {
Threads[i].nodes = 0ULL; Threads[i].nodes = 0ULL;
@ -467,48 +472,45 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
// Set thinking time // Set thinking time
int myTime = time[side_to_move]; int myTime = time[side_to_move];
int myIncrement = increment[side_to_move]; int myIncrement = increment[side_to_move];
if (UseTimeManagement)
if (!movesToGo) // Sudden death time control
{ {
if (myIncrement) if (!movesToGo) // Sudden death time control
{ {
MaxSearchTime = myTime / 30 + myIncrement; if (myIncrement)
AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100); {
} else { // Blitz game without increment MaxSearchTime = myTime / 30 + myIncrement;
MaxSearchTime = myTime / 30; AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100);
AbsoluteMaxSearchTime = myTime / 8; }
else // Blitz game without increment
{
MaxSearchTime = myTime / 30;
AbsoluteMaxSearchTime = myTime / 8;
}
} }
} else // (x moves) / (y minutes)
else // (x moves) / (y minutes)
{
if (movesToGo == 1)
{ {
MaxSearchTime = myTime / 2; if (movesToGo == 1)
AbsoluteMaxSearchTime = {
(myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4); MaxSearchTime = myTime / 2;
} else { AbsoluteMaxSearchTime = (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
MaxSearchTime = myTime / Min(movesToGo, 20); }
AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3); else
{
MaxSearchTime = myTime / Min(movesToGo, 20);
AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
}
}
if (PonderingEnabled)
{
MaxSearchTime += MaxSearchTime / 4;
MaxSearchTime = Min(MaxSearchTime, AbsoluteMaxSearchTime);
} }
} }
if (PonderingEnabled) // Set best NodesBetweenPolls interval
{
MaxSearchTime += MaxSearchTime / 4;
MaxSearchTime = Min(MaxSearchTime, AbsoluteMaxSearchTime);
}
// Fixed depth or fixed number of nodes?
MaxDepth = maxDepth;
if (MaxDepth)
InfiniteSearch = true; // HACK
MaxNodes = maxNodes;
if (MaxNodes) if (MaxNodes)
{
NodesBetweenPolls = Min(MaxNodes, 30000); NodesBetweenPolls = Min(MaxNodes, 30000);
InfiniteSearch = true; // HACK
}
else if (myTime && myTime < 1000) else if (myTime && myTime < 1000)
NodesBetweenPolls = 1000; NodesBetweenPolls = 1000;
else if (myTime && myTime < 5000) else if (myTime && myTime < 5000)
@ -793,7 +795,7 @@ namespace {
Problem = false; Problem = false;
if (!InfiniteSearch) if (UseTimeManagement)
{ {
// Time to stop? // Time to stop?
bool stopSearch = false; bool stopSearch = false;
@ -846,9 +848,9 @@ namespace {
rml.sort(); rml.sort();
// If we are pondering, we shouldn't print the best move before we // If we are pondering or in infinite search, we shouldn't print the
// are told to do so // best move before we are told to do so.
if (PonderSearch) if (PonderSearch || InfiniteSearch)
wait_for_stop_or_ponderhit(); wait_for_stop_or_ponderhit();
else else
// Print final search statistics // Print final search statistics
@ -2662,16 +2664,26 @@ namespace {
if (ShowCurrentLine) if (ShowCurrentLine)
Threads[0].printCurrentLine = true; Threads[0].printCurrentLine = true;
} }
// Should we stop the search? // Should we stop the search?
if (PonderSearch) if (PonderSearch)
return; return;
bool overTime = t > AbsoluteMaxSearchTime bool stillAtFirstMove = RootMoveNumber == 1
|| (RootMoveNumber == 1 && t > MaxSearchTime + ExtraSearchTime && !FailLow) //FIXME: We are not checking any problem flags, BUG? && !FailLow
|| ( !FailHigh && !FailLow && !fail_high_ply_1() && !Problem && t > MaxSearchTime + ExtraSearchTime;
&& t > 6*(MaxSearchTime + ExtraSearchTime));
if ( (Iteration >= 3 && (!InfiniteSearch && overTime)) bool noProblemFound = !FailHigh
&& !FailLow
&& !fail_high_ply_1()
&& !Problem
&& t > 6 * (MaxSearchTime + ExtraSearchTime);
bool noMoreTime = t > AbsoluteMaxSearchTime
|| stillAtFirstMove //FIXME: We are not checking any problem flags, BUG?
|| noProblemFound;
if ( (Iteration >= 3 && UseTimeManagement && noMoreTime)
|| (ExactMaxTime && t >= ExactMaxTime) || (ExactMaxTime && t >= ExactMaxTime)
|| (Iteration >= 3 && MaxNodes && nodes_searched() >= MaxNodes)) || (Iteration >= 3 && MaxNodes && nodes_searched() >= MaxNodes))
AbortSearch = true; AbortSearch = true;
@ -2686,14 +2698,23 @@ namespace {
int t = current_search_time(); int t = current_search_time();
PonderSearch = false; PonderSearch = false;
if (Iteration >= 3 &&
(!InfiniteSearch && (StopOnPonderhit || bool stillAtFirstMove = RootMoveNumber == 1
t > AbsoluteMaxSearchTime || && !FailLow
(RootMoveNumber == 1 && && t > MaxSearchTime + ExtraSearchTime;
t > MaxSearchTime + ExtraSearchTime && !FailLow) ||
(!FailHigh && !FailLow && !fail_high_ply_1() && !Problem && bool noProblemFound = !FailHigh
t > 6*(MaxSearchTime + ExtraSearchTime))))) && !FailLow
AbortSearch = true; && !fail_high_ply_1()
&& !Problem
&& t > 6 * (MaxSearchTime + ExtraSearchTime);
bool noMoreTime = t > AbsoluteMaxSearchTime
|| stillAtFirstMove
|| noProblemFound;
if (Iteration >= 3 && UseTimeManagement && (noMoreTime || StopOnPonderhit))
AbortSearch = true;
} }