/// Search::perft() is our utility to verify move generation. All the leaf nodes
/// up to the given depth are generated and counted and the sum returned.
-static size_t perft(Position& pos, Depth depth) {
+static uint64_t perft(Position& pos, Depth depth) {
StateInfo st;
- size_t cnt = 0;
+ uint64_t cnt = 0;
CheckInfo ci(pos);
const bool leaf = depth == 2 * ONE_PLY;
return cnt;
}
-size_t Search::perft(Position& pos, Depth depth) {
+uint64_t Search::perft(Position& pos, Depth depth) {
return depth > ONE_PLY ? ::perft(pos, depth) : MoveList<LEGAL>(pos).size();
}
// Step 6. Razoring (skipped when in check)
if ( !PvNode
&& depth < 4 * ONE_PLY
- && eval + razor_margin(depth) < beta
+ && eval + razor_margin(depth) <= alpha
&& ttMove == MOVE_NONE
&& abs(beta) < VALUE_MATE_IN_MAX_PLY
&& !pos.pawn_on_7th(pos.side_to_move()))
{
- Value rbeta = beta - razor_margin(depth);
- Value v = qsearch<NonPV, false>(pos, ss, rbeta-1, rbeta, DEPTH_ZERO);
- if (v < rbeta)
- // Logically we should return (v + razor_margin(depth)), but
- // surprisingly this performed slightly weaker in tests.
+ Value ralpha = alpha - razor_margin(depth);
+ Value v = qsearch<NonPV, false>(pos, ss, ralpha, ralpha+1, DEPTH_ZERO);
+ if (v <= ralpha)
return v;
}
{
ss->currentMove = MOVE_NULL;
- // Null move dynamic reduction based on depth
- Depth R = 3 * ONE_PLY + depth / 4;
+ assert(eval - beta >= 0);
- // Null move dynamic reduction based on value
- if (eval - PawnValueMg > beta)
- R += ONE_PLY;
+ // Null move dynamic reduction based on depth and value
+ Depth R = 3 * ONE_PLY
+ + depth / 4
+ + int(eval - beta) / PawnValueMg * ONE_PLY;
pos.do_null_move(st);
(ss+1)->skipNullMove = true;
- nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -alpha, DEPTH_ZERO)
- : - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R, !cutNode);
+ nullValue = depth-R < ONE_PLY ? -qsearch<NonPV, false>(pos, ss+1, -beta, -beta+1, DEPTH_ZERO)
+ : - search<NonPV>(pos, ss+1, -beta, -beta+1, depth-R, !cutNode);
(ss+1)->skipNullMove = false;
pos.undo_null_move();
// Do verification search at high depths
ss->skipNullMove = true;
- Value v = search<NonPV>(pos, ss, alpha, beta, depth-R, false);
+ Value v = depth-R < ONE_PLY ? qsearch<NonPV, false>(pos, ss, beta-1, beta, DEPTH_ZERO)
+ : search<NonPV>(pos, ss, beta-1, beta, depth-R, false);
ss->skipNullMove = false;
if (v >= beta)
ext = DEPTH_ZERO;
captureOrPromotion = pos.capture_or_promotion(move);
- givesCheck = pos.gives_check(move, ci);
+
+ givesCheck = type_of(move) == NORMAL && !ci.dcCandidates
+ ? ci.checkSq[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
+ : pos.gives_check(move, ci);
+
dangerous = givesCheck
|| type_of(move) != NORMAL
|| pos.advanced_pawn_push(move);
{
assert(is_ok(move));
- givesCheck = pos.gives_check(move, ci);
+ givesCheck = type_of(move) == NORMAL && !ci.dcCandidates
+ ? ci.checkSq[type_of(pos.piece_on(from_sq(move)))] & to_sq(move)
+ : pos.gives_check(move, ci);
// Futility pruning
if ( !PvNode