/// Search::perft() is our utility to verify move generation. All the leaf nodes
/// up to the given depth are generated and counted and the sum returned.
/// Search::perft() is our utility to verify move generation. All the leaf nodes
/// up to the given depth are generated and counted and the sum returned.
for (MoveList<LEGAL> it(pos); *it; ++it)
{
pos.do_move(*it, st, ci, pos.move_gives_check(*it, ci));
for (MoveList<LEGAL> it(pos); *it; ++it)
{
pos.do_move(*it, st, ci, pos.move_gives_check(*it, ci));
/// Search::think() is the external interface to Stockfish's search, and is
/// called by the main thread when the program receives the UCI 'go' command. It
/// Search::think() is the external interface to Stockfish's search, and is
/// called by the main thread when the program receives the UCI 'go' command. It
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
// Set best timer interval to avoid lagging under time pressure. Timer is
// used to check for remaining available thinking time.
Threads.timer->msec = 0; // Stop the timer
Threads.sleepWhileIdle = true; // Send idle threads to sleep
Threads.timer->msec = 0; // Stop the timer
Threads.sleepWhileIdle = true; // Send idle threads to sleep
Value bestValue, alpha, beta, delta;
memset(ss-1, 0, 4 * sizeof(Stack));
Value bestValue, alpha, beta, delta;
memset(ss-1, 0, 4 * sizeof(Stack));
// MultiPV loop. We perform a full root search for each PV line
for (PVIdx = 0; PVIdx < PVSize; PVIdx++)
{
// MultiPV loop. We perform a full root search for each PV line
for (PVIdx = 0; PVIdx < PVSize; PVIdx++)
{
- alpha = RootMoves[PVIdx].prevScore - delta;
- beta = RootMoves[PVIdx].prevScore + delta;
- }
- else
- {
- alpha = -VALUE_INFINITE;
- beta = VALUE_INFINITE;
+ alpha = std::max(RootMoves[PVIdx].prevScore - delta,-VALUE_INFINITE);
+ beta = std::min(RootMoves[PVIdx].prevScore + delta, VALUE_INFINITE);
// Give some update (without cluttering the UI) before to research
if (Time::now() - SearchTime > 3000)
sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl;
// Give some update (without cluttering the UI) before to research
if (Time::now() - SearchTime > 3000)
sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl;
- if (abs(bestValue) >= VALUE_KNOWN_WIN)
+ // In case of failing low/high increase aspiration window and
+ // research, otherwise exit the loop.
+ if (bestValue <= alpha)
- alpha = -VALUE_INFINITE;
- beta = VALUE_INFINITE;
+ alpha = std::max(bestValue - delta, -VALUE_INFINITE);
+
+ Signals.failedLowAtRoot = true;
+ Signals.stopOnPonderhit = false;
&& eval - futility_margin(depth, (ss-1)->futilityMoveCount) >= beta
&& abs(beta) < VALUE_MATE_IN_MAX_PLY
&& abs(eval) < VALUE_KNOWN_WIN
&& eval - futility_margin(depth, (ss-1)->futilityMoveCount) >= beta
&& abs(beta) < VALUE_MATE_IN_MAX_PLY
&& abs(eval) < VALUE_KNOWN_WIN
Square prevMoveSq = to_sq((ss-1)->currentMove);
Move countermoves[] = { Countermoves[pos.piece_on(prevMoveSq)][prevMoveSq].first,
Square prevMoveSq = to_sq((ss-1)->currentMove);
Move countermoves[] = { Countermoves[pos.piece_on(prevMoveSq)][prevMoveSq].first,