#define S(mg, eg) make_score(mg, eg)
// Pawn penalties
- constexpr Score Backward = S( 6, 23);
- constexpr Score Doubled = S(13, 53);
- constexpr Score DoubledEarly = S(20, 10);
- constexpr Score Isolated = S( 2, 15);
- constexpr Score WeakLever = S( 5, 57);
- constexpr Score WeakUnopposed = S(16, 22);
+ constexpr Score Backward = S( 9, 22);
+ constexpr Score Doubled = S(13, 51);
+ constexpr Score DoubledEarly = S(20, 7);
+ constexpr Score Isolated = S( 3, 15);
+ constexpr Score WeakLever = S( 4, 58);
+ constexpr Score WeakUnopposed = S(13, 24);
// Bonus for blocked pawns at 5th or 6th rank
- constexpr Score BlockedPawn[RANK_NB - 5] = { S(-15, -3), S(-6, 3) };
- constexpr Score BlockedPawn[2] = { S(-17, -6), S(-9, 2) };
++ constexpr Score BlockedPawn[RANK_NB - 5] = { S(-17, -6), S(-9, 2) };
constexpr Score BlockedStorm[RANK_NB] = {
S(0, 0), S(0, 0), S(75, 78), S(-8, 16), S(-6, 10), S(-6, 6), S(0, 2)
{ S(-3,-39), S( 6,-18), S(13, -9), S( 7, 3) },
{ S( 4,-23), S( 5, -3), S( 9, 13), S( 8, 24) },
{ S( 0,-29), S(14, -6), S(12, 9), S( 5, 21) },
- { S(-4,-38), S(10,-18), S( 6,-12), S( 8, 1) },
+ { S(-4,-38), S(10,-18), S( 6,-11), S( 8, 1) },
{ S(-5,-50), S( 6,-27), S(10,-24), S( 8, -8) },
- { S(-2,-75), S(-2,-52), S( 1,-43), S(-2,-36) }
+ { S(-2,-74), S(-2,-52), S( 1,-43), S(-2,-34) }
- },
- { // King
+ }
+};
+
+constexpr Score KingBonus[RANK_NB][int(FILE_NB) / 2] = {
{ S(271, 1), S(327, 45), S(271, 85), S(198, 76) },
{ S(278, 53), S(303,100), S(234,133), S(179,135) },
{ S(195, 88), S(258,130), S(169,169), S(120,175) },
// Step 8. Null move search with verification search (~40 Elo)
if ( !PvNode
&& (ss-1)->currentMove != MOVE_NULL
- && (ss-1)->statScore < 22977
+ && (ss-1)->statScore < 22661
&& eval >= beta
&& eval >= ss->staticEval
- && ss->staticEval >= beta - 30 * depth - 28 * improving + 84 * ss->ttPv + 168 + 200 * (!pos.double_step_enabled() && pos.piece_to_char()[PAWN] != ' ')
- && ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159
++ && ss->staticEval >= beta - 24 * depth - 34 * improving + 162 * ss->ttPv + 159 + 200 * (!pos.double_step_enabled() && pos.piece_to_char()[PAWN] != ' ')
&& !excludedMove
&& pos.non_pawn_material(us)
+ && pos.count<ALL_PIECES>(~us) != pos.count<PAWN>(~us)
+ && !pos.flip_enclosed_pieces()
&& (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor))
{
assert(eval - beta >= 0);
// Null move dynamic reduction based on depth and value
- Depth R = (1015 - 300 * pos.must_capture() - 250 * !pos.checking_permitted() + 85 * depth) / 256 + std::min(int(eval - beta) / 191, pos.must_capture() || pos.blast_on_capture() ? 0 : 3);
- Depth R = (1062 + 68 * depth) / 256 + std::min(int(eval - beta) / 190, 3);
++ Depth R = (1062 - 300 * pos.must_capture() - 250 * !pos.checking_permitted() + 68 * depth) / 256 + std::min(int(eval - beta) / 190, pos.must_capture() || pos.blast_on_capture() ? 0 : 3);
ss->currentMove = MOVE_NULL;
ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0];
}
}
- probCutBeta = beta + (194 + 20 * !!pos.capture_the_flag_piece() + 50 * pos.captures_to_hand()) * (1 + pos.check_counting() + pos.extinction_single_piece()) - 49 * improving;
- probCutBeta = beta + 209 - 44 * improving;
++ probCutBeta = beta + (209 + 20 * !!pos.capture_the_flag_piece() + 50 * pos.captures_to_hand()) * (1 + pos.check_counting() + pos.extinction_single_piece()) - 44 * improving;
// Step 9. ProbCut (~10 Elo)
// If we have a good enough capture and a reduced search returns a value
// Futility pruning: parent node (~5 Elo)
if ( lmrDepth < 7
&& !ss->inCheck
- && ss->staticEval + 174 + 157 * 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)] / 3 < 26237)
+ && !pos.extinction_single_piece()
- && ss->staticEval + (254 + 159 * lmrDepth) * (1 + pos.check_counting()) <= alpha
++ && ss->staticEval + (174 + 157 * lmrDepth) * (1 + pos.check_counting()) <= alpha
+ && (*contHist[0])[history_slot(movedPiece)][to_sq(move)]
+ + (*contHist[1])[history_slot(movedPiece)][to_sq(move)]
+ + (*contHist[3])[history_slot(movedPiece)][to_sq(move)]
- + (*contHist[5])[history_slot(movedPiece)][to_sq(move)] / 2 < 26394)
++ + (*contHist[5])[history_slot(movedPiece)][to_sq(move)] / 3 < 26237)
continue;
// Prune moves with negative SEE (~20 Elo)
r -= 2 + ss->ttPv - (type_of(movedPiece) == PAWN);
ss->statScore = thisThread->mainHistory[us][from_to(move)]
- + (*contHist[0])[movedPiece][to_sq(move)]
- + (*contHist[1])[movedPiece][to_sq(move)]
- + (*contHist[3])[movedPiece][to_sq(move)]
+ + (*contHist[0])[history_slot(movedPiece)][to_sq(move)]
+ + (*contHist[1])[history_slot(movedPiece)][to_sq(move)]
+ + (*contHist[3])[history_slot(movedPiece)][to_sq(move)]
- - 5287;
+ - 5337;
// Decrease/increase reduction by comparing opponent's stat score (~10 Elo)
- if (ss->statScore >= -105 && (ss-1)->statScore < -103)
+ if (ss->statScore >= -89 && (ss-1)->statScore < -116)
r--;
- else if ((ss-1)->statScore >= -122 && ss->statScore < -129)
+ else if ((ss-1)->statScore >= -112 && ss->statScore < -100)
r++;
// Decrease/increase reduction for moves with a good/bad history (~30 Elo)
// use sum of main history and first continuation history with an offset
if (ss->inCheck)
r -= (thisThread->mainHistory[us][from_to(move)]
- + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] - 4333) / 16384;
- + (*contHist[0])[movedPiece][to_sq(move)] - 4341) / 16384;
++ + (*contHist[0])[history_slot(movedPiece)][to_sq(move)] - 4341) / 16384;
else
- r -= ss->statScore / (14884 - 4434 * pos.captures_to_hand());
- r -= ss->statScore / 14382;
++ r -= ss->statScore / (14382 - 4434 * pos.captures_to_hand());
}
Depth d = std::clamp(newDepth - r, 1, newDepth);