mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-23 21:27:14 +00:00
Merge branch 'master' into clusterMergeMaster3
This commit is contained in:
+61
-41
@@ -114,8 +114,8 @@ namespace {
|
||||
Value value_from_tt(Value v, int ply);
|
||||
void update_pv(Move* pv, Move move, Move* childPv);
|
||||
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
|
||||
void update_quiet_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietsCnt, int bonus);
|
||||
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCnt, int bonus);
|
||||
void update_quiet_stats(const Position& pos, Stack* ss, Move move, Move* quiets, int quietCount, int bonus);
|
||||
void update_capture_stats(const Position& pos, Move move, Move* captures, int captureCount, int bonus);
|
||||
|
||||
inline bool gives_check(const Position& pos, Move move) {
|
||||
Color us = pos.side_to_move();
|
||||
@@ -529,32 +529,32 @@ void Thread::search() {
|
||||
if ( Limits.use_time_management()
|
||||
&& !Threads.stop
|
||||
&& !Threads.stopOnPonderhit)
|
||||
{
|
||||
double fallingEval = (306 + 119 * failedLow + 6 * (mainThread->previousScore - bestValue)) / 581.0;
|
||||
fallingEval = std::max(0.5, std::min(1.5, fallingEval));
|
||||
|
||||
// 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 * fallingEval)
|
||||
{
|
||||
double fallingEval = (306 + 119 * failedLow + 6 * (mainThread->previousScore - bestValue)) / 581.0;
|
||||
fallingEval = std::max(0.5, std::min(1.5, fallingEval));
|
||||
|
||||
// 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 * fallingEval)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mainThread)
|
||||
@@ -608,7 +608,7 @@ namespace {
|
||||
Move ttMove, move, excludedMove, bestMove;
|
||||
Depth extension, newDepth;
|
||||
Value bestValue, value, ttValue, eval, maxValue, pureStaticEval;
|
||||
bool ttHit, inCheck, givesCheck, improving;
|
||||
bool ttHit, pvHit, inCheck, givesCheck, improving;
|
||||
bool captureOrPromotion, doFullDepthSearch, moveCountPruning, skipQuiets, ttCapture, pvExact;
|
||||
Piece movedPiece;
|
||||
int moveCount, captureCount, quietCount;
|
||||
@@ -674,6 +674,7 @@ namespace {
|
||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
||||
ttMove = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0]
|
||||
: ttHit ? tte->move() : MOVE_NONE;
|
||||
pvHit = ttHit ? tte->pv_hit() : false;
|
||||
|
||||
// At non-PV nodes we check for an early TT cutoff
|
||||
if ( !PvNode
|
||||
@@ -707,6 +708,11 @@ namespace {
|
||||
return ttValue;
|
||||
}
|
||||
|
||||
if ( depth > 6 * ONE_PLY
|
||||
&& !excludedMove
|
||||
&& PvNode)
|
||||
pvHit = true;
|
||||
|
||||
// Step 5. Tablebases probe
|
||||
if (!rootNode && TB::Cardinality)
|
||||
{
|
||||
@@ -741,7 +747,7 @@ namespace {
|
||||
|| (b == BOUND_LOWER ? value >= beta : value <= alpha))
|
||||
{
|
||||
Cluster::save(thisThread, tte,
|
||||
posKey, value_to_tt(value, ss->ply), b,
|
||||
posKey, value_to_tt(value, ss->ply), pvHit, b,
|
||||
std::min(DEPTH_MAX - ONE_PLY, depth + 6 * ONE_PLY),
|
||||
MOVE_NONE, VALUE_NONE);
|
||||
|
||||
@@ -793,7 +799,7 @@ namespace {
|
||||
ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::Tempo;
|
||||
|
||||
Cluster::save(thisThread, tte,
|
||||
posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE,
|
||||
posKey, VALUE_NONE, pvHit, BOUND_NONE, DEPTH_NONE, MOVE_NONE,
|
||||
pureStaticEval);
|
||||
}
|
||||
|
||||
@@ -909,6 +915,7 @@ namespace {
|
||||
tte = TT.probe(posKey, ttHit);
|
||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
||||
ttMove = ttHit ? tte->move() : MOVE_NONE;
|
||||
pvHit = ttHit ? tte->pv_hit() : false;
|
||||
}
|
||||
|
||||
moves_loop: // When in check, search starts from here
|
||||
@@ -977,13 +984,21 @@ moves_loop: // When in check, search starts from here
|
||||
&& tte->depth() >= depth - 3 * ONE_PLY
|
||||
&& pos.legal(move))
|
||||
{
|
||||
Value reducedBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
|
||||
Value singularBeta = std::max(ttValue - 2 * depth / ONE_PLY, -VALUE_MATE);
|
||||
ss->excludedMove = move;
|
||||
value = search<NonPV>(pos, ss, reducedBeta - 1, reducedBeta, depth / 2, cutNode);
|
||||
value = search<NonPV>(pos, ss, singularBeta - 1, singularBeta, depth / 2, cutNode);
|
||||
ss->excludedMove = MOVE_NONE;
|
||||
|
||||
if (value < reducedBeta)
|
||||
if (value < singularBeta)
|
||||
extension = ONE_PLY;
|
||||
|
||||
// Multi-cut pruning
|
||||
// Our ttMove is assumed to fail high, and now we failed high also on a reduced
|
||||
// search without the ttMove. So we assume this expected Cut-node is not singular,
|
||||
// that is multiple moves fail high, and we can prune the whole subtree by returning
|
||||
// the hard beta bound.
|
||||
else if (cutNode && singularBeta > beta)
|
||||
return beta;
|
||||
}
|
||||
else if ( givesCheck // Check extension (~2 Elo)
|
||||
&& pos.see_ge(move))
|
||||
@@ -1061,6 +1076,10 @@ moves_loop: // When in check, search starts from here
|
||||
{
|
||||
Depth r = reduction<PvNode>(improving, depth, moveCount);
|
||||
|
||||
// Decrease reduction if position is or has been on the PV
|
||||
if (pvHit && !PvNode)
|
||||
r -= ONE_PLY;
|
||||
|
||||
// Decrease reduction if opponent's move count is high (~10 Elo)
|
||||
if ((ss-1)->moveCount > 15)
|
||||
r -= ONE_PLY;
|
||||
@@ -1244,7 +1263,7 @@ moves_loop: // When in check, search starts from here
|
||||
|
||||
if (!excludedMove)
|
||||
Cluster::save(thisThread, tte,
|
||||
posKey, value_to_tt(bestValue, ss->ply),
|
||||
posKey, value_to_tt(bestValue, ss->ply), pvHit,
|
||||
bestValue >= beta ? BOUND_LOWER :
|
||||
PvNode && bestMove ? BOUND_EXACT : BOUND_UPPER,
|
||||
depth, bestMove, pureStaticEval);
|
||||
@@ -1274,7 +1293,7 @@ moves_loop: // When in check, search starts from here
|
||||
Move ttMove, move, bestMove;
|
||||
Depth ttDepth;
|
||||
Value bestValue, value, ttValue, futilityValue, futilityBase, oldAlpha;
|
||||
bool ttHit, inCheck, givesCheck, evasionPrunable;
|
||||
bool ttHit, pvHit, inCheck, givesCheck, evasionPrunable;
|
||||
int moveCount;
|
||||
|
||||
if (PvNode)
|
||||
@@ -1308,6 +1327,7 @@ moves_loop: // When in check, search starts from here
|
||||
tte = TT.probe(posKey, ttHit);
|
||||
ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
|
||||
ttMove = ttHit ? tte->move() : MOVE_NONE;
|
||||
pvHit = ttHit ? tte->pv_hit() : false;
|
||||
|
||||
if ( !PvNode
|
||||
&& ttHit
|
||||
@@ -1346,7 +1366,7 @@ moves_loop: // When in check, search starts from here
|
||||
{
|
||||
if (!ttHit)
|
||||
Cluster::save(thisThread, tte,
|
||||
posKey, value_to_tt(bestValue, ss->ply), BOUND_LOWER,
|
||||
posKey, value_to_tt(bestValue, ss->ply), pvHit, BOUND_LOWER,
|
||||
DEPTH_NONE, MOVE_NONE, ss->staticEval);
|
||||
|
||||
return bestValue;
|
||||
@@ -1458,7 +1478,7 @@ moves_loop: // When in check, search starts from here
|
||||
return mated_in(ss->ply); // Plies to mate from the root
|
||||
|
||||
Cluster::save(thisThread, tte,
|
||||
posKey, value_to_tt(bestValue, ss->ply),
|
||||
posKey, value_to_tt(bestValue, ss->ply), pvHit,
|
||||
bestValue >= beta ? BOUND_LOWER :
|
||||
PvNode && bestValue > oldAlpha ? BOUND_EXACT : BOUND_UPPER,
|
||||
ttDepth, bestMove, ss->staticEval);
|
||||
@@ -1518,7 +1538,7 @@ moves_loop: // When in check, search starts from here
|
||||
// update_capture_stats() updates move sorting heuristics when a new capture best move is found
|
||||
|
||||
void update_capture_stats(const Position& pos, Move move,
|
||||
Move* captures, int captureCnt, int bonus) {
|
||||
Move* captures, int captureCount, int bonus) {
|
||||
|
||||
CapturePieceToHistory& captureHistory = pos.this_thread()->captureHistory;
|
||||
Piece moved_piece = pos.moved_piece(move);
|
||||
@@ -1528,7 +1548,7 @@ moves_loop: // When in check, search starts from here
|
||||
captureHistory[moved_piece][to_sq(move)][captured] << bonus;
|
||||
|
||||
// Decrease all the other played capture moves
|
||||
for (int i = 0; i < captureCnt; ++i)
|
||||
for (int i = 0; i < captureCount; ++i)
|
||||
{
|
||||
moved_piece = pos.moved_piece(captures[i]);
|
||||
captured = type_of(pos.piece_on(to_sq(captures[i])));
|
||||
@@ -1540,7 +1560,7 @@ moves_loop: // When in check, search starts from here
|
||||
// update_quiet_stats() updates move sorting heuristics when a new quiet best move is found
|
||||
|
||||
void update_quiet_stats(const Position& pos, Stack* ss, Move move,
|
||||
Move* quiets, int quietsCnt, int bonus) {
|
||||
Move* quiets, int quietCount, int bonus) {
|
||||
|
||||
if (ss->killers[0] != move)
|
||||
{
|
||||
@@ -1560,7 +1580,7 @@ moves_loop: // When in check, search starts from here
|
||||
}
|
||||
|
||||
// Decrease all the other played quiet moves
|
||||
for (int i = 0; i < quietsCnt; ++i)
|
||||
for (int i = 0; i < quietCount; ++i)
|
||||
{
|
||||
thisThread->mainHistory[us][from_to(quiets[i])] << -bonus;
|
||||
update_continuation_histories(ss, pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus);
|
||||
@@ -1706,7 +1726,7 @@ bool RootMove::extract_ponder_from_tt(Position& pos) {
|
||||
|
||||
assert(pv.size() == 1);
|
||||
|
||||
if (!pv[0])
|
||||
if (pv[0] == MOVE_NONE)
|
||||
return false;
|
||||
|
||||
pos.do_move(pv[0], st);
|
||||
|
||||
Reference in New Issue
Block a user