2 Glaurung, a UCI chess playing engine.
3 Copyright (C) 2004-2008 Tord Romstad
5 Glaurung 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 Glaurung 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/>.
30 //// Local definitions
35 int generate_white_pawn_captures(const Position&, MoveStack*);
36 int generate_black_pawn_captures(const Position&, MoveStack*);
37 int generate_white_pawn_noncaptures(const Position&, MoveStack*);
38 int generate_black_pawn_noncaptures(const Position&, MoveStack*);
39 int generate_knight_moves(const Position&, MoveStack*, Color side, Bitboard t);
40 int generate_bishop_moves(const Position&, MoveStack*, Color side, Bitboard t);
41 int generate_rook_moves(const Position&, MoveStack*, Color side, Bitboard t);
42 int generate_queen_moves(const Position&, MoveStack*, Color side, Bitboard t);
43 int generate_king_moves(const Position&, MoveStack*, Square from, Bitboard t);
44 int generate_castle_moves(const Position&, MoveStack*, Color us);
54 /// generate_captures generates() all pseudo-legal captures and queen
55 /// promotions. The return value is the number of moves generated.
57 int generate_captures(const Position& pos, MoveStack* mlist) {
60 assert(!pos.is_check());
62 Color us = pos.side_to_move();
63 Bitboard target = pos.pieces_of_color(opposite_color(us));
67 n = generate_white_pawn_captures(pos, mlist);
69 n = generate_black_pawn_captures(pos, mlist);
71 n += generate_knight_moves(pos, mlist+n, us, target);
72 n += generate_bishop_moves(pos, mlist+n, us, target);
73 n += generate_rook_moves(pos, mlist+n, us, target);
74 n += generate_queen_moves(pos, mlist+n, us, target);
75 n += generate_king_moves(pos, mlist+n, pos.king_square(us), target);
80 /// generate_noncaptures() generates all pseudo-legal non-captures and
81 /// underpromotions. The return value is the number of moves generated.
83 int generate_noncaptures(const Position& pos, MoveStack *mlist) {
86 assert(!pos.is_check());
88 Color us = pos.side_to_move();
89 Bitboard target = pos.empty_squares();
93 n = generate_white_pawn_noncaptures(pos, mlist);
95 n = generate_black_pawn_noncaptures(pos, mlist);
97 n += generate_knight_moves(pos, mlist+n, us, target);
98 n += generate_bishop_moves(pos, mlist+n, us, target);
99 n += generate_rook_moves(pos, mlist+n, us, target);
100 n += generate_queen_moves(pos, mlist+n, us, target);
101 n += generate_king_moves(pos, mlist+n, pos.king_square(us), target);
102 n += generate_castle_moves(pos, mlist+n, us);
107 /// generate_checks() generates all pseudo-legal non-capturing, non-promoting
108 /// checks, except castling moves (will add this later). It returns the
109 /// number of generated moves.
111 int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) {
114 assert(!pos.is_check());
117 Square ksq, from, to;
118 Bitboard empty, checkSqs, b1, b2, b3;
121 us = pos.side_to_move();
122 them = opposite_color(us);
124 ksq = pos.king_square(them);
125 assert(pos.piece_on(ksq) == king_of_color(them));
127 dc = pos.discovered_check_candidates(us);
128 empty = pos.empty_squares();
130 // Pawn moves. This is somewhat messy, and we use separate code for white
131 // and black, because we can't shift by negative numbers in C/C++. :-(
135 // Pawn moves which give discovered check. This is possible only if the
136 // pawn is not on the same file as the enemy king, because we don't
137 // generate captures.
139 // Find all friendly pawns not on the enemy king's file:
140 b1 = pos.pawns(us) & ~file_bb(ksq);
142 // Discovered checks, single pawn pushes:
143 b2 = b3 = ((b1 & dc) << 8) & ~Rank8BB & empty;
145 to = pop_1st_bit(&b3);
146 mlist[n++].move = make_move(to - DELTA_N, to);
149 // Discovered checks, double pawn pushes:
150 b3 = ((b2 & Rank3BB) << 8) & empty;
152 to = pop_1st_bit(&b3);
153 mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to);
156 // Direct checks. These are possible only for pawns on neighboring files
157 // of the enemy king:
159 b1 &= (~dc & neighboring_files_bb(ksq));
161 // Direct checks, single pawn pushes:
162 b2 = (b1 << 8) & empty;
163 b3 = b2 & pos.black_pawn_attacks(ksq);
165 to = pop_1st_bit(&b3);
166 mlist[n++].move = make_move(to - DELTA_N, to);
169 // Direct checks, double pawn pushes:
170 b3 = ((b2 & Rank3BB) << 8) & empty & pos.black_pawn_attacks(ksq);
172 to = pop_1st_bit(&b3);
173 mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to);
176 else { // (us == BLACK)
178 // Pawn moves which give discovered check. This is possible only if the
179 // pawn is not on the same file as the enemy king, because we don't
180 // generate captures.
182 // Find all friendly pawns not on the enemy king's file:
183 b1 = pos.pawns(us) & ~file_bb(ksq);
185 // Discovered checks, single pawn pushes:
186 b2 = b3 = ((b1 & dc) >> 8) & ~Rank1BB & empty;
188 to = pop_1st_bit(&b3);
189 mlist[n++].move = make_move(to - DELTA_S, to);
192 // Discovered checks, double pawn pushes:
193 b3 = ((b2 & Rank6BB) >> 8) & empty;
195 to = pop_1st_bit(&b3);
196 mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to);
199 // Direct checks. These are possible only for pawns on neighboring files
200 // of the enemy king:
202 b1 &= (~dc & neighboring_files_bb(ksq));
204 // Direct checks, single pawn pushes:
205 b2 = (b1 >> 8) & empty;
206 b3 = b2 & pos.white_pawn_attacks(ksq);
208 to = pop_1st_bit(&b3);
209 mlist[n++].move = make_move(to - DELTA_S, to);
212 // Direct checks, double pawn pushes:
213 b3 = ((b2 & Rank6BB) >> 8) & empty & pos.black_pawn_attacks(ksq);
215 to = pop_1st_bit(&b3);
216 mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to);
221 b1 = pos.knights(us);
223 // Discovered knight checks:
226 from = pop_1st_bit(&b2);
227 b3 = pos.knight_attacks(from) & empty;
229 to = pop_1st_bit(&b3);
230 mlist[n++].move = make_move(from, to);
234 // Direct knight checks:
236 checkSqs = pos.knight_attacks(ksq) & empty;
238 from = pop_1st_bit(&b2);
239 b3 = pos.knight_attacks(from) & checkSqs;
241 to = pop_1st_bit(&b3);
242 mlist[n++].move = make_move(from, to);
248 b1 = pos.bishops(us);
250 // Discovered bishop checks:
253 from = pop_1st_bit(&b2);
254 b3 = pos.bishop_attacks(from) & empty;
256 to = pop_1st_bit(&b3);
257 mlist[n++].move = make_move(from, to);
261 // Direct bishop checks:
263 checkSqs = pos.bishop_attacks(ksq) & empty;
265 from = pop_1st_bit(&b2);
266 b3 = pos.bishop_attacks(from) & checkSqs;
268 to = pop_1st_bit(&b3);
269 mlist[n++].move = make_move(from, to);
277 // Discovered rook checks:
280 from = pop_1st_bit(&b2);
281 b3 = pos.rook_attacks(from) & empty;
283 to = pop_1st_bit(&b3);
284 mlist[n++].move = make_move(from, to);
288 // Direct rook checks:
290 checkSqs = pos.rook_attacks(ksq) & empty;
292 from = pop_1st_bit(&b2);
293 b3 = pos.rook_attacks(from) & checkSqs;
295 to = pop_1st_bit(&b3);
296 mlist[n++].move = make_move(from, to);
304 // Discovered queen checks are impossible!
306 // Direct queen checks:
307 checkSqs = pos.queen_attacks(ksq) & empty;
309 from = pop_1st_bit(&b1);
310 b2 = pos.queen_attacks(from) & checkSqs;
312 to = pop_1st_bit(&b2);
313 mlist[n++].move = make_move(from, to);
319 from = pos.king_square(us);
320 if(bit_is_set(dc, from)) {
321 b1 = pos.king_attacks(from) & empty & ~QueenPseudoAttacks[ksq];
323 to = pop_1st_bit(&b1);
324 mlist[n++].move = make_move(from, to);
328 // TODO: Castling moves!
334 /// generate_evasions() generates all check evasions when the side to move is
335 /// in check. Unlike the other move generation functions, this one generates
336 /// only legal moves. It returns the number of generated moves. This
337 /// function is very ugly, and needs cleaning up some time later. FIXME
339 int generate_evasions(const Position &pos, MoveStack *mlist) {
342 assert(pos.is_check());
345 Bitboard checkers = pos.checkers();
346 Bitboard pinned, b1, b2;
347 Square ksq, from, to;
350 us = pos.side_to_move();
351 them = opposite_color(us);
353 ksq = pos.king_square(us);
354 assert(pos.piece_on(ksq) == king_of_color(us));
356 // Generate evasions for king:
357 b1 = pos.king_attacks(ksq) & ~pos.pieces_of_color(us);
358 b2 = pos.occupied_squares();
361 to = pop_1st_bit(&b1);
363 // Make sure to is not attacked by the other side. This is a bit ugly,
364 // because we can't use Position::square_is_attacked. Instead we use
365 // the low-level bishop_attacks_bb and rook_attacks_bb with the bitboard
366 // b2 (the occupied squares with the king removed) in order to test whether
367 // the king will remain in check on the destination square.
368 if(((pos.pawn_attacks(us, to) & pos.pawns(them)) == EmptyBoardBB) &&
369 ((pos.knight_attacks(to) & pos.knights(them)) == EmptyBoardBB) &&
370 ((pos.king_attacks(to) & pos.kings(them)) == EmptyBoardBB) &&
371 ((bishop_attacks_bb(to, b2) & pos.bishops_and_queens(them))
373 ((rook_attacks_bb(to, b2) & pos.rooks_and_queens(them)) == EmptyBoardBB))
374 mlist[n++].move = make_move(ksq, to);
378 // Generate evasions for other pieces only if not double check. We use a
379 // simple bit twiddling hack here rather than calling count_1s in order to
380 // save some time (we know that pos.checkers() has at most two nonzero bits).
381 if(!(checkers & (checkers - 1))) {
382 Square checksq = first_1(checkers);
383 assert(pos.color_of_piece_on(checksq) == them);
385 // Find pinned pieces:
386 pinned = pos.pinned_pieces(us);
388 // Generate captures of the checking piece:
391 b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & ~pinned;
393 from = pop_1st_bit(&b1);
394 if(relative_rank(us, checksq) == RANK_8) {
395 mlist[n++].move = make_promotion_move(from, checksq, QUEEN);
396 mlist[n++].move = make_promotion_move(from, checksq, ROOK);
397 mlist[n++].move = make_promotion_move(from, checksq, BISHOP);
398 mlist[n++].move = make_promotion_move(from, checksq, KNIGHT);
401 mlist[n++].move = make_move(from, checksq);
405 b1 = pos.knight_attacks(checksq) & pos.knights(us) & ~pinned;
407 from = pop_1st_bit(&b1);
408 mlist[n++].move = make_move(from, checksq);
411 // Bishop and queen captures:
412 b1 = pos.bishop_attacks(checksq) & pos.bishops_and_queens(us)
415 from = pop_1st_bit(&b1);
416 mlist[n++].move = make_move(from, checksq);
419 // Rook and queen captures:
420 b1 = pos.rook_attacks(checksq) & pos.rooks_and_queens(us)
423 from = pop_1st_bit(&b1);
424 mlist[n++].move = make_move(from, checksq);
427 // Blocking check evasions are possible only if the checking piece is
429 if(checkers & pos.sliders()) {
430 Bitboard blockSquares = squares_between(checksq, ksq);
431 assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB);
433 // Pawn moves. Because a blocking evasion can never be a capture, we
434 // only generate pawn pushes. As so often, the code for pawns is a bit
435 // ugly, and uses separate clauses for white and black pawns. :-(
437 // Find non-pinned pawns:
438 b1 = pos.pawns(WHITE) & ~pinned;
440 // Single pawn pushes. We don't have to AND with empty squares here,
441 // because the blocking squares will always be empty.
442 b2 = (b1 << 8) & blockSquares;
444 to = pop_1st_bit(&b2);
445 assert(pos.piece_on(to) == EMPTY);
446 if(square_rank(to) == RANK_8) {
447 mlist[n++].move = make_promotion_move(to - DELTA_N, to, QUEEN);
448 mlist[n++].move = make_promotion_move(to - DELTA_N, to, ROOK);
449 mlist[n++].move = make_promotion_move(to - DELTA_N, to, BISHOP);
450 mlist[n++].move = make_promotion_move(to - DELTA_N, to, KNIGHT);
453 mlist[n++].move = make_move(to - DELTA_N, to);
455 // Double pawn pushes.
456 b2 = (((b1 << 8) & pos.empty_squares() & Rank3BB) << 8) & blockSquares;
458 to = pop_1st_bit(&b2);
459 assert(pos.piece_on(to) == EMPTY);
460 assert(square_rank(to) == RANK_4);
461 mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to);
464 else { // (us == BLACK)
465 // Find non-pinned pawns:
466 b1 = pos.pawns(BLACK) & ~pinned;
468 // Single pawn pushes. We don't have to AND with empty squares here,
469 // because the blocking squares will always be empty.
470 b2 = (b1 >> 8) & blockSquares;
472 to = pop_1st_bit(&b2);
473 assert(pos.piece_on(to) == EMPTY);
474 if(square_rank(to) == RANK_1) {
475 mlist[n++].move = make_promotion_move(to - DELTA_S, to, QUEEN);
476 mlist[n++].move = make_promotion_move(to - DELTA_S, to, ROOK);
477 mlist[n++].move = make_promotion_move(to - DELTA_S, to, BISHOP);
478 mlist[n++].move = make_promotion_move(to - DELTA_S, to, KNIGHT);
481 mlist[n++].move = make_move(to - DELTA_S, to);
483 // Double pawn pushes.
484 b2 = (((b1 >> 8) & pos.empty_squares() & Rank6BB) >> 8) & blockSquares;
486 to = pop_1st_bit(&b2);
487 assert(pos.piece_on(to) == EMPTY);
488 assert(square_rank(to) == RANK_5);
489 mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to);
494 b1 = pos.knights(us) & ~pinned;
496 from = pop_1st_bit(&b1);
497 b2 = pos.knight_attacks(from) & blockSquares;
499 to = pop_1st_bit(&b2);
500 mlist[n++].move = make_move(from, to);
505 b1 = pos.bishops(us) & ~pinned;
507 from = pop_1st_bit(&b1);
508 b2 = pos.bishop_attacks(from) & blockSquares;
510 to = pop_1st_bit(&b2);
511 mlist[n++].move = make_move(from, to);
516 b1 = pos.rooks(us) & ~pinned;
518 from = pop_1st_bit(&b1);
519 b2 = pos.rook_attacks(from) & blockSquares;
521 to = pop_1st_bit(&b2);
522 mlist[n++].move = make_move(from, to);
527 b1 = pos.queens(us) & ~pinned;
529 from = pop_1st_bit(&b1);
530 b2 = pos.queen_attacks(from) & blockSquares;
532 to = pop_1st_bit(&b2);
533 mlist[n++].move = make_move(from, to);
538 // Finally, the ugly special case of en passant captures. An en passant
539 // capture can only be a check evasion if the check is not a discovered
540 // check. If pos.ep_square() is set, the last move made must have been
541 // a double pawn push. If, furthermore, the checking piece is a pawn,
542 // an en passant check evasion may be possible.
543 if(pos.ep_square() != SQ_NONE && (checkers & pos.pawns(them))) {
544 to = pos.ep_square();
545 b1 = pos.pawn_attacks(them, to) & pos.pawns(us);
546 assert(b1 != EmptyBoardBB);
549 from = pop_1st_bit(&b1);
551 // Before generating the move, we have to make sure it is legal.
552 // This is somewhat tricky, because the two disappearing pawns may
553 // cause new "discovered checks". We test this by removing the
554 // two relevant bits from the occupied squares bitboard, and using
555 // the low-level bitboard functions for bishop and rook attacks.
556 b2 = pos.occupied_squares();
557 clear_bit(&b2, from);
558 clear_bit(&b2, checksq);
559 if(((bishop_attacks_bb(ksq, b2) & pos.bishops_and_queens(them))
561 ((rook_attacks_bb(ksq, b2) & pos.rooks_and_queens(them))
563 mlist[n++].move = make_ep_move(from, to);
572 /// generate_legal_moves() computes a complete list of legal moves in the
573 /// current position. This function is not very fast, and should be used
574 /// only in situations where performance is unimportant. It wouldn't be
575 /// very hard to write an efficient legal move generator, but for the moment
576 /// we don't need it.
578 int generate_legal_moves(const Position& pos, MoveStack* mlist) {
583 return generate_evasions(pos, mlist);
585 // Generate pseudo-legal moves:
586 int n = generate_captures(pos, mlist);
587 n += generate_noncaptures(pos, mlist + n);
589 Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
591 // Remove illegal moves from the list:
592 for (int i = 0; i < n; i++)
593 if (!pos.move_is_legal(mlist[i].move, pinned))
594 mlist[i--].move = mlist[--n].move;
600 /// generate_move_if_legal() takes a position and a (not necessarily
601 /// pseudo-legal) move and a pinned pieces bitboard as input, and tests
602 /// whether the move is legal. If the move is legal, the move itself is
603 /// returned. If not, the function returns MOVE_NONE. This function must
604 /// only be used when the side to move is not in check.
606 Move generate_move_if_legal(const Position &pos, Move m, Bitboard pinned) {
609 assert(!pos.is_check());
610 assert(move_is_ok(m));
612 Color us = pos.side_to_move();
613 Color them = opposite_color(us);
614 Square from = move_from(m);
615 Piece pc = pos.piece_on(from);
617 // If the from square is not occupied by a piece belonging to the side to
618 // move, the move is obviously not legal.
619 if (color_of_piece(pc) != us)
622 Square to = move_to(m);
627 // The piece must be a pawn and destination square must be the
628 // en passant square.
629 if ( type_of_piece(pc) != PAWN
630 || to != pos.ep_square())
633 assert(pos.square_is_empty(to));
634 assert(pos.piece_on(to - pawn_push(us)) == pawn_of_color(them));
636 // The move is pseudo-legal. If it is legal, return it.
637 return (pos.move_is_legal(m) ? m : MOVE_NONE);
641 if (move_is_short_castle(m))
643 // The piece must be a king and side to move must still have
644 // the right to castle kingside.
645 if ( type_of_piece(pc) != KING
646 ||!pos.can_castle_kingside(us))
649 assert(from == pos.king_square(us));
650 assert(to == pos.initial_kr_square(us));
651 assert(pos.piece_on(to) == rook_of_color(us));
653 Square g1 = relative_square(us, SQ_G1);
654 Square f1 = relative_square(us, SQ_F1);
656 bool illegal = false;
658 // Check if any of the squares between king and rook
659 // is occupied or under attack.
660 for (s = Min(from, g1); s <= Max(from, g1); s++)
661 if ( (s != from && s != to && !pos.square_is_empty(s))
662 || pos.square_is_attacked(s, them))
665 // Check if any of the squares between king and rook
667 for (s = Min(to, f1); s <= Max(to, f1); s++)
668 if (s != from && s != to && !pos.square_is_empty(s))
671 return (!illegal ? m : MOVE_NONE);
674 if (move_is_long_castle(m))
676 // The piece must be a king and side to move must still have
677 // the right to castle kingside.
678 if ( type_of_piece(pc) != KING
679 ||!pos.can_castle_queenside(us))
682 assert(from == pos.king_square(us));
683 assert(to == pos.initial_qr_square(us));
684 assert(pos.piece_on(to) == rook_of_color(us));
686 Square c1 = relative_square(us, SQ_C1);
687 Square d1 = relative_square(us, SQ_D1);
689 bool illegal = false;
691 for (s = Min(from, c1); s <= Max(from, c1); s++)
692 if( (s != from && s != to && !pos.square_is_empty(s))
693 || pos.square_is_attacked(s, them))
696 for (s = Min(to, d1); s <= Max(to, d1); s++)
697 if(s != from && s != to && !pos.square_is_empty(s))
700 if ( square_file(to) == FILE_B
701 && ( pos.piece_on(to + DELTA_W) == rook_of_color(them)
702 || pos.piece_on(to + DELTA_W) == queen_of_color(them)))
705 return (!illegal ? m : MOVE_NONE);
710 // The destination square cannot be occupied by a friendly piece
711 if (pos.color_of_piece_on(to) == us)
714 // Proceed according to the type of the moving piece.
715 if (type_of_piece(pc) == PAWN)
717 // If the destination square is on the 8/1th rank, the move must
719 if ( ( (square_rank(to) == RANK_8 && us == WHITE)
720 ||(square_rank(to) == RANK_1 && us != WHITE))
721 && !move_promotion(m))
724 // Proceed according to the square delta between the source and
725 // destionation squares.
732 // Capture. The destination square must be occupied by an enemy
733 // piece (en passant captures was handled earlier).
734 if (pos.color_of_piece_on(to) != them)
740 // Pawn push. The destination square must be empty.
741 if (!pos.square_is_empty(to))
746 // Double white pawn push. The destination square must be on the fourth
747 // rank, and both the destination square and the square between the
748 // source and destination squares must be empty.
749 if ( square_rank(to) != RANK_4
750 || !pos.square_is_empty(to)
751 || !pos.square_is_empty(from + DELTA_N))
756 // Double black pawn push. The destination square must be on the fifth
757 // rank, and both the destination square and the square between the
758 // source and destination squares must be empty.
759 if ( square_rank(to) != RANK_5
760 || !pos.square_is_empty(to)
761 || !pos.square_is_empty(from + DELTA_S))
768 // The move is pseudo-legal. Return it if it is legal.
769 return (pos.move_is_legal(m) ? m : MOVE_NONE);
772 // Luckly we can handle all the other pieces in one go
773 return ( pos.piece_attacks_square(from, to)
774 && pos.move_is_legal(m)
775 && !move_promotion(m) ? m : MOVE_NONE);
781 int generate_white_pawn_captures(const Position &pos, MoveStack *mlist) {
782 Bitboard pawns = pos.pawns(WHITE);
783 Bitboard enemyPieces = pos.pieces_of_color(BLACK);
788 // Captures in the a1-h8 direction:
789 b1 = (pawns << 9) & ~FileABB & enemyPieces;
794 sq = pop_1st_bit(&b2);
795 mlist[n++].move = make_promotion_move(sq - DELTA_NE, sq, QUEEN);
801 sq = pop_1st_bit(&b2);
802 mlist[n++].move = make_move(sq - DELTA_NE, sq);
805 // Captures in the h1-a8 direction:
806 b1 = (pawns << 7) & ~FileHBB & enemyPieces;
811 sq = pop_1st_bit(&b2);
812 mlist[n++].move = make_promotion_move(sq - DELTA_NW, sq, QUEEN);
818 sq = pop_1st_bit(&b2);
819 mlist[n++].move = make_move(sq - DELTA_NW, sq);
822 // Non-capturing promotions:
823 b1 = (pawns << 8) & pos.empty_squares() & Rank8BB;
825 sq = pop_1st_bit(&b1);
826 mlist[n++].move = make_promotion_move(sq - DELTA_N, sq, QUEEN);
829 // En passant captures:
830 if(pos.ep_square() != SQ_NONE) {
831 assert(square_rank(pos.ep_square()) == RANK_6);
832 b1 = pawns & pos.black_pawn_attacks(pos.ep_square());
833 assert(b1 != EmptyBoardBB);
835 sq = pop_1st_bit(&b1);
836 mlist[n++].move = make_ep_move(sq, pos.ep_square());
844 int generate_black_pawn_captures(const Position &pos, MoveStack *mlist) {
845 Bitboard pawns = pos.pawns(BLACK);
846 Bitboard enemyPieces = pos.pieces_of_color(WHITE);
851 // Captures in the a8-h1 direction:
852 b1 = (pawns >> 7) & ~FileABB & enemyPieces;
857 sq = pop_1st_bit(&b2);
858 mlist[n++].move = make_promotion_move(sq - DELTA_SE, sq, QUEEN);
864 sq = pop_1st_bit(&b2);
865 mlist[n++].move = make_move(sq - DELTA_SE, sq);
868 // Captures in the h8-a1 direction:
869 b1 = (pawns >> 9) & ~FileHBB & enemyPieces;
874 sq = pop_1st_bit(&b2);
875 mlist[n++].move = make_promotion_move(sq - DELTA_SW, sq, QUEEN);
881 sq = pop_1st_bit(&b2);
882 mlist[n++].move = make_move(sq - DELTA_SW, sq);
885 // Non-capturing promotions:
886 b1 = (pawns >> 8) & pos.empty_squares() & Rank1BB;
888 sq = pop_1st_bit(&b1);
889 mlist[n++].move = make_promotion_move(sq - DELTA_S, sq, QUEEN);
892 // En passant captures:
893 if(pos.ep_square() != SQ_NONE) {
894 assert(square_rank(pos.ep_square()) == RANK_3);
895 b1 = pawns & pos.white_pawn_attacks(pos.ep_square());
896 assert(b1 != EmptyBoardBB);
898 sq = pop_1st_bit(&b1);
899 mlist[n++].move = make_ep_move(sq, pos.ep_square());
907 int generate_white_pawn_noncaptures(const Position &pos, MoveStack *mlist) {
908 Bitboard pawns = pos.pawns(WHITE);
909 Bitboard enemyPieces = pos.pieces_of_color(BLACK);
910 Bitboard emptySquares = pos.empty_squares();
915 // Underpromotion captures in the a1-h8 direction:
916 b1 = (pawns << 9) & ~FileABB & enemyPieces & Rank8BB;
918 sq = pop_1st_bit(&b1);
919 mlist[n++].move = make_promotion_move(sq - DELTA_NE, sq, ROOK);
920 mlist[n++].move = make_promotion_move(sq - DELTA_NE, sq, BISHOP);
921 mlist[n++].move = make_promotion_move(sq - DELTA_NE, sq, KNIGHT);
924 // Underpromotion captures in the h1-a8 direction:
925 b1 = (pawns << 7) & ~FileHBB & enemyPieces & Rank8BB;
927 sq = pop_1st_bit(&b1);
928 mlist[n++].move = make_promotion_move(sq - DELTA_NW, sq, ROOK);
929 mlist[n++].move = make_promotion_move(sq - DELTA_NW, sq, BISHOP);
930 mlist[n++].move = make_promotion_move(sq - DELTA_NW, sq, KNIGHT);
933 // Single pawn pushes:
934 b1 = (pawns << 8) & emptySquares;
937 sq = pop_1st_bit(&b2);
938 mlist[n++].move = make_promotion_move(sq - DELTA_N, sq, ROOK);
939 mlist[n++].move = make_promotion_move(sq - DELTA_N, sq, BISHOP);
940 mlist[n++].move = make_promotion_move(sq - DELTA_N, sq, KNIGHT);
944 sq = pop_1st_bit(&b2);
945 mlist[n++].move = make_move(sq - DELTA_N, sq);
948 // Double pawn pushes:
949 b2 = ((b1 & Rank3BB) << 8) & emptySquares;
951 sq = pop_1st_bit(&b2);
952 mlist[n++].move = make_move(sq - DELTA_N - DELTA_N, sq);
959 int generate_black_pawn_noncaptures(const Position &pos, MoveStack *mlist) {
960 Bitboard pawns = pos.pawns(BLACK);
961 Bitboard enemyPieces = pos.pieces_of_color(WHITE);
962 Bitboard emptySquares = pos.empty_squares();
967 // Underpromotion captures in the a8-h1 direction:
968 b1 = (pawns >> 7) & ~FileABB & enemyPieces & Rank1BB;
970 sq = pop_1st_bit(&b1);
971 mlist[n++].move = make_promotion_move(sq - DELTA_SE, sq, ROOK);
972 mlist[n++].move = make_promotion_move(sq - DELTA_SE, sq, BISHOP);
973 mlist[n++].move = make_promotion_move(sq - DELTA_SE, sq, KNIGHT);
976 // Underpromotion captures in the h8-a1 direction:
977 b1 = (pawns >> 9) & ~FileHBB & enemyPieces & Rank1BB;
979 sq = pop_1st_bit(&b1);
980 mlist[n++].move = make_promotion_move(sq - DELTA_SW, sq, ROOK);
981 mlist[n++].move = make_promotion_move(sq - DELTA_SW, sq, BISHOP);
982 mlist[n++].move = make_promotion_move(sq - DELTA_SW, sq, KNIGHT);
985 // Single pawn pushes:
986 b1 = (pawns >> 8) & emptySquares;
989 sq = pop_1st_bit(&b2);
990 mlist[n++].move = make_promotion_move(sq - DELTA_S, sq, ROOK);
991 mlist[n++].move = make_promotion_move(sq - DELTA_S, sq, BISHOP);
992 mlist[n++].move = make_promotion_move(sq - DELTA_S, sq, KNIGHT);
996 sq = pop_1st_bit(&b2);
997 mlist[n++].move = make_move(sq - DELTA_S, sq);
1000 // Double pawn pushes:
1001 b2 = ((b1 & Rank6BB) >> 8) & emptySquares;
1003 sq = pop_1st_bit(&b2);
1004 mlist[n++].move = make_move(sq - DELTA_S - DELTA_S, sq);
1011 int generate_knight_moves(const Position &pos, MoveStack *mlist,
1012 Color side, Bitboard target) {
1017 for(i = 0; i < pos.knight_count(side); i++) {
1018 from = pos.knight_list(side, i);
1019 b = pos.knight_attacks(from) & target;
1021 to = pop_1st_bit(&b);
1022 mlist[n++].move = make_move(from, to);
1029 int generate_bishop_moves(const Position &pos, MoveStack *mlist,
1030 Color side, Bitboard target) {
1035 for(i = 0; i < pos.bishop_count(side); i++) {
1036 from = pos.bishop_list(side, i);
1037 b = pos.bishop_attacks(from) & target;
1039 to = pop_1st_bit(&b);
1040 mlist[n++].move = make_move(from, to);
1047 int generate_rook_moves(const Position &pos, MoveStack *mlist,
1048 Color side, Bitboard target) {
1053 for(i = 0; i < pos.rook_count(side); i++) {
1054 from = pos.rook_list(side, i);
1055 b = pos.rook_attacks(from) & target;
1057 to = pop_1st_bit(&b);
1058 mlist[n++].move = make_move(from, to);
1065 int generate_queen_moves(const Position &pos, MoveStack *mlist,
1066 Color side, Bitboard target) {
1071 for(i = 0; i < pos.queen_count(side); i++) {
1072 from = pos.queen_list(side, i);
1073 b = pos.queen_attacks(from) & target;
1075 to = pop_1st_bit(&b);
1076 mlist[n++].move = make_move(from, to);
1083 int generate_king_moves(const Position &pos, MoveStack *mlist,
1084 Square from, Bitboard target) {
1089 b = pos.king_attacks(from) & target;
1091 to = pop_1st_bit(&b);
1092 mlist[n++].move = make_move(from, to);
1098 int generate_castle_moves(const Position &pos, MoveStack *mlist, Color us) {
1101 if(pos.can_castle(us)) {
1102 Color them = opposite_color(us);
1103 Square ksq = pos.king_square(us);
1104 assert(pos.piece_on(ksq) == king_of_color(us));
1106 if(pos.can_castle_kingside(us)) {
1107 Square rsq = pos.initial_kr_square(us);
1108 Square g1 = relative_square(us, SQ_G1);
1109 Square f1 = relative_square(us, SQ_F1);
1111 bool illegal = false;
1113 assert(pos.piece_on(rsq) == rook_of_color(us));
1115 for(s = Min(ksq, g1); s <= Max(ksq, g1); s++)
1116 if((s != ksq && s != rsq && pos.square_is_occupied(s))
1117 || pos.square_is_attacked(s, them))
1119 for(s = Min(rsq, f1); s <= Max(rsq, f1); s++)
1120 if(s != ksq && s != rsq && pos.square_is_occupied(s))
1124 mlist[n++].move = make_castle_move(ksq, rsq);
1127 if(pos.can_castle_queenside(us)) {
1128 Square rsq = pos.initial_qr_square(us);
1129 Square c1 = relative_square(us, SQ_C1);
1130 Square d1 = relative_square(us, SQ_D1);
1132 bool illegal = false;
1134 assert(pos.piece_on(rsq) == rook_of_color(us));
1136 for(s = Min(ksq, c1); s <= Max(ksq, c1); s++)
1137 if((s != ksq && s != rsq && pos.square_is_occupied(s))
1138 || pos.square_is_attacked(s, them))
1140 for(s = Min(rsq, d1); s <= Max(rsq, d1); s++)
1141 if(s != ksq && s != rsq && pos.square_is_occupied(s))
1143 if(square_file(rsq) == FILE_B &&
1144 (pos.piece_on(relative_square(us, SQ_A1)) == rook_of_color(them) ||
1145 pos.piece_on(relative_square(us, SQ_A1)) == queen_of_color(them)))
1149 mlist[n++].move = make_castle_move(ksq, rsq);