+ // Start with a small aspiration window and, in case of fail high/low,
+ // research with bigger window until not failing high/low anymore.
+ do {
+ // Search starts from ss+1 to allow referencing (ss-1). This is
+ // needed by update gains and ss copy when splitting at Root.
+ bestValue = search<Root>(pos, ss+1, alpha, beta, depth * ONE_PLY);
+
+ // Bring to front the best move. It is critical that sorting is
+ // done with a stable algorithm because all the values but the first
+ // and eventually the new best one are set to -VALUE_INFINITE and
+ // we want to keep the same order for all the moves but the new
+ // PV that goes to the front. Note that in case of MultiPV search
+ // the already searched PV lines are preserved.
+ sort<RootMove>(RootMoves.begin() + PVIdx, RootMoves.end());
+
+ // In case we have found an exact score and we are going to leave
+ // the fail high/low loop then reorder the PV moves, otherwise
+ // leave the last PV move in its position so to be searched again.
+ // Of course this is needed only in MultiPV search.
+ if (PVIdx && bestValue > alpha && bestValue < beta)
+ sort<RootMove>(RootMoves.begin(), RootMoves.begin() + PVIdx);
+
+ // Write PV back to transposition table in case the relevant
+ // entries have been overwritten during the search.
+ for (size_t i = 0; i <= PVIdx; i++)
+ RootMoves[i].insert_pv_in_tt(pos);
+
+ // If search has been stopped exit the aspiration window loop.
+ // Sorting and writing PV back to TT is safe becuase RootMoves
+ // is still valid, although refers to previous iteration.
+ if (Signals.stop)
+ break;
+
+ // Send full PV info to GUI if we are going to leave the loop or
+ // if we have a fail high/low and we are deep in the search.
+ if ((bestValue > alpha && bestValue < beta) || elapsed_time() > 2000)
+ pv_info_to_uci(pos, depth, alpha, beta);
+
+ // In case of failing high/low increase aspiration window and
+ // research, otherwise exit the fail high/low loop.
+ if (bestValue >= beta)
+ {
+ beta += delta;
+ delta += delta / 2;
+ }
+ else if (bestValue <= alpha)
+ {
+ Signals.failedLowAtRoot = true;
+ Signals.stopOnPonderhit = false;
+
+ alpha -= delta;
+ delta += delta / 2;
+ }
+ else
+ break;
+
+ assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE);
+
+ } while (abs(bestValue) < VALUE_KNOWN_WIN);
+ }