if ( !givesCheck
&& lmrDepth < 7
&& !ss->inCheck
- && ss->staticEval + 197 + 248 * lmrDepth + PieceValue[EG][pos.piece_on(to_sq(move))]
+ && ss->staticEval + 197 + 248 * lmrDepth + PieceValue[pos.piece_on(to_sq(move))]
+ captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] / 7 < alpha)
continue;
- Bitboard occupied;
- // SEE based pruning (~11 Elo)
- if (!pos.see_ge(move, occupied, Value(-205) * depth))
- {
- if (depth < 2 - capture)
- continue;
- // Don't prune the move if opponent Queen/Rook is under discovered attack after the exchanges
- // Don't prune the move if opponent King is under discovered attack after or during the exchanges
- Bitboard leftEnemies = (pos.pieces(~us, KING, QUEEN, ROOK)) & occupied;
- Bitboard attacks = 0;
- occupied |= to_sq(move);
- while (leftEnemies && !attacks)
- {
- Square sq = pop_lsb(leftEnemies);
- attacks |= pos.attackers_to(sq, occupied) & pos.pieces(us) & occupied;
- // Don't consider pieces that were already threatened/hanging before SEE exchanges
- if (attacks && (sq != pos.square<KING>(~us) && (pos.attackers_to(sq, pos.pieces()) & pos.pieces(us))))
- attacks = 0;
- }
- if (!attacks)
- continue;
- }
+ // SEE based pruning for captures and checks (~11 Elo)
+ if (!pos.see_ge(move, Value(-205) * depth))
+ continue;
}
else
{
if (ttCapture)
r++;
- // Decrease reduction for PvNodes based on depth (~2 Elo)
+ // Decrease reduction for PvNodes (~2 Elo)
if (PvNode)
- r -= 1 + (depth < 6);
+ r--;
// Decrease reduction if ttMove has been singularly extended (~1 Elo)
if (singularQuietLMR)
r--;
+
+ // Increase reduction on repetition (~1 Elo)
+ if ( move == (ss-4)->currentMove
+ && pos.has_repeated())
+ r += 2;
// Increase reduction if next ply has a lot of fail high (~5 Elo)
if ((ss+1)->cutoffCnt > 3)
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth - (r > 3), !cutNode);
}
- // For PV nodes only, do a full PV search on the first move or after a fail
- // high (in the latter case search only if value < beta), otherwise let the
- // parent node fail low with value <= alpha and try another move.
- if (PvNode && (moveCount == 1 || (value > alpha && (rootNode || value < beta))))
+ // For PV nodes only, do a full PV search on the first move or after a fail high,
+ // otherwise let the parent node fail low with value <= alpha and try another move.
+ if (PvNode && (moveCount == 1 || value > alpha))
{
(ss+1)->pv = pv;
(ss+1)->pv[0] = MOVE_NONE;
// Bonus for prior countermove that caused the fail low
else if (!priorCapture && prevSq != SQ_NONE)
{
- int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 113 * depth) + ((ss-1)->moveCount > 12);
+ int bonus = (depth > 5) + (PvNode || cutNode) + (bestValue < alpha - 800) + ((ss-1)->moveCount > 12);
update_continuation_histories(ss-1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus);
thisThread->mainHistory[~us][from_to((ss-1)->currentMove)] << stat_bonus(depth) * bonus / 2;
}
if (moveCount > 2)
continue;
- futilityValue = futilityBase + PieceValue[EG][pos.piece_on(to_sq(move))];
+ futilityValue = futilityBase + PieceValue[pos.piece_on(to_sq(move))];
if (futilityValue <= alpha)
{
// RootMoves are already sorted by score in descending order
Value topScore = rootMoves[0].score;
- int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg);
+ int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValue);
int maxScore = -VALUE_INFINITE;
double weakness = 120 - 2 * level;