2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2008 Tord Romstad (Glaurung author) Copyright (C) 2008 Marco Costalba
5 Stockfish is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 Stockfish is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 // Simple macro to wrap a very common while loop, no facny, no flexibility,
29 // hardcoded list name 'mlist' and from square 'from'.
30 #define SERIALIZE_MOVES(b) while (b) (*mlist++).move = make_move(from, pop_1st_bit(&b))
33 //// Local definitions
49 bool castling_is_check(const Position
&, CastlingSide
);
52 template<CastlingSide Side
>
53 MoveStack
* generate_castle_moves(const Position
& pos
, MoveStack
* mlist
);
55 template<Color Us
, Rank
, Bitboard
, SquareDelta
>
56 MoveStack
* generate_pawn_blocking_evasions(const Position
&, Bitboard
, Bitboard
, MoveStack
*);
58 template<Color
, Color
, Bitboard
, SquareDelta
, SquareDelta
, SquareDelta
>
59 MoveStack
* generate_pawn_captures(const Position
& pos
, MoveStack
* mlist
);
61 template<Color
, Color
, Bitboard
, Bitboard
, SquareDelta
, SquareDelta
, SquareDelta
>
62 MoveStack
* generate_pawn_noncaptures(const Position
& pos
, MoveStack
* mlist
);
64 template<Color
, Color
, Bitboard
, Bitboard
, SquareDelta
>
65 MoveStack
* generate_pawn_checks(const Position
&, Bitboard
, Square
, MoveStack
*);
67 template<Color Us
, SquareDelta Direction
>
68 inline Bitboard
move_pawns(Bitboard p
) {
70 if (Direction
== DELTA_N
)
71 return Us
== WHITE
? p
<< 8 : p
>> 8;
72 else if (Direction
== DELTA_NE
)
73 return Us
== WHITE
? p
<< 9 : p
>> 7;
74 else if (Direction
== DELTA_NW
)
75 return Us
== WHITE
? p
<< 7 : p
>> 9;
80 // Template generate_piece_checks() with specializations
82 MoveStack
* generate_piece_checks(const Position
&, MoveStack
*, Color
, Bitboard
, Square
);
85 inline MoveStack
* generate_piece_checks
<PAWN
>(const Position
& p
, MoveStack
* m
, Color us
, Bitboard dc
, Square ksq
) {
88 return generate_pawn_checks
<WHITE
, BLACK
, Rank8BB
, Rank3BB
, DELTA_N
>(p
, dc
, ksq
, m
);
90 return generate_pawn_checks
<BLACK
, WHITE
, Rank1BB
, Rank6BB
, DELTA_S
>(p
, dc
, ksq
, m
);
94 // Template generate_piece_moves() with specializations and overloads
96 MoveStack
* generate_piece_moves(const Position
&, MoveStack
*, Color us
, Bitboard
);
99 MoveStack
* generate_piece_moves
<KING
>(const Position
&, MoveStack
*, Color
, Bitboard
);
101 template<PieceType Piece
, MoveType Type
>
102 inline MoveStack
* generate_piece_moves(const Position
& p
, MoveStack
* m
, Color us
) {
104 assert(Piece
== PAWN
);
107 return (us
== WHITE
? generate_pawn_captures
<WHITE
, BLACK
, Rank8BB
, DELTA_NE
, DELTA_NW
, DELTA_N
>(p
, m
)
108 : generate_pawn_captures
<BLACK
, WHITE
, Rank1BB
, DELTA_SE
, DELTA_SW
, DELTA_S
>(p
, m
));
110 return (us
== WHITE
? generate_pawn_noncaptures
<WHITE
, BLACK
, Rank8BB
, Rank3BB
, DELTA_NE
, DELTA_NW
, DELTA_N
>(p
, m
)
111 : generate_pawn_noncaptures
<BLACK
, WHITE
, Rank1BB
, Rank6BB
, DELTA_SE
, DELTA_SW
, DELTA_S
>(p
, m
));
115 MoveStack
* generate_piece_moves(const Position
&, MoveStack
*, Color us
, Bitboard
, Bitboard
);
118 inline MoveStack
* generate_piece_moves
<PAWN
>(const Position
& p
, MoveStack
* m
,
119 Color us
, Bitboard t
, Bitboard pnd
) {
121 return generate_pawn_blocking_evasions
<WHITE
, RANK_8
, Rank3BB
, DELTA_N
>(p
, pnd
, t
, m
);
123 return generate_pawn_blocking_evasions
<BLACK
, RANK_1
, Rank6BB
, DELTA_S
>(p
, pnd
, t
, m
);
133 /// generate_captures generates() all pseudo-legal captures and queen
134 /// promotions. The return value is the number of moves generated.
136 int generate_captures(const Position
& pos
, MoveStack
* mlist
) {
139 assert(!pos
.is_check());
141 Color us
= pos
.side_to_move();
142 Bitboard target
= pos
.pieces_of_color(opposite_color(us
));
143 MoveStack
* mlist_start
= mlist
;
145 mlist
= generate_piece_moves
<QUEEN
>(pos
, mlist
, us
, target
);
146 mlist
= generate_piece_moves
<ROOK
>(pos
, mlist
, us
, target
);
147 mlist
= generate_piece_moves
<BISHOP
>(pos
, mlist
, us
, target
);
148 mlist
= generate_piece_moves
<KNIGHT
>(pos
, mlist
, us
, target
);
149 mlist
= generate_piece_moves
<PAWN
, CAPTURE
>(pos
, mlist
, us
);
150 mlist
= generate_piece_moves
<KING
>(pos
, mlist
, us
, target
);
151 return int(mlist
- mlist_start
);
155 /// generate_noncaptures() generates all pseudo-legal non-captures and
156 /// underpromotions. The return value is the number of moves generated.
158 int generate_noncaptures(const Position
& pos
, MoveStack
* mlist
) {
161 assert(!pos
.is_check());
163 Color us
= pos
.side_to_move();
164 Bitboard target
= pos
.empty_squares();
165 MoveStack
* mlist_start
= mlist
;
167 mlist
= generate_piece_moves
<PAWN
, NON_CAPTURE
>(pos
, mlist
, us
);
168 mlist
= generate_piece_moves
<KNIGHT
>(pos
, mlist
, us
, target
);
169 mlist
= generate_piece_moves
<BISHOP
>(pos
, mlist
, us
, target
);
170 mlist
= generate_piece_moves
<ROOK
>(pos
, mlist
, us
, target
);
171 mlist
= generate_piece_moves
<QUEEN
>(pos
, mlist
, us
, target
);
172 mlist
= generate_piece_moves
<KING
>(pos
, mlist
, us
, target
);
173 mlist
= generate_castle_moves
<KING_SIDE
>(pos
, mlist
);
174 mlist
= generate_castle_moves
<QUEEN_SIDE
>(pos
, mlist
);
175 return int(mlist
- mlist_start
);
179 /// generate_non_capture_checks() generates all pseudo-legal non-capturing,
180 /// non-promoting checks. It returns the number of generated moves.
182 int generate_non_capture_checks(const Position
& pos
, MoveStack
* mlist
, Bitboard dc
) {
185 assert(!pos
.is_check());
187 Color us
= pos
.side_to_move();
188 Square ksq
= pos
.king_square(opposite_color(us
));
189 MoveStack
* mlist_start
= mlist
;
191 assert(pos
.piece_on(ksq
) == piece_of_color_and_type(opposite_color(us
), KING
));
194 mlist
= generate_piece_checks
<PAWN
>(pos
, mlist
, us
, dc
, ksq
);
195 mlist
= generate_piece_checks
<KNIGHT
>(pos
, mlist
, us
, dc
, ksq
);
196 mlist
= generate_piece_checks
<BISHOP
>(pos
, mlist
, us
, dc
, ksq
);
197 mlist
= generate_piece_checks
<ROOK
>(pos
, mlist
, us
, dc
, ksq
);
198 mlist
= generate_piece_checks
<QUEEN
>(pos
, mlist
, us
, dc
, ksq
);
199 mlist
= generate_piece_checks
<KING
>(pos
, mlist
, us
, dc
, ksq
);
201 // Castling moves that give check. Very rare but nice to have!
202 if ( pos
.can_castle_queenside(us
)
203 && (square_rank(ksq
) == square_rank(pos
.king_square(us
)) || square_file(ksq
) == FILE_D
)
204 && castling_is_check(pos
, QUEEN_SIDE
))
205 mlist
= generate_castle_moves
<QUEEN_SIDE
>(pos
, mlist
);
207 if ( pos
.can_castle_kingside(us
)
208 && (square_rank(ksq
) == square_rank(pos
.king_square(us
)) || square_file(ksq
) == FILE_F
)
209 && castling_is_check(pos
, KING_SIDE
))
210 mlist
= generate_castle_moves
<KING_SIDE
>(pos
, mlist
);
212 return int(mlist
- mlist_start
);
216 /// generate_evasions() generates all check evasions when the side to move is
217 /// in check. Unlike the other move generation functions, this one generates
218 /// only legal moves. It returns the number of generated moves.
220 int generate_evasions(const Position
& pos
, MoveStack
* mlist
, Bitboard pinned
) {
223 assert(pos
.is_check());
226 Color us
= pos
.side_to_move();
227 Color them
= opposite_color(us
);
228 Square ksq
= pos
.king_square(us
);
229 MoveStack
* mlist_start
= mlist
;
231 assert(pos
.piece_on(ksq
) == piece_of_color_and_type(us
, KING
));
233 // The bitboard of occupied pieces without our king
234 Bitboard b_noKing
= pos
.occupied_squares();
235 clear_bit(&b_noKing
, ksq
);
237 // Find squares attacked by slider checkers, we will
238 // remove them from king evasions set so to avoid a couple
239 // of cycles in the slow king evasions legality check loop
240 // and to be able to use square_is_attacked().
241 Bitboard checkers
= pos
.checkers();
242 Bitboard checkersAttacks
= EmptyBoardBB
;
243 Bitboard b
= checkers
& (pos
.queens() | pos
.bishops());
246 from
= pop_1st_bit(&b
);
247 checkersAttacks
|= bishop_attacks_bb(from
, b_noKing
);
250 b
= checkers
& (pos
.queens() | pos
.rooks());
253 from
= pop_1st_bit(&b
);
254 checkersAttacks
|= rook_attacks_bb(from
, b_noKing
);
257 // Generate evasions for king
258 Bitboard b1
= pos
.piece_attacks
<KING
>(ksq
) & ~pos
.pieces_of_color(us
) & ~checkersAttacks
;
261 to
= pop_1st_bit(&b1
);
262 // Note that we can use square_is_attacked() only because we
263 // have already removed slider checkers.
264 if (!pos
.square_is_attacked(to
, them
))
265 (*mlist
++).move
= make_move(ksq
, to
);
268 // Generate evasions for other pieces only if not double check. We use a
269 // simple bit twiddling hack here rather than calling count_1s in order to
270 // save some time (we know that pos.checkers() has at most two nonzero bits).
271 if (!(checkers
& (checkers
- 1))) // Only one bit set?
273 Square checksq
= first_1(checkers
);
275 assert(pos
.color_of_piece_on(checksq
) == them
);
277 // Generate captures of the checking piece
280 b1
= pos
.pawn_attacks(them
, checksq
) & pos
.pawns(us
) & ~pinned
;
283 from
= pop_1st_bit(&b1
);
284 if (relative_rank(us
, checksq
) == RANK_8
)
286 (*mlist
++).move
= make_promotion_move(from
, checksq
, QUEEN
);
287 (*mlist
++).move
= make_promotion_move(from
, checksq
, ROOK
);
288 (*mlist
++).move
= make_promotion_move(from
, checksq
, BISHOP
);
289 (*mlist
++).move
= make_promotion_move(from
, checksq
, KNIGHT
);
291 (*mlist
++).move
= make_move(from
, checksq
);
295 b1
= ( (pos
.piece_attacks
<KNIGHT
>(checksq
) & pos
.knights(us
))
296 | (pos
.piece_attacks
<BISHOP
>(checksq
) & pos
.bishops_and_queens(us
))
297 | (pos
.piece_attacks
<ROOK
>(checksq
) & pos
.rooks_and_queens(us
)) ) & ~pinned
;
301 from
= pop_1st_bit(&b1
);
302 (*mlist
++).move
= make_move(from
, checksq
);
305 // Blocking check evasions are possible only if the checking piece is
307 if (checkers
& pos
.sliders())
309 Bitboard blockSquares
= squares_between(checksq
, ksq
);
311 assert((pos
.occupied_squares() & blockSquares
) == EmptyBoardBB
);
313 if (blockSquares
!= EmptyBoardBB
)
315 mlist
= generate_piece_moves
<PAWN
>(pos
, mlist
, us
, blockSquares
, pinned
);
316 mlist
= generate_piece_moves
<KNIGHT
>(pos
, mlist
, us
, blockSquares
, pinned
);
317 mlist
= generate_piece_moves
<BISHOP
>(pos
, mlist
, us
, blockSquares
, pinned
);
318 mlist
= generate_piece_moves
<ROOK
>(pos
, mlist
, us
, blockSquares
, pinned
);
319 mlist
= generate_piece_moves
<QUEEN
>(pos
, mlist
, us
, blockSquares
, pinned
);
323 // Finally, the special case of en passant captures. An en passant
324 // capture can only be a check evasion if the check is not a discovered
325 // check. If pos.ep_square() is set, the last move made must have been
326 // a double pawn push. If, furthermore, the checking piece is a pawn,
327 // an en passant check evasion may be possible.
328 if (pos
.ep_square() != SQ_NONE
&& (checkers
& pos
.pawns(them
)))
330 to
= pos
.ep_square();
331 b1
= pos
.pawn_attacks(them
, to
) & pos
.pawns(us
);
333 // The checking pawn cannot be a discovered (bishop) check candidate
334 // otherwise we were in check also before last double push move.
335 assert(!bit_is_set(pos
.discovered_check_candidates(them
), checksq
));
336 assert(count_1s(b1
) == 1 || count_1s(b1
) == 2);
341 from
= pop_1st_bit(&b1
);
342 // Move is always legal because checking pawn is not a discovered
343 // check candidate and our capturing pawn has been already tested
344 // against pinned pieces.
345 (*mlist
++).move
= make_ep_move(from
, to
);
349 return int(mlist
- mlist_start
);
353 /// generate_legal_moves() computes a complete list of legal moves in the
354 /// current position. This function is not very fast, and should be used
355 /// only in situations where performance is unimportant. It wouldn't be
356 /// very hard to write an efficient legal move generator, but for the moment
357 /// we don't need it.
359 int generate_legal_moves(const Position
& pos
, MoveStack
* mlist
) {
363 Bitboard pinned
= pos
.pinned_pieces(pos
.side_to_move());
366 return generate_evasions(pos
, mlist
, pinned
);
368 // Generate pseudo-legal moves
369 int n
= generate_captures(pos
, mlist
);
370 n
+= generate_noncaptures(pos
, mlist
+ n
);
372 // Remove illegal moves from the list
373 for (int i
= 0; i
< n
; i
++)
374 if (!pos
.pl_move_is_legal(mlist
[i
].move
, pinned
))
375 mlist
[i
--].move
= mlist
[--n
].move
;
381 /// move_is_legal() takes a position and a (not necessarily pseudo-legal)
382 /// move and a pinned pieces bitboard as input, and tests whether
383 /// the move is legal. If the move is legal, the move itself is
384 /// returned. If not, the function returns false. This function must
385 /// only be used when the side to move is not in check.
387 bool move_is_legal(const Position
& pos
, const Move m
, Bitboard pinned
) {
390 assert(!pos
.is_check());
391 assert(move_is_ok(m
));
392 assert(pinned
== pos
.pinned_pieces(pos
.side_to_move()));
394 Color us
= pos
.side_to_move();
395 Color them
= opposite_color(us
);
396 Square from
= move_from(m
);
397 Piece pc
= pos
.piece_on(from
);
399 // If the from square is not occupied by a piece belonging to the side to
400 // move, the move is obviously not legal.
401 if (color_of_piece(pc
) != us
)
404 Square to
= move_to(m
);
409 // The piece must be a pawn and destination square must be the
410 // en passant square.
411 if ( type_of_piece(pc
) != PAWN
412 || to
!= pos
.ep_square())
415 assert(pos
.square_is_empty(to
));
416 assert(pos
.piece_on(to
- pawn_push(us
)) == piece_of_color_and_type(them
, PAWN
));
418 // The move is pseudo-legal, check if it is also legal
419 return pos
.pl_move_is_legal(m
, pinned
);
423 if (move_is_short_castle(m
))
425 // The piece must be a king and side to move must still have
426 // the right to castle kingside.
427 if ( type_of_piece(pc
) != KING
428 ||!pos
.can_castle_kingside(us
))
431 assert(from
== pos
.king_square(us
));
432 assert(to
== pos
.initial_kr_square(us
));
433 assert(pos
.piece_on(to
) == piece_of_color_and_type(us
, ROOK
));
435 Square g1
= relative_square(us
, SQ_G1
);
436 Square f1
= relative_square(us
, SQ_F1
);
438 bool illegal
= false;
440 // Check if any of the squares between king and rook
441 // is occupied or under attack.
442 for (s
= Min(from
, g1
); s
<= Max(from
, g1
); s
++)
443 if ( (s
!= from
&& s
!= to
&& !pos
.square_is_empty(s
))
444 || pos
.square_is_attacked(s
, them
))
447 // Check if any of the squares between king and rook
449 for (s
= Min(to
, f1
); s
<= Max(to
, f1
); s
++)
450 if (s
!= from
&& s
!= to
&& !pos
.square_is_empty(s
))
456 if (move_is_long_castle(m
))
458 // The piece must be a king and side to move must still have
459 // the right to castle kingside.
460 if ( type_of_piece(pc
) != KING
461 ||!pos
.can_castle_queenside(us
))
464 assert(from
== pos
.king_square(us
));
465 assert(to
== pos
.initial_qr_square(us
));
466 assert(pos
.piece_on(to
) == piece_of_color_and_type(us
, ROOK
));
468 Square c1
= relative_square(us
, SQ_C1
);
469 Square d1
= relative_square(us
, SQ_D1
);
471 bool illegal
= false;
473 for (s
= Min(from
, c1
); s
<= Max(from
, c1
); s
++)
474 if( (s
!= from
&& s
!= to
&& !pos
.square_is_empty(s
))
475 || pos
.square_is_attacked(s
, them
))
478 for (s
= Min(to
, d1
); s
<= Max(to
, d1
); s
++)
479 if(s
!= from
&& s
!= to
&& !pos
.square_is_empty(s
))
482 if ( square_file(to
) == FILE_B
483 && ( pos
.piece_on(to
+ DELTA_W
) == piece_of_color_and_type(them
, ROOK
)
484 || pos
.piece_on(to
+ DELTA_W
) == piece_of_color_and_type(them
, QUEEN
)))
492 // The destination square cannot be occupied by a friendly piece
493 if (pos
.color_of_piece_on(to
) == us
)
496 // Proceed according to the type of the moving piece.
497 if (type_of_piece(pc
) == PAWN
)
499 // Move direction must be compatible with pawn color
500 int direction
= to
- from
;
501 if ((us
== WHITE
) != (direction
> 0))
504 // If the destination square is on the 8/1th rank, the move must
506 if ( ( (square_rank(to
) == RANK_8
&& us
== WHITE
)
507 ||(square_rank(to
) == RANK_1
&& us
!= WHITE
))
508 && !move_promotion(m
))
511 // Proceed according to the square delta between the source and
512 // destionation squares.
519 // Capture. The destination square must be occupied by an enemy
520 // piece (en passant captures was handled earlier).
521 if (pos
.color_of_piece_on(to
) != them
)
527 // Pawn push. The destination square must be empty.
528 if (!pos
.square_is_empty(to
))
533 // Double white pawn push. The destination square must be on the fourth
534 // rank, and both the destination square and the square between the
535 // source and destination squares must be empty.
536 if ( square_rank(to
) != RANK_4
537 || !pos
.square_is_empty(to
)
538 || !pos
.square_is_empty(from
+ DELTA_N
))
543 // Double black pawn push. The destination square must be on the fifth
544 // rank, and both the destination square and the square between the
545 // source and destination squares must be empty.
546 if ( square_rank(to
) != RANK_5
547 || !pos
.square_is_empty(to
)
548 || !pos
.square_is_empty(from
+ DELTA_S
))
555 // The move is pseudo-legal, check if it is also legal
556 return pos
.pl_move_is_legal(m
, pinned
);
559 // Luckly we can handle all the other pieces in one go
560 return ( pos
.piece_attacks_square(pos
.piece_on(from
), from
, to
)
561 && pos
.pl_move_is_legal(m
, pinned
)
562 && !move_promotion(m
));
568 template<PieceType Piece
>
569 MoveStack
* generate_piece_moves(const Position
& pos
, MoveStack
* mlist
, Color us
, Bitboard target
) {
574 for (int i
= 0, e
= pos
.piece_count(us
, Piece
); i
< e
; i
++)
576 from
= pos
.piece_list(us
, Piece
, i
);
577 b
= pos
.piece_attacks
<Piece
>(from
) & target
;
583 template<PieceType Piece
>
584 MoveStack
* generate_piece_moves(const Position
& pos
, MoveStack
* mlist
,
585 Color us
, Bitboard target
, Bitboard pinned
) {
589 for (int i
= 0, e
= pos
.piece_count(us
, Piece
); i
< e
; i
++)
591 from
= pos
.piece_list(us
, Piece
, i
);
592 if (pinned
&& bit_is_set(pinned
, from
))
595 b
= pos
.piece_attacks
<Piece
>(from
) & target
;
602 MoveStack
* generate_piece_moves
<KING
>(const Position
& pos
, MoveStack
* mlist
, Color us
, Bitboard target
) {
605 Square from
= pos
.king_square(us
);
607 b
= pos
.piece_attacks
<KING
>(from
) & target
;
612 template<Color Us
, Color Them
, Bitboard TRank8BB
, SquareDelta TDELTA_NE
,
613 SquareDelta TDELTA_NW
, SquareDelta TDELTA_N
615 MoveStack
* generate_pawn_captures(const Position
& pos
, MoveStack
* mlist
) {
618 Bitboard pawns
= pos
.pawns(Us
);
619 Bitboard enemyPieces
= pos
.pieces_of_color(Them
);
621 // Captures in the a1-h8 (a8-h1 for black) direction
622 Bitboard b1
= move_pawns
<Us
, DELTA_NE
>(pawns
) & ~FileABB
& enemyPieces
;
624 // Capturing promotions
625 Bitboard b2
= b1
& TRank8BB
;
628 to
= pop_1st_bit(&b2
);
629 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NE
, to
, QUEEN
);
632 // Capturing non-promotions
636 to
= pop_1st_bit(&b2
);
637 (*mlist
++).move
= make_move(to
- TDELTA_NE
, to
);
640 // Captures in the h1-a8 (h8-a1 for black) direction
641 b1
= move_pawns
<Us
, DELTA_NW
>(pawns
) & ~FileHBB
& enemyPieces
;
643 // Capturing promotions
647 to
= pop_1st_bit(&b2
);
648 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NW
, to
, QUEEN
);
651 // Capturing non-promotions
655 to
= pop_1st_bit(&b2
);
656 (*mlist
++).move
= make_move(to
- TDELTA_NW
, to
);
659 // Non-capturing promotions
660 b1
= move_pawns
<Us
, DELTA_N
>(pawns
) & pos
.empty_squares() & TRank8BB
;
663 to
= pop_1st_bit(&b1
);
664 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, QUEEN
);
667 // En passant captures
668 if (pos
.ep_square() != SQ_NONE
)
670 assert(Us
!= WHITE
|| square_rank(pos
.ep_square()) == RANK_6
);
671 assert(Us
!= BLACK
|| square_rank(pos
.ep_square()) == RANK_3
);
673 b1
= pawns
& pos
.pawn_attacks(Them
, pos
.ep_square());
674 assert(b1
!= EmptyBoardBB
);
678 to
= pop_1st_bit(&b1
);
679 (*mlist
++).move
= make_ep_move(to
, pos
.ep_square());
685 template<Color Us
, Color Them
, Bitboard TRank8BB
, Bitboard TRank3BB
,
686 SquareDelta TDELTA_NE
, SquareDelta TDELTA_NW
, SquareDelta TDELTA_N
688 MoveStack
* generate_pawn_noncaptures(const Position
& pos
, MoveStack
* mlist
) {
690 Bitboard pawns
= pos
.pawns(Us
);
691 Bitboard enemyPieces
= pos
.pieces_of_color(Them
);
692 Bitboard emptySquares
= pos
.empty_squares();
696 // Underpromotion captures in the a1-h8 (a8-h1 for black) direction
697 b1
= move_pawns
<Us
, DELTA_NE
>(pawns
) & ~FileABB
& enemyPieces
& TRank8BB
;
700 to
= pop_1st_bit(&b1
);
701 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NE
, to
, ROOK
);
702 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NE
, to
, BISHOP
);
703 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NE
, to
, KNIGHT
);
706 // Underpromotion captures in the h1-a8 (h8-a1 for black) direction
707 b1
= move_pawns
<Us
, DELTA_NW
>(pawns
) & ~FileHBB
& enemyPieces
& TRank8BB
;
710 to
= pop_1st_bit(&b1
);
711 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NW
, to
, ROOK
);
712 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NW
, to
, BISHOP
);
713 (*mlist
++).move
= make_promotion_move(to
- TDELTA_NW
, to
, KNIGHT
);
716 // Single pawn pushes
717 b1
= move_pawns
<Us
, DELTA_N
>(pawns
) & emptySquares
;
721 to
= pop_1st_bit(&b2
);
722 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, ROOK
);
723 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, BISHOP
);
724 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, KNIGHT
);
729 to
= pop_1st_bit(&b2
);
730 (*mlist
++).move
= make_move(to
- TDELTA_N
, to
);
733 // Double pawn pushes
734 b2
= move_pawns
<Us
, DELTA_N
>(b1
& TRank3BB
) & emptySquares
;
737 to
= pop_1st_bit(&b2
);
738 (*mlist
++).move
= make_move(to
- TDELTA_N
- TDELTA_N
, to
);
744 template<Color Us
, Color Them
, Bitboard TRank8BB
, Bitboard TRank3BB
, SquareDelta TDELTA_N
>
745 MoveStack
* generate_pawn_checks(const Position
& pos
, Bitboard dc
, Square ksq
, MoveStack
* mlist
)
747 // Find all friendly pawns not on the enemy king's file
749 Bitboard empty
= pos
.empty_squares();
751 if (dc
!= EmptyBoardBB
)
753 // Pawn moves which gives discovered check. This is possible only if the
754 // pawn is not on the same file as the enemy king, because we don't
755 // generate captures.
756 b1
= pos
.pawns(Us
) & ~file_bb(ksq
);
758 // Discovered checks, single pawn pushes, no promotions
759 b2
= b3
= move_pawns
<Us
, DELTA_N
>(b1
& dc
) & empty
& ~TRank8BB
;
762 Square to
= pop_1st_bit(&b3
);
763 (*mlist
++).move
= make_move(to
- TDELTA_N
, to
);
766 // Discovered checks, double pawn pushes
767 b3
= move_pawns
<Us
, DELTA_N
>(b2
& TRank3BB
) & empty
;
770 Square to
= pop_1st_bit(&b3
);
771 (*mlist
++).move
= make_move(to
- TDELTA_N
- TDELTA_N
, to
);
775 // Direct checks. These are possible only for pawns on neighboring files
776 // of the enemy king.
777 b1
= pos
.pawns(Us
) & neighboring_files_bb(ksq
) & ~dc
;
779 // Direct checks, single pawn pushes
780 b2
= move_pawns
<Us
, DELTA_N
>(b1
) & empty
;
781 b3
= b2
& pos
.pawn_attacks(Them
, ksq
);
784 Square to
= pop_1st_bit(&b3
);
785 (*mlist
++).move
= make_move(to
- TDELTA_N
, to
);
788 // Direct checks, double pawn pushes
789 b3
= move_pawns
<Us
, DELTA_N
>(b2
& TRank3BB
) & empty
& pos
.pawn_attacks(Them
, ksq
);
792 Square to
= pop_1st_bit(&b3
);
793 (*mlist
++).move
= make_move(to
- TDELTA_N
- TDELTA_N
, to
);
798 template<PieceType Piece
>
799 MoveStack
* generate_piece_checks(const Position
& pos
, MoveStack
* mlist
, Color us
,
800 Bitboard dc
, Square ksq
) {
802 Bitboard target
= pos
.pieces_of_color_and_type(us
, Piece
);
805 Bitboard b
= target
& dc
;
808 Square from
= pop_1st_bit(&b
);
809 Bitboard bb
= pos
.piece_attacks
<Piece
>(from
) & pos
.empty_squares();
811 bb
&= ~QueenPseudoAttacks
[ksq
];
818 if (Piece
== KING
|| !b
)
821 Bitboard checkSqs
= pos
.piece_attacks
<Piece
>(ksq
) & pos
.empty_squares();
827 Square from
= pop_1st_bit(&b
);
828 if ( (Piece
== QUEEN
&& !(QueenPseudoAttacks
[from
] & checkSqs
))
829 || (Piece
== ROOK
&& !(RookPseudoAttacks
[from
] & checkSqs
))
830 || (Piece
== BISHOP
&& !(BishopPseudoAttacks
[from
] & checkSqs
)))
833 Bitboard bb
= pos
.piece_attacks
<Piece
>(from
) & checkSqs
;
839 template<Color Us
, Rank TRANK_8
, Bitboard TRank3BB
, SquareDelta TDELTA_N
>
840 MoveStack
* generate_pawn_blocking_evasions(const Position
& pos
, Bitboard pinned
,
841 Bitboard blockSquares
, MoveStack
* mlist
) {
844 // Find non-pinned pawns and push them one square
845 Bitboard b1
= move_pawns
<Us
, DELTA_N
>(pos
.pawns(Us
) & ~pinned
);
847 // We don't have to AND with empty squares here,
848 // because the blocking squares will always be empty.
849 Bitboard b2
= b1
& blockSquares
;
852 to
= pop_1st_bit(&b2
);
854 assert(pos
.piece_on(to
) == EMPTY
);
856 if (square_rank(to
) == TRANK_8
)
858 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, QUEEN
);
859 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, ROOK
);
860 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, BISHOP
);
861 (*mlist
++).move
= make_promotion_move(to
- TDELTA_N
, to
, KNIGHT
);
863 (*mlist
++).move
= make_move(to
- TDELTA_N
, to
);
866 // Double pawn pushes
867 b2
= b1
& pos
.empty_squares() & TRank3BB
;
868 b2
= move_pawns
<Us
, DELTA_N
>(b2
) & blockSquares
;
871 to
= pop_1st_bit(&b2
);
873 assert(pos
.piece_on(to
) == EMPTY
);
874 assert(Us
!= WHITE
|| square_rank(to
) == RANK_4
);
875 assert(Us
!= BLACK
|| square_rank(to
) == RANK_5
);
877 (*mlist
++).move
= make_move(to
- TDELTA_N
- TDELTA_N
, to
);
882 template<CastlingSide Side
>
883 MoveStack
* generate_castle_moves(const Position
& pos
, MoveStack
* mlist
) {
885 Color us
= pos
.side_to_move();
887 if ( (Side
== KING_SIDE
&& pos
.can_castle_kingside(us
))
888 ||(Side
== QUEEN_SIDE
&& pos
.can_castle_queenside(us
)))
890 Color them
= opposite_color(us
);
891 Square ksq
= pos
.king_square(us
);
893 assert(pos
.piece_on(ksq
) == piece_of_color_and_type(us
, KING
));
895 Square rsq
= (Side
== KING_SIDE
? pos
.initial_kr_square(us
) : pos
.initial_qr_square(us
));
896 Square s1
= relative_square(us
, Side
== KING_SIDE
? SQ_G1
: SQ_C1
);
897 Square s2
= relative_square(us
, Side
== KING_SIDE
? SQ_F1
: SQ_D1
);
899 bool illegal
= false;
901 assert(pos
.piece_on(rsq
) == piece_of_color_and_type(us
, ROOK
));
903 // It is a bit complicated to correctly handle Chess960
904 for (s
= Min(ksq
, s1
); s
<= Max(ksq
, s1
); s
++)
905 if ( (s
!= ksq
&& s
!= rsq
&& pos
.square_is_occupied(s
))
906 || pos
.square_is_attacked(s
, them
))
909 for (s
= Min(rsq
, s2
); s
<= Max(rsq
, s2
); s
++)
910 if (s
!= ksq
&& s
!= rsq
&& pos
.square_is_occupied(s
))
913 if ( Side
== QUEEN_SIDE
914 && square_file(rsq
) == FILE_B
915 && ( pos
.piece_on(relative_square(us
, SQ_A1
)) == piece_of_color_and_type(them
, ROOK
)
916 || pos
.piece_on(relative_square(us
, SQ_A1
)) == piece_of_color_and_type(them
, QUEEN
)))
920 (*mlist
++).move
= make_castle_move(ksq
, rsq
);
925 bool castling_is_check(const Position
& pos
, CastlingSide side
) {
927 // After castling opponent king is attacked by the castled rook?
928 File rookFile
= (side
== QUEEN_SIDE
? FILE_D
: FILE_F
);
929 Color us
= pos
.side_to_move();
930 Square ksq
= pos
.king_square(us
);
931 Bitboard occ
= pos
.occupied_squares();
933 clear_bit(&occ
, ksq
); // Remove our king from the board
934 Square rsq
= make_square(rookFile
, square_rank(ksq
));
935 return bit_is_set(rook_attacks_bb(rsq
, occ
), pos
.king_square(opposite_color(us
)));