Options["Threads"] = threads;
if (valType == "time")
- limits.maxTime = 1000 * atoi(valStr.c_str()); // maxTime is in ms
+ limits.movetime = 1000 * atoi(valStr.c_str()); // movetime is in ms
else if (valType == "nodes")
- limits.maxNodes = atoi(valStr.c_str());
+ limits.nodes = atoi(valStr.c_str());
else
- limits.maxDepth = atoi(valStr.c_str());
+ limits.depth = atoi(valStr.c_str());
if (fenFile != "default")
{
if (valType == "perft")
{
- int64_t cnt = Search::perft(pos, limits.maxDepth * ONE_PLY);
- cerr << "\nPerft " << limits.maxDepth << " leaf nodes: " << cnt << endl;
+ int64_t cnt = Search::perft(pos, limits.depth * ONE_PLY);
+ cerr << "\nPerft " << limits.depth << " leaf nodes: " << cnt << endl;
nodes += cnt;
}
else
Chess960 = pos.is_chess960();
Eval::RootColor = pos.side_to_move();
SearchTime.restart();
- TimeMgr.init(Limits, pos.startpos_ply_counter());
+ TimeMgr.init(Limits, pos.startpos_ply_counter(), pos.side_to_move());
TT.new_search();
H.clear();
log << "\nSearching: " << pos.to_fen()
<< "\ninfinite: " << Limits.infinite
<< " ponder: " << Limits.ponder
- << " time: " << Limits.time
- << " increment: " << Limits.increment
- << " moves to go: " << Limits.movesToGo
+ << " time: " << Limits.times[pos.side_to_move()]
+ << " increment: " << Limits.incs[pos.side_to_move()]
+ << " moves to go: " << Limits.movestogo
<< endl;
}
ss->currentMove = MOVE_NULL; // Hack to skip update gains
// Iterative deepening loop until requested to stop or target depth reached
- while (!Signals.stop && ++depth <= MAX_PLY && (!Limits.maxDepth || depth <= Limits.maxDepth))
+ while (!Signals.stop && ++depth <= MAX_PLY && (!Limits.depth || depth <= Limits.depth))
{
// Save last iteration's scores before first PV line is searched and all
// the move scores but the (new) PV are set to -VALUE_INFINITE.
// Step 2. Check for aborted search and immediate draw
// Enforce node limit here. FIXME: This only works with 1 search thread.
- if (Limits.maxNodes && pos.nodes_searched() >= Limits.maxNodes)
+ if (Limits.nodes && pos.nodes_searched() >= Limits.nodes)
Signals.stop = true;
if (( Signals.stop
|| stillAtFirstMove;
if ( (Limits.use_time_management() && noMoreTime)
- || (Limits.maxTime && e >= Limits.maxTime))
+ || (Limits.movetime && e >= Limits.movetime))
Signals.stop = true;
}
struct LimitsType {
LimitsType() { memset(this, 0, sizeof(LimitsType)); }
- bool use_time_management() const { return !(maxTime | maxDepth | maxNodes | infinite); }
+ bool use_time_management() const { return !(movetime | depth | nodes | infinite); }
- int time, increment, movesToGo, maxTime, maxDepth, maxNodes, infinite, ponder;
+ int times[2], incs[2], movestogo, depth, nodes, movetime, infinite, ponder;
};
}
-void TimeManager::init(const Search::LimitsType& limits, int currentPly)
+void TimeManager::init(const Search::LimitsType& limits, int currentPly, Color us)
{
/* We support four different kind of time controls:
// Initialize to maximum values but unstablePVExtraTime that is reset
unstablePVExtraTime = 0;
- optimumSearchTime = maximumSearchTime = limits.time;
+ optimumSearchTime = maximumSearchTime = limits.times[us];
// We calculate optimum time usage for different hypothetic "moves to go"-values and choose the
// minimum of calculated search time values. Usually the greatest hypMTG gives the minimum values.
- for (hypMTG = 1; hypMTG <= (limits.movesToGo ? std::min(limits.movesToGo, MoveHorizon) : MoveHorizon); hypMTG++)
+ for (hypMTG = 1; hypMTG <= (limits.movestogo ? std::min(limits.movestogo, MoveHorizon) : MoveHorizon); hypMTG++)
{
// Calculate thinking time for hypothetic "moves to go"-value
- hypMyTime = limits.time
- + limits.increment * (hypMTG - 1)
+ hypMyTime = limits.times[us]
+ + limits.incs[us] * (hypMTG - 1)
- emergencyBaseTime
- emergencyMoveTime * std::min(hypMTG, emergencyMoveHorizon);
class TimeManager {
public:
- void init(const Search::LimitsType& limits, int currentPly);
+ void init(const Search::LimitsType& limits, int currentPly, Color us);
void pv_instability(int curChanges, int prevChanges);
int available_time() const { return optimumSearchTime + unstablePVExtraTime; }
int maximum_time() const { return maximumSearchTime; }
// go() is called when engine receives the "go" UCI command. The function sets
// the thinking time and other parameters from the input string, and then starts
- // the main searching thread.
+ // the search.
void go(Position& pos, istringstream& is) {
- string token;
Search::LimitsType limits;
std::set<Move> searchMoves;
- int time[] = { 0, 0 }, inc[] = { 0, 0 };
+ string token;
while (is >> token)
{
- if (token == "infinite")
- limits.infinite = true;
- else if (token == "ponder")
- limits.ponder = true;
- else if (token == "wtime")
- is >> time[WHITE];
+ if (token == "wtime")
+ is >> limits.times[WHITE];
else if (token == "btime")
- is >> time[BLACK];
+ is >> limits.times[BLACK];
else if (token == "winc")
- is >> inc[WHITE];
+ is >> limits.incs[WHITE];
else if (token == "binc")
- is >> inc[BLACK];
+ is >> limits.incs[BLACK];
else if (token == "movestogo")
- is >> limits.movesToGo;
+ is >> limits.movestogo;
else if (token == "depth")
- is >> limits.maxDepth;
+ is >> limits.depth;
else if (token == "nodes")
- is >> limits.maxNodes;
+ is >> limits.nodes;
else if (token == "movetime")
- is >> limits.maxTime;
+ is >> limits.movetime;
+ else if (token == "infinite")
+ limits.infinite = true;
+ else if (token == "ponder")
+ limits.ponder = true;
else if (token == "searchmoves")
while (is >> token)
searchMoves.insert(move_from_uci(pos, token));
}
- limits.time = time[pos.side_to_move()];
- limits.increment = inc[pos.side_to_move()];
-
Threads.start_searching(pos, limits, searchMoves);
}