#include "uci.h"
#include "syzygy/tbprobe.h"
+namespace Stockfish {
+
namespace Search {
LimitsType Limits;
while (true)
{
Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt - searchAgainCounter);
- bestValue = ::search<PV>(rootPos, ss, alpha, beta, adjustedDepth, false);
+ bestValue = Stockfish::search<PV>(rootPos, ss, alpha, beta, adjustedDepth, false);
// Bring the best move to the front. It is critical that sorting
// is done with a stable algorithm because all the values but the
// Step 1. Initialize node
Thread* thisThread = pos.this_thread();
- ss->inCheck = pos.checkers();
- priorCapture = pos.captured_piece();
- Color us = pos.side_to_move();
- moveCount = captureCount = quietCount = ss->moveCount = 0;
- bestValue = -VALUE_INFINITE;
- maxValue = VALUE_INFINITE;
- ss->distanceFromPv = (PvNode ? 0 : ss->distanceFromPv);
+ ss->inCheck = pos.checkers();
+ priorCapture = pos.captured_piece();
+ Color us = pos.side_to_move();
+ moveCount = captureCount = quietCount = ss->moveCount = 0;
+ bestValue = -VALUE_INFINITE;
+ maxValue = VALUE_INFINITE;
// Check for the available remaining time
if (thisThread == Threads.main())
return probCutBeta;
assert(probCutBeta < VALUE_INFINITE);
+
MovePicker mp(pos, ttMove, probCutBeta - ss->staticEval, &captureHistory);
int probCutCount = 0;
bool ttPv = ss->ttPv;
{
Value singularBeta = ttValue - ((formerPv + 4) * depth) / 2;
Depth singularDepth = (depth - 1 + 3 * formerPv) / 2;
+
ss->excludedMove = move;
value = search<NonPV>(pos, ss, singularBeta - 1, singularBeta, singularDepth, cutNode);
ss->excludedMove = MOVE_NONE;
// Step 15. Make the move
pos.do_move(move, st, givesCheck);
- (ss+1)->distanceFromPv = ss->distanceFromPv + moveCount - 1;
-
// Step 16. Late moves reduction / extension (LMR, ~200 Elo)
// We use various heuristics for the sons of a node after the first son has
// been searched. In general we would like to reduce them, but there are many
// Decrease reduction if position is or has been on the PV
// and node is not likely to fail low. (~10 Elo)
- if (ss->ttPv && !likelyFailLow)
+ if ( ss->ttPv
+ && !likelyFailLow)
r -= 2;
// Increase reduction at root and non-PV nodes when the best move does not change frequently
- if ((rootNode || !PvNode) && thisThread->rootDepth > 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
- if (moveCountPruning && !formerPv)
+ if ( moveCountPruning
+ && !formerPv)
r++;
// Decrease reduction if opponent's move count is high (~5 Elo)
if (captureOrPromotion)
{
- // Unless giving check, this capture is likely bad
+ // Increase reduction for non-checking captures likely to be bad
if ( !givesCheck
&& ss->staticEval + PieceValue[EG][pos.captured_piece()] + 210 * depth <= alpha)
r++;
// Decrease reduction for moves that escape a capture. Filter out
// castling moves, because they are coded as "king captures rook" and
- // hence break make_move(). (~2 Elo)
+ // hence break reverse_move() (~2 Elo)
else if ( type_of(move) == NORMAL
&& !pos.see_ge(reverse_move(move)))
r -= 2 + ss->ttPv - (type_of(movedPiece) == PAWN);
r -= ss->statScore / 14790;
}
- // In general we want to cap the LMR depth search at newDepth. But for nodes
- // close to the principal variation the cap is at (newDepth + 1), which will
- // allow these nodes to be searched deeper than the pv (up to 4 plies deeper).
- Depth d = std::clamp(newDepth - r, 1, newDepth + ((ss+1)->distanceFromPv <= 4));
+ // In general we want to cap the LMR depth search at newDepth. But if
+ // reductions are really negative and movecount is low, we allow this move
+ // to be searched deeper than the first move.
+ Depth d = std::clamp(newDepth - r, 1, newDepth + (r < -1 && moveCount <= 5));
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
assert(moveCount || !ss->inCheck || excludedMove || !MoveList<LEGAL>(pos).size());
if (!moveCount)
- bestValue = excludedMove ? alpha
- : ss->inCheck ? mated_in(ss->ply) : VALUE_DRAW;
+ bestValue = excludedMove ? alpha :
+ ss->inCheck ? mated_in(ss->ply)
+ : VALUE_DRAW;
// If there is a move which produces search value greater than alpha we update stats of searched moves
else if (bestMove)
moveCount++;
- // Futility pruning
+ // Futility pruning and moveCount pruning
if ( bestValue > VALUE_TB_LOSS_IN_MAX_PLY
&& !givesCheck
&& futilityBase > -VALUE_KNOWN_WIN
- && !pos.advanced_pawn_push(move))
+ && type_of(move) != PROMOTION)
{
- assert(type_of(move) != EN_PASSANT); // Due to !pos.advanced_pawn_push
- // moveCount pruning
if (moveCount > 2)
continue;
m.tbRank = 0;
}
}
+
+} // namespace Stockfish