// History and stats update bonus, based on depth
int stat_bonus(Depth d) {
- return d > 13 ? 29 : 17 * d * d + 134 * d - 134;
+ return d > 14 ? 29 : 8 * d * d + 224 * d - 215;
}
// Add a small random component to draw evaluations to avoid 3fold-blindness
tte->save(posKey, VALUE_NONE, ss->ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, eval);
}
- // Update static history for previous move
+ // Use static evaluation difference to improve quiet move ordering
if (is_ok((ss-1)->currentMove) && !(ss-1)->inCheck && !priorCapture)
{
- int bonus = ss->staticEval > -(ss-1)->staticEval + 2 * Tempo ? -stat_bonus(depth) :
- ss->staticEval < -(ss-1)->staticEval + 2 * Tempo ? stat_bonus(depth) :
- 0;
- thisThread->staticHistory[~us][from_to((ss-1)->currentMove)] << bonus;
+ int bonus = std::clamp(-depth * 4 * int((ss-1)->staticEval + ss->staticEval - 2 * Tempo), -1000, 1000);
+ thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << bonus;
}
// Step 7. Razoring (~1 Elo)
// Step 8. Futility pruning: child node (~50 Elo)
if ( !PvNode
- && depth < 8
+ && depth < 9
&& eval - futility_margin(depth, improving) >= beta
&& eval < VALUE_KNOWN_WIN) // Do not return unproven wins
return eval;
}
}
- probCutBeta = beta + 183 - 49 * improving;
+ probCutBeta = beta + 194 - 49 * improving;
// Step 10. ProbCut (~10 Elo)
// If we have a good enough capture and a reduced search returns a value
Move countermove = thisThread->counterMoves[pos.piece_on(prevSq)][prevSq];
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
- &thisThread->staticHistory,
&thisThread->lowPlyHistory,
&captureHistory,
contHist,
// Futility pruning: parent node (~5 Elo)
if ( lmrDepth < 7
&& !ss->inCheck
- && ss->staticEval + 266 + 170 * lmrDepth <= alpha
+ && ss->staticEval + 254 + 159 * lmrDepth <= alpha
&& (*contHist[0])[movedPiece][to_sq(move)]
+ (*contHist[1])[movedPiece][to_sq(move)]
+ (*contHist[3])[movedPiece][to_sq(move)]
- + (*contHist[5])[movedPiece][to_sq(move)] / 2 < 27376)
+ + (*contHist[5])[movedPiece][to_sq(move)] / 2 < 26394)
continue;
// Prune moves with negative SEE (~20 Elo)
continue;
// SEE based pruning
- if (!pos.see_ge(move, Value(-213) * depth)) // (~25 Elo)
+ if (!pos.see_ge(move, Value(-218) * depth)) // (~25 Elo)
continue;
}
}
|| moveCountPruning
|| ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha
|| cutNode
+ || (!PvNode && !formerPv && thisThread->captureHistory[movedPiece][to_sq(move)][type_of(pos.captured_piece())] < 4506)
|| thisThread->ttHitAverage < 432 * TtHitAverageResolution * TtHitAverageWindow / 1024))
{
Depth r = reduction(improving, depth, moveCount);
r -= 2;
// Increase reduction at root and non-PV nodes when the best move does not change frequently
- if ((rootNode || !PvNode) && depth > 10 && thisThread->bestMoveChanges <= 2)
+ if ((rootNode || !PvNode) && thisThread->rootDepth > 10 && thisThread->bestMoveChanges <= 2)
r++;
// More reductions for late moves if position was not in previous PV
// queen and checking knight promotions, and other checks(only if depth >= DEPTH_QS_CHECKS)
// will be generated.
MovePicker mp(pos, ttMove, depth, &thisThread->mainHistory,
- &thisThread->staticHistory,
&thisThread->captureHistory,
contHist,
to_sq((ss-1)->currentMove));