/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
- Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
- Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
- Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
+ Copyright (C) 2004-2020 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Time.init(Limits, us, rootPos.game_ply());
TT.new_search();
+ Eval::verify_NNUE();
+
if (rootMoves.empty())
{
rootMoves.emplace_back(MOVE_NONE);
// Step 8. Futility pruning: child node (~50 Elo)
if ( !PvNode
- && depth < 6
+ && depth < 8
&& eval - futility_margin(depth, improving) >= beta
&& eval < VALUE_KNOWN_WIN) // Do not return unproven wins
return eval;
&& (ss-1)->statScore < 23824
&& eval >= beta
&& eval >= ss->staticEval
- && ss->staticEval >= beta - 33 * depth - 33 * improving + 112 * ttPv + 311
+ && ss->staticEval >= beta - 28 * depth - 28 * improving + 94 * ttPv + 200
&& !excludedMove
&& pos.non_pawn_material(us)
&& (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
thisThread->rootMoves.begin() + thisThread->pvLast, move))
continue;
+ // Check for legality
+ if (!rootNode && !pos.legal(move))
+ continue;
+
ss->moveCount = ++moveCount;
if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000)
continue;
// Futility pruning: parent node (~5 Elo)
- if ( lmrDepth < 6
+ if ( lmrDepth < 8
&& !ss->inCheck
&& ss->staticEval + 284 + 188 * lmrDepth <= alpha
&& (*contHist[0])[movedPiece][to_sq(move)]
&& !(PvNode && abs(bestValue) < 2)
&& PieceValue[MG][type_of(movedPiece)] >= PieceValue[MG][type_of(pos.piece_on(to_sq(move)))]
&& !ss->inCheck
- && ss->staticEval + 267 + 391 * lmrDepth
+ && ss->staticEval + 178 + 261 * lmrDepth
+ PieceValue[MG][type_of(pos.piece_on(to_sq(move)))] <= alpha)
continue;
// then that move is singular and should be extended. To verify this we do
// a reduced search on all the other moves but the ttMove and if the
// result is lower than ttValue minus a margin, then we will extend the ttMove.
- if ( depth >= 6
+ if ( depth >= 7
&& move == ttMove
&& !rootNode
&& !excludedMove // Avoid recursive singular search
/* && ttValue != VALUE_NONE Already implicit in the next condition */
&& abs(ttValue) < VALUE_KNOWN_WIN
&& (tte->bound() & BOUND_LOWER)
- && tte->depth() >= depth - 3
- && pos.legal(move))
+ && tte->depth() >= depth - 3)
{
Value singularBeta = ttValue - ((formerPv + 4) * depth) / 2;
Depth singularDepth = (depth - 1 + 3 * formerPv) / 2;
if (type_of(move) == CASTLING)
extension = 1;
+ // Late irreversible move extension
+ if ( move == ttMove
+ && pos.rule50_count() > 80
+ && (captureOrPromotion || type_of(movedPiece) == PAWN))
+ extension = 2;
+
// Add extension to new depth
newDepth += extension;
// Speculative prefetch as early as possible
prefetch(TT.first_entry(pos.key_after(move)));
- // Check for legality just before making the move
- if (!rootNode && !pos.legal(move))
- {
- ss->moveCount = --moveCount;
- continue;
- }
-
// Update the current move (this must be done after singular extension search)
ss->currentMove = move;
ss->continuationHistory = &thisThread->continuationHistory[ss->inCheck]
{
Depth r = reduction(improving, depth, moveCount);
+ // Decrease reduction at non-check cut nodes for second move at low depths
+ if ( cutNode
+ && depth <= 10
+ && moveCount <= 2
+ && !ss->inCheck)
+ r--;
+
// Decrease reduction if the ttHit running average is large
if (thisThread->ttHitAverage > 473 * TtHitAverageResolution * TtHitAverageWindow / 1024)
r--;