+ if (mainThread)
+ {
+ failedLow = true;
+ Threads.stopOnPonderhit = false;
+ }
+ }
+ else if (bestValue >= beta)
+ beta = std::min(bestValue + delta, VALUE_INFINITE);
+ else
+ break;
+
+ delta += delta / 4 + 5;
+
+ assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE);
+ }
+
+ // Sort the PV lines searched so far and update the GUI
+ std::stable_sort(rootMoves.begin() + pvFirst, rootMoves.begin() + pvIdx + 1);
+
+ if ( mainThread
+ && (Threads.stop || pvIdx + 1 == multiPV || Time.elapsed() > 3000))
+ sync_cout << UCI::pv(rootPos, rootDepth, alpha, beta) << sync_endl;
+ }
+
+ if (!Threads.stop)
+ completedDepth = rootDepth;
+
+ if (rootMoves[0].pv[0] != lastBestMove) {
+ lastBestMove = rootMoves[0].pv[0];
+ lastBestMoveDepth = rootDepth;
+ }
+
+ // Have we found a "mate in x"?
+ if ( Limits.mate
+ && bestValue >= VALUE_MATE_IN_MAX_PLY
+ && VALUE_MATE - bestValue <= 2 * Limits.mate)
+ Threads.stop = true;
+
+ if (!mainThread)
+ continue;
+
+ // If skill level is enabled and time is up, pick a sub-optimal best move
+ if (skill.enabled() && skill.time_to_pick(rootDepth))
+ skill.pick_best(multiPV);
+
+ // Do we have time for the next iteration? Can we stop searching now?
+ if ( Limits.use_time_management()
+ && !Threads.stop
+ && !Threads.stopOnPonderhit)
+ {
+ const int F[] = { failedLow,
+ bestValue - mainThread->previousScore };
+
+ int improvingFactor = std::max(246, std::min(832, 306 + 119 * F[0] - 6 * F[1]));
+
+ // If the bestMove is stable over several iterations, reduce time accordingly
+ timeReduction = 1.0;
+ for (int i : {3, 4, 5})
+ if (lastBestMoveDepth * i < completedDepth)
+ timeReduction *= 1.25;
+
+ // Use part of the gained time from a previous stable move for the current move
+ double bestMoveInstability = 1.0 + mainThread->bestMoveChanges;
+ bestMoveInstability *= std::pow(mainThread->previousTimeReduction, 0.528) / timeReduction;
+
+ // Stop the search if we have only one legal move, or if available time elapsed
+ if ( rootMoves.size() == 1
+ || Time.elapsed() > Time.optimum() * bestMoveInstability * improvingFactor / 581)
+ {
+ // If we are allowed to ponder do not stop the search now but
+ // keep pondering until the GUI sends "ponderhit" or "stop".
+ if (Threads.ponder)
+ Threads.stopOnPonderhit = true;
+ else
+ Threads.stop = true;
+ }
+ }