mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +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:
parent
968c3de8e0
commit
55745f4105
2 changed files with 54 additions and 57 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
109
src/search.cpp
109
src/search.cpp
|
@ -231,7 +231,7 @@ namespace {
|
||||||
int SearchStartTime;
|
int SearchStartTime;
|
||||||
int MaxNodes, MaxDepth;
|
int MaxNodes, MaxDepth;
|
||||||
int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime;
|
int MaxSearchTime, AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime;
|
||||||
bool InfiniteSearch, PonderSearch, StopOnPonderhit;
|
bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit;
|
||||||
bool AbortSearch, Quit;
|
bool AbortSearch, Quit;
|
||||||
bool FailHigh, FailLow, Problem;
|
bool FailHigh, FailLow, Problem;
|
||||||
|
|
||||||
|
@ -373,8 +373,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())
|
||||||
|
@ -388,15 +400,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize global search variables
|
|
||||||
Idle = StopOnPonderhit = AbortSearch = Quit = false;
|
|
||||||
FailHigh = FailLow = Problem = false;
|
|
||||||
SearchStartTime = get_system_time();
|
|
||||||
ExactMaxTime = maxTime;
|
|
||||||
NodesSincePoll = 0;
|
|
||||||
InfiniteSearch = infinite;
|
|
||||||
PonderSearch = ponder;
|
|
||||||
|
|
||||||
for (int i = 0; i < THREAD_MAX; i++)
|
for (int i = 0; i < THREAD_MAX; i++)
|
||||||
{
|
{
|
||||||
Threads[i].nodes = 0ULL;
|
Threads[i].nodes = 0ULL;
|
||||||
|
@ -464,51 +467,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)
|
||||||
|
{
|
||||||
|
MaxSearchTime = myTime / 30 + myIncrement;
|
||||||
|
AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100);
|
||||||
|
}
|
||||||
|
else // Blitz game without increment
|
||||||
|
{
|
||||||
|
MaxSearchTime = myTime / 30;
|
||||||
|
AbsoluteMaxSearchTime = myTime / 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // (x moves) / (y minutes)
|
||||||
|
{
|
||||||
|
if (movesToGo == 1)
|
||||||
|
{
|
||||||
|
MaxSearchTime = myTime / 2;
|
||||||
|
AbsoluteMaxSearchTime = (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MaxSearchTime = myTime / Min(movesToGo, 20);
|
||||||
|
AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!movesToGo) // Sudden death time control
|
if (PonderingEnabled)
|
||||||
{
|
|
||||||
if (myIncrement)
|
|
||||||
{
|
{
|
||||||
MaxSearchTime = myTime / 30 + myIncrement;
|
MaxSearchTime += MaxSearchTime / 4;
|
||||||
AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100);
|
MaxSearchTime = Min(MaxSearchTime, AbsoluteMaxSearchTime);
|
||||||
}
|
|
||||||
else // Blitz game without increment
|
|
||||||
{
|
|
||||||
MaxSearchTime = myTime / 30;
|
|
||||||
AbsoluteMaxSearchTime = myTime / 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // (x moves) / (y minutes)
|
|
||||||
{
|
|
||||||
if (movesToGo == 1)
|
|
||||||
{
|
|
||||||
MaxSearchTime = myTime / 2;
|
|
||||||
AbsoluteMaxSearchTime = (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaxSearchTime = myTime / Min(movesToGo, 20);
|
|
||||||
AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -791,7 +788,7 @@ namespace {
|
||||||
|
|
||||||
Problem = false;
|
Problem = false;
|
||||||
|
|
||||||
if (!InfiniteSearch)
|
if (UseTimeManagement)
|
||||||
{
|
{
|
||||||
// Time to stop?
|
// Time to stop?
|
||||||
bool stopSearch = false;
|
bool stopSearch = false;
|
||||||
|
@ -845,9 +842,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
|
||||||
|
@ -2680,7 +2677,7 @@ namespace {
|
||||||
|| stillAtFirstMove //FIXME: We are not checking any problem flags, BUG?
|
|| stillAtFirstMove //FIXME: We are not checking any problem flags, BUG?
|
||||||
|| noProblemFound;
|
|| noProblemFound;
|
||||||
|
|
||||||
if ( (Iteration >= 3 && !InfiniteSearch && noMoreTime)
|
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;
|
||||||
|
@ -2710,7 +2707,7 @@ namespace {
|
||||||
|| stillAtFirstMove
|
|| stillAtFirstMove
|
||||||
|| noProblemFound;
|
|| noProblemFound;
|
||||||
|
|
||||||
if (Iteration >= 3 && !InfiniteSearch && (noMoreTime || StopOnPonderhit))
|
if (Iteration >= 3 && UseTimeManagement && (noMoreTime || StopOnPonderhit))
|
||||||
AbortSearch = true;
|
AbortSearch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue