// Different node types, used as a template parameter
enum NodeType { NonPV, PV };
+ constexpr uint64_t ttHitAverageWindow = 4096;
+ constexpr uint64_t ttHitAverageResolution = 1024;
+
// Razor and futility margins
constexpr int RazorMargin = 661;
Value futility_margin(Depth d, bool improving) {
multiPV = std::max(multiPV, (size_t)4);
multiPV = std::min(multiPV, rootMoves.size());
+ ttHitAverage = ttHitAverageWindow * ttHitAverageResolution / 2;
int ct = int(Options["Contempt"]) * PawnValueEg / 100; // From centipawns
ttMove = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0]
: ttHit ? tte->move() : MOVE_NONE;
ttPv = PvNode || (ttHit && tte->is_pv());
+ // thisThread->ttHitAverage can be used to approximate the running average of ttHit
+ thisThread->ttHitAverage = (ttHitAverageWindow - 1) * thisThread->ttHitAverage / ttHitAverageWindow
+ + ttHitAverageResolution * ttHit;
// At non-PV nodes we check for an early TT cutoff
if ( !PvNode
moveCountPruning = moveCount >= futility_move_count(improving, depth);
if ( !captureOrPromotion
- && !givesCheck
- && (!PvNode || !pos.advanced_pawn_push(move) || pos.non_pawn_material(~us) > BishopValueMg))
+ && !givesCheck)
{
// Reduced depth of the next LMR search
int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0);
{
Depth r = reduction(improving, depth, moveCount);
+ // Decrease reduction if the ttHit running average is large
+ if (thisThread->ttHitAverage > 544 * ttHitAverageResolution * ttHitAverageWindow / 1024)
+ r--;
+
// Reduction if other threads are searching this position.
if (th.marked())
r++;