+
+ // Blocking check evasions are possible only if the checking piece is
+ // a slider
+ if (checkers & pos.sliders())
+ {
+ Bitboard blockSquares = squares_between(checksq, ksq);
+
+ assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB);
+
+ // Pawn moves. Because a blocking evasion can never be a capture, we
+ // only generate pawn pushes. As so often, the code for pawns is a bit
+ // ugly, and uses separate clauses for white and black pawns. :-(
+ if (us == WHITE)
+ {
+ // Find non-pinned pawns
+ b1 = pos.pawns(WHITE) & not_pinned;
+
+ // Single pawn pushes. We don't have to AND with empty squares here,
+ // because the blocking squares will always be empty.
+ b2 = (b1 << 8) & blockSquares;
+ while(b2)
+ {
+ to = pop_1st_bit(&b2);
+
+ assert(pos.piece_on(to) == EMPTY);
+
+ if (square_rank(to) == RANK_8)
+ {
+ mlist[n++].move = make_promotion_move(to - DELTA_N, to, QUEEN);
+ mlist[n++].move = make_promotion_move(to - DELTA_N, to, ROOK);
+ mlist[n++].move = make_promotion_move(to - DELTA_N, to, BISHOP);
+ mlist[n++].move = make_promotion_move(to - DELTA_N, to, KNIGHT);
+ } else
+ mlist[n++].move = make_move(to - DELTA_N, to);
+ }
+
+ // Double pawn pushes
+ b2 = (((b1 << 8) & pos.empty_squares() & Rank3BB) << 8) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+
+ assert(pos.piece_on(to) == EMPTY);
+ assert(square_rank(to) == RANK_4);
+
+ mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to);
+ }
+ } else { // (us == BLACK)
+
+ // Find non-pinned pawns
+ b1 = pos.pawns(BLACK) & not_pinned;
+
+ // Single pawn pushes. We don't have to AND with empty squares here,
+ // because the blocking squares will always be empty.
+ b2 = (b1 >> 8) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+
+ assert(pos.piece_on(to) == EMPTY);
+
+ if (square_rank(to) == RANK_1)
+ {
+ mlist[n++].move = make_promotion_move(to - DELTA_S, to, QUEEN);
+ mlist[n++].move = make_promotion_move(to - DELTA_S, to, ROOK);
+ mlist[n++].move = make_promotion_move(to - DELTA_S, to, BISHOP);
+ mlist[n++].move = make_promotion_move(to - DELTA_S, to, KNIGHT);
+ } else
+ mlist[n++].move = make_move(to - DELTA_S, to);
+ }
+
+ // Double pawn pushes
+ b2 = (((b1 >> 8) & pos.empty_squares() & Rank6BB) >> 8) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+
+ assert(pos.piece_on(to) == EMPTY);
+ assert(square_rank(to) == RANK_5);
+
+ mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to);
+ }
+ }
+
+ // Knight moves
+ b1 = pos.knights(us) & not_pinned;
+ while (b1)
+ {
+ from = pop_1st_bit(&b1);
+ b2 = pos.knight_attacks(from) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+ mlist[n++].move = make_move(from, to);
+ }
+ }
+
+ // Bishop moves
+ b1 = pos.bishops(us) & not_pinned;
+ while (b1)
+ {
+ from = pop_1st_bit(&b1);
+ b2 = pos.bishop_attacks(from) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+ mlist[n++].move = make_move(from, to);
+ }
+ }
+
+ // Rook moves
+ b1 = pos.rooks(us) & not_pinned;
+ while (b1)
+ {
+ from = pop_1st_bit(&b1);
+ b2 = pos.rook_attacks(from) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+ mlist[n++].move = make_move(from, to);
+ }
+ }
+
+ // Queen moves
+ b1 = pos.queens(us) & not_pinned;
+ while (b1)
+ {
+ from = pop_1st_bit(&b1);
+ b2 = pos.queen_attacks(from) & blockSquares;
+ while (b2)
+ {
+ to = pop_1st_bit(&b2);
+ mlist[n++].move = make_move(from, to);
+ }
+ }