string uci_pv(const Position& pos, int depth, Value alpha, Value beta);
struct Skill {
string uci_pv(const Position& pos, int depth, Value alpha, Value beta);
struct Skill {
- Skill(int l) : level(l), best(MOVE_NONE) {}
+ Skill(int l, size_t rootSize) : level(l),
+ candidates(l < 20 ? std::min(4, (int)rootSize) : 0),
+ best(MOVE_NONE) {}
std::swap(RootMoves[0], *std::find(RootMoves.begin(),
RootMoves.end(), best ? best : pick_move()));
}
std::swap(RootMoves[0], *std::find(RootMoves.begin(),
RootMoves.end(), best ? best : pick_move()));
}
- MultiPV = Options["MultiPV"];
- Skill skill(Options["Skill Level"]);
+ size_t multiPV = Options["MultiPV"];
+ Skill skill(Options["Skill Level"], RootMoves.size());
// Do we have to play with skill handicap? In this case enable MultiPV search
// that we will use behind the scenes to retrieve a set of possible moves.
// Do we have to play with skill handicap? In this case enable MultiPV search
// that we will use behind the scenes to retrieve a set of possible moves.
// Iterative deepening loop until requested to stop or target depth reached
while (++depth <= MAX_PLY && !Signals.stop && (!Limits.depth || depth <= Limits.depth))
// Iterative deepening loop until requested to stop or target depth reached
while (++depth <= MAX_PLY && !Signals.stop && (!Limits.depth || depth <= Limits.depth))
RootMoves[i].prevScore = RootMoves[i].score;
// MultiPV loop. We perform a full root search for each PV line
RootMoves[i].prevScore = RootMoves[i].score;
// MultiPV loop. We perform a full root search for each PV line
// Sort the PV lines searched so far and update the GUI
std::stable_sort(RootMoves.begin(), RootMoves.begin() + PVIdx + 1);
// Sort the PV lines searched so far and update the GUI
std::stable_sort(RootMoves.begin(), RootMoves.begin() + PVIdx + 1);
sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl;
}
// If skill levels are enabled and time is up, pick a sub-optimal best move
sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl;
}
// If skill levels are enabled and time is up, pick a sub-optimal best move
if (Limits.use_time_management() && !Signals.stop && !Signals.stopOnPonderhit)
{
// Take some extra time if the best move has changed
if (Limits.use_time_management() && !Signals.stop && !Signals.stopOnPonderhit)
{
// Take some extra time if the best move has changed
TimeMgr.pv_instability(BestMoveChanges);
// Stop the search if only one legal move is available or all
TimeMgr.pv_instability(BestMoveChanges);
// Stop the search if only one legal move is available or all
- // When playing with a strength handicap, choose best move among the MultiPV
- // set using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
+ // When playing with a strength handicap, choose best move among the first 'candidates'
+ // RootMoves using a statistical rule dependent on 'level'. Idea by Heinz van Saanen.
// Choose best move. For each move score we add two terms both dependent on
// weakness. One deterministic and bigger for weaker moves, and one random,
// then we choose the move with the resulting highest score.
// Choose best move. For each move score we add two terms both dependent on
// weakness. One deterministic and bigger for weaker moves, and one random,
// then we choose the move with the resulting highest score.