if (PvNode && thread.maxPly < ss->ply)
thread.maxPly = ss->ply;
- // Step 1. Initialize node and poll. Polling can abort search
+ // Step 1. Initialize node.
if (!SpNode)
{
ss->currentMove = ss->bestMove = threatMove = (ss+1)->excludedMove = MOVE_NONE;
goto split_point_start;
}
- if (pos.thread() == 0 && ++NodesSincePoll > NodesBetweenPolls)
- {
- NodesSincePoll = 0;
- poll(pos);
- }
-
- // Step 2. Check for aborted search and immediate draw
- if (( StopRequest
- || pos.is_draw<false>()
- || ss->ply > PLY_MAX) && !RootNode)
- return VALUE_DRAW;
-
// Step 3. Mate distance pruning
if (!RootNode)
{
if (pos.pl_move_is_legal(move, ci.pinned))
{
pos.do_move(move, st, ci, pos.move_gives_check(move, ci));
- value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth);
+
+ if (pos.is_draw<false>() || ss->ply + 1 > PLY_MAX)
+ value = VALUE_DRAW;
+ else
+ value = -search<NonPV>(pos, ss+1, -rbeta, -rbeta+1, rdepth);
+
pos.undo_move(move);
if (value >= rbeta)
return value;
// Step 14. Make the move
pos.do_move(move, st, ci, givesCheck);
+ // Step XX. Poll. Check if search should be aborted.
+ if (pos.thread() == 0 && ++NodesSincePoll > NodesBetweenPolls)
+ {
+ NodesSincePoll = 0;
+ poll(pos);
+ }
+
+ // Step XX. Check for aborted search and immediate draw
+ if ( StopRequest
+ || pos.is_draw<false>()
+ || ss->ply + 1 > PLY_MAX)
+ {
+ value = VALUE_DRAW;
+ goto undo;
+ }
+
// Step extra. pv search (only in PV nodes)
// The first move in list is the expected PV
if (isPvMove)
}
// Step 17. Undo move
+undo:
pos.undo_move(move);
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
ss->bestMove = ss->currentMove = MOVE_NONE;
ss->ply = (ss-1)->ply + 1;
- // Check for an instant draw or maximum ply reached
- if (pos.is_draw<true>() || ss->ply > PLY_MAX)
- return VALUE_DRAW;
-
// Decide whether or not to include checks, this fixes also the type of
// TT entry depth that we are going to use. Note that in qsearch we use
// only two types of depth in TT: DEPTH_QS_CHECKS or DEPTH_QS_NO_CHECKS.
// Make and search the move
pos.do_move(move, st, ci, givesCheck);
- value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth-ONE_PLY);
+
+ if (pos.is_draw<true>() || ss->ply+1 > PLY_MAX)
+ value = VALUE_DRAW;
+ else
+ value = -qsearch<NT>(pos, ss+1, -beta, -alpha, depth-ONE_PLY);
+
pos.undo_move(move);
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
Square f1, t1, f2, t2;
Piece p1, p2;
+ Square ksq;
assert(m1 && move_is_ok(m1));
assert(m2 && move_is_ok(m2));
return true;
// Case 5: Discovered check, checking piece is the piece moved in m1
+ ksq = pos.king_square(pos.side_to_move());
if ( piece_is_slider(p1)
- && bit_is_set(squares_between(t1, pos.king_square(pos.side_to_move())), f2)
- && !bit_is_set(squares_between(t1, pos.king_square(pos.side_to_move())), t2))
+ && bit_is_set(squares_between(t1, ksq), f2))
{
- // discovered_check_candidates() works also if the Position's side to
- // move is the opposite of the checking piece.
- Color them = opposite_color(pos.side_to_move());
- Bitboard dcCandidates = pos.discovered_check_candidates(them);
-
- if (bit_is_set(dcCandidates, f2))
+ Bitboard occ = pos.occupied_squares();
+ clear_bit(&occ, f2);
+ if (bit_is_set(pos.attacks_from(p1, t1, occ), ksq))
return true;
}
return false;
while ( (tte = TT.probe(pos.get_key())) != NULL
&& tte->move() != MOVE_NONE
&& pos.move_is_pl(tte->move())
- && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces(pos.side_to_move()))
+ && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
&& ply < PLY_MAX
&& (!pos.is_draw<false>() || ply < 2))
{