]> git.sesse.net Git - stockfish/blob - src/movegen.cpp
Add generation of castling checks
[stockfish] / src / movegen.cpp
1 /*
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
4
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.
9
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.
14
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/>.
17 */
18
19
20 ////
21 //// Includes
22 ////
23
24 #include <cassert>
25
26 #include "movegen.h"
27
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))
31
32 ////
33 //// Local definitions
34 ////
35
36 namespace {
37
38   enum CastlingSide {
39     KING_SIDE = 1,
40     QUEEN_SIDE = 2
41   };
42
43   // Functions
44   MoveStack* generate_castle_moves(const Position&, MoveStack*, unsigned = (KING_SIDE | QUEEN_SIDE));
45   bool castling_is_check(const Position& pos, CastlingSide side);
46
47   // Template generate_pawn_captures() with specializations
48   template<Color, Color, Bitboard, SquareDelta, SquareDelta, SquareDelta>
49   MoveStack* do_generate_pawn_captures(const Position& pos, MoveStack* mlist);
50
51   template<Color>
52   inline MoveStack* generate_pawn_captures(const Position& p, MoveStack* m) {
53       return do_generate_pawn_captures<WHITE, BLACK, Rank8BB, DELTA_NE, DELTA_NW, DELTA_N>(p, m);
54   }
55   template<>
56   inline MoveStack* generate_pawn_captures<BLACK>(const Position& p, MoveStack* m) {
57       return do_generate_pawn_captures<BLACK, WHITE, Rank1BB, DELTA_SE, DELTA_SW, DELTA_S>(p, m);
58   }
59
60   // Template generate_pawn_noncaptures() with specializations
61   template<Color, Color, Bitboard, Bitboard, SquareDelta, SquareDelta, SquareDelta>
62   MoveStack* do_generate_pawn_noncaptures(const Position& pos, MoveStack* mlist);
63
64   template<Color>
65   inline MoveStack* generate_pawn_noncaptures(const Position& p, MoveStack* m) {
66       return do_generate_pawn_noncaptures<WHITE, BLACK, Rank8BB, Rank3BB, DELTA_NE, DELTA_NW, DELTA_N>(p, m);
67   }
68   template<>
69   inline MoveStack* generate_pawn_noncaptures<BLACK>(const Position& p, MoveStack* m) {
70       return do_generate_pawn_noncaptures<BLACK, WHITE, Rank1BB, Rank6BB, DELTA_SE, DELTA_SW, DELTA_S>(p, m);
71   }
72
73   // Template generate_pawn_blocking_evasions() with specializations
74   template<Color Us, Rank, Bitboard, SquareDelta>
75   MoveStack* do_generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned,
76                                                 Bitboard blockSquares, MoveStack* mlist);
77   template<Color>
78   inline MoveStack* generate_pawn_blocking_evasions(const Position& p, Bitboard np, Bitboard bs, MoveStack* m) {
79       return do_generate_pawn_blocking_evasions<WHITE, RANK_8, Rank3BB, DELTA_N>(p, np, bs, m);
80   }
81   template<>
82   inline MoveStack* generate_pawn_blocking_evasions<BLACK>(const Position& p, Bitboard np, Bitboard bs, MoveStack* m) {
83       return do_generate_pawn_blocking_evasions<BLACK, RANK_1, Rank6BB, DELTA_S>(p, np, bs, m);
84   }
85
86   // Template generate_pawn_checks() with specializations
87   template<Color, Color, Bitboard, Bitboard, SquareDelta>
88   MoveStack* do_generate_pawn_checks(const Position&, Bitboard, Square, MoveStack*);
89
90   template<Color>
91   inline MoveStack* generate_pawn_checks(const Position& p, Bitboard dc, Square ksq, MoveStack* m) {
92       return do_generate_pawn_checks<WHITE, BLACK, Rank8BB, Rank3BB, DELTA_N>(p, dc, ksq, m);
93   }
94   template<>
95   inline MoveStack* generate_pawn_checks<BLACK>(const Position& p, Bitboard dc, Square ksq, MoveStack* m) {
96       return do_generate_pawn_checks<BLACK, WHITE, Rank1BB, Rank6BB, DELTA_S>(p, dc, ksq, m);
97   }
98
99   // non-pawn templates
100   template<PieceType>
101   MoveStack* generate_piece_moves(const Position&, MoveStack*, Color us, Bitboard);
102   template<>
103   MoveStack* generate_piece_moves<KING>(const Position& pos, MoveStack* mlist, Color us, Bitboard target);
104
105   template<PieceType>
106   MoveStack* generate_piece_checks(const Position&, Bitboard, Bitboard, Square, MoveStack*);
107   MoveStack* generate_piece_checks_king(const Position&, Square, Bitboard, Square, MoveStack*);
108
109   template<PieceType>
110   MoveStack* generate_piece_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*);
111 }
112
113
114 ////
115 //// Functions
116 ////
117
118
119 /// generate_captures generates() all pseudo-legal captures and queen
120 /// promotions.  The return value is the number of moves generated.
121
122 int generate_captures(const Position& pos, MoveStack* mlist) {
123
124   assert(pos.is_ok());
125   assert(!pos.is_check());
126
127   Color us = pos.side_to_move();
128   Bitboard target = pos.pieces_of_color(opposite_color(us));
129   MoveStack* mlist_start = mlist;
130
131   mlist = generate_piece_moves<QUEEN>(pos, mlist, us, target);
132   mlist = generate_piece_moves<ROOK>(pos, mlist, us, target);
133   mlist = generate_piece_moves<BISHOP>(pos, mlist, us, target);
134   mlist = generate_piece_moves<KNIGHT>(pos, mlist, us, target);
135
136   if (us == WHITE)
137       mlist = generate_pawn_captures<WHITE>(pos, mlist);
138   else
139       mlist = generate_pawn_captures<BLACK>(pos, mlist);
140
141   mlist = generate_piece_moves<KING>(pos, mlist, us, target);
142   return int(mlist - mlist_start);
143 }
144
145
146 /// generate_noncaptures() generates all pseudo-legal non-captures and
147 /// underpromotions.  The return value is the number of moves generated.
148
149 int generate_noncaptures(const Position& pos, MoveStack* mlist) {
150
151   assert(pos.is_ok());
152   assert(!pos.is_check());
153
154   Color us = pos.side_to_move();
155   Bitboard target = pos.empty_squares();
156   MoveStack* mlist_start = mlist;
157
158   if (us == WHITE)
159       mlist = generate_pawn_noncaptures<WHITE>(pos, mlist);
160   else
161       mlist = generate_pawn_noncaptures<BLACK>(pos, mlist);
162
163   mlist = generate_piece_moves<KNIGHT>(pos, mlist, us, target);
164   mlist = generate_piece_moves<BISHOP>(pos, mlist, us, target);
165   mlist = generate_piece_moves<ROOK>(pos, mlist, us, target);
166   mlist = generate_piece_moves<QUEEN>(pos, mlist, us, target);
167   mlist = generate_piece_moves<KING>(pos, mlist, us, target);
168   mlist = generate_castle_moves(pos, mlist);
169   return int(mlist - mlist_start);
170 }
171
172
173 /// generate_checks() generates all pseudo-legal non-capturing, non-promoting
174 /// checks. It returns the number of generated moves.
175
176 int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) {
177
178   assert(pos.is_ok());
179   assert(!pos.is_check());
180
181   Color us = pos.side_to_move();
182   Square ksq = pos.king_square(opposite_color(us));
183   MoveStack* mlist_start = mlist;
184
185   assert(pos.piece_on(ksq) == king_of_color(opposite_color(us)));
186
187   dc = pos.discovered_check_candidates(us);
188
189   // Pawn moves
190   if (us == WHITE)
191      mlist = generate_pawn_checks<WHITE>(pos, dc, ksq, mlist);
192   else
193      mlist = generate_pawn_checks<BLACK>(pos, dc, ksq, mlist);
194
195   // Pieces moves
196   Bitboard b = pos.knights(us);
197   if (b)
198       mlist = generate_piece_checks<KNIGHT>(pos, b, dc, ksq, mlist);
199
200   b = pos.bishops(us);
201   if (b)
202       mlist = generate_piece_checks<BISHOP>(pos, b, dc, ksq, mlist);
203
204   b = pos.rooks(us);
205   if (b)
206       mlist = generate_piece_checks<ROOK>(pos, b, dc, ksq, mlist);
207
208   b = pos.queens(us);
209   if (b)
210       mlist = generate_piece_checks<QUEEN>(pos, b, dc, ksq, mlist);
211
212   // Hopefully we always have a king ;-)
213   mlist = generate_piece_checks_king(pos, pos.king_square(us), dc, ksq, mlist);
214
215   // Castling moves that give check. Very rare but nice to have!
216   if (   pos.can_castle_queenside(us)
217       && (square_rank(ksq) == square_rank(pos.king_square(us)) || square_file(ksq) == FILE_D)
218       && castling_is_check(pos, QUEEN_SIDE))
219       mlist = generate_castle_moves(pos, mlist, QUEEN_SIDE);
220
221   if (   pos.can_castle_kingside(us)
222       && (square_rank(ksq) == square_rank(pos.king_square(us)) || square_file(ksq) == FILE_F)
223       && castling_is_check(pos, KING_SIDE))
224       mlist = generate_castle_moves(pos, mlist, KING_SIDE);
225
226   return int(mlist - mlist_start);
227 }
228
229
230 /// generate_evasions() generates all check evasions when the side to move is
231 /// in check.  Unlike the other move generation functions, this one generates
232 /// only legal moves.  It returns the number of generated moves.  This
233 /// function is very ugly, and needs cleaning up some time later.  FIXME
234
235 int generate_evasions(const Position& pos, MoveStack* mlist) {
236
237   assert(pos.is_ok());
238   assert(pos.is_check());
239
240   Square from, to;
241   Color us = pos.side_to_move();
242   Color them = opposite_color(us);
243   Square ksq = pos.king_square(us);
244   MoveStack* mlist_start = mlist;
245
246   assert(pos.piece_on(ksq) == king_of_color(us));
247
248   // Generate evasions for king
249   Bitboard b1 = pos.piece_attacks<KING>(ksq) & ~pos.pieces_of_color(us);
250   Bitboard b2 = pos.occupied_squares();
251   clear_bit(&b2, ksq);
252
253   while (b1)
254   {
255     to = pop_1st_bit(&b1);
256
257     // Make sure 'to' is not attacked by the other side. This is a bit ugly,
258     // because we can't use Position::square_is_attacked. Instead we use
259     // the low-level bishop_attacks_bb and rook_attacks_bb with the bitboard
260     // b2 (the occupied squares with the king removed) in order to test whether
261     // the king will remain in check on the destination square.
262     if (!(   (pos.piece_attacks<KNIGHT>(to) & pos.knights(them))
263           || (pos.pawn_attacks(us, to)      & pos.pawns(them))
264           || (bishop_attacks_bb(to, b2)     & pos.bishops_and_queens(them))
265           || (rook_attacks_bb(to, b2)       & pos.rooks_and_queens(them))
266           || (pos.piece_attacks<KING>(to)   & pos.kings(them))))
267
268         (*mlist++).move = make_move(ksq, to);
269   }
270
271   // Generate evasions for other pieces only if not double check. We use a
272   // simple bit twiddling hack here rather than calling count_1s in order to
273   // save some time (we know that pos.checkers() has at most two nonzero bits).
274   Bitboard checkers = pos.checkers();
275
276   if (!(checkers & (checkers - 1))) // Only one bit set?
277   {
278       Square checksq = first_1(checkers);
279
280       assert(pos.color_of_piece_on(checksq) == them);
281
282       // Find pinned pieces
283       Bitboard not_pinned = ~pos.pinned_pieces(us);
284
285       // Generate captures of the checking piece
286
287       // Pawn captures
288       b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & not_pinned;
289       while (b1)
290       {
291           from = pop_1st_bit(&b1);
292           if (relative_rank(us, checksq) == RANK_8)
293           {
294               (*mlist++).move = make_promotion_move(from, checksq, QUEEN);
295               (*mlist++).move = make_promotion_move(from, checksq, ROOK);
296               (*mlist++).move = make_promotion_move(from, checksq, BISHOP);
297               (*mlist++).move = make_promotion_move(from, checksq, KNIGHT);
298           } else
299               (*mlist++).move = make_move(from, checksq);
300       }
301
302       // Pieces captures
303       b1 = (  (pos.piece_attacks<KNIGHT>(checksq) & pos.knights(us))
304             | (pos.piece_attacks<BISHOP>(checksq) & pos.bishops_and_queens(us))
305             | (pos.piece_attacks<ROOK>(checksq)   & pos.rooks_and_queens(us)) ) & not_pinned;
306
307       while (b1)
308       {
309           from = pop_1st_bit(&b1);
310           (*mlist++).move = make_move(from, checksq);
311       }
312
313       // Blocking check evasions are possible only if the checking piece is
314       // a slider
315       if (checkers & pos.sliders())
316       {
317           Bitboard blockSquares = squares_between(checksq, ksq);
318
319           assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB);
320
321           // Pawn moves. Because a blocking evasion can never be a capture, we
322           // only generate pawn pushes.
323           if (us == WHITE)
324               mlist = generate_pawn_blocking_evasions<WHITE>(pos, not_pinned, blockSquares, mlist);
325           else
326               mlist = generate_pawn_blocking_evasions<BLACK>(pos, not_pinned, blockSquares, mlist);
327
328           // Pieces moves
329           b1 = pos.knights(us) & not_pinned;
330           if (b1)
331               mlist = generate_piece_blocking_evasions<KNIGHT>(pos, b1, blockSquares, mlist);
332
333           b1 = pos.bishops(us) & not_pinned;
334           if (b1)
335               mlist = generate_piece_blocking_evasions<BISHOP>(pos, b1, blockSquares, mlist);
336
337           b1 = pos.rooks(us) & not_pinned;
338           if (b1)
339               mlist = generate_piece_blocking_evasions<ROOK>(pos, b1, blockSquares, mlist);
340
341           b1 = pos.queens(us) & not_pinned;
342           if (b1)
343               mlist = generate_piece_blocking_evasions<QUEEN>(pos, b1, blockSquares, mlist);
344     }
345
346     // Finally, the ugly special case of en passant captures. An en passant
347     // capture can only be a check evasion if the check is not a discovered
348     // check. If pos.ep_square() is set, the last move made must have been
349     // a double pawn push. If, furthermore, the checking piece is a pawn,
350     // an en passant check evasion may be possible.
351     if (pos.ep_square() != SQ_NONE && (checkers & pos.pawns(them)))
352     {
353         to = pos.ep_square();
354         b1 = pos.pawn_attacks(them, to) & pos.pawns(us);
355
356         assert(b1 != EmptyBoardBB);
357
358         b1 &= not_pinned;
359         while (b1)
360         {
361             from = pop_1st_bit(&b1);
362
363             // Before generating the move, we have to make sure it is legal.
364             // This is somewhat tricky, because the two disappearing pawns may
365             // cause new "discovered checks".  We test this by removing the
366             // two relevant bits from the occupied squares bitboard, and using
367             // the low-level bitboard functions for bishop and rook attacks.
368             b2 = pos.occupied_squares();
369             clear_bit(&b2, from);
370             clear_bit(&b2, checksq);
371             if (!(  (bishop_attacks_bb(ksq, b2) & pos.bishops_and_queens(them))
372                   ||(rook_attacks_bb(ksq, b2)   & pos.rooks_and_queens(them))))
373
374                  (*mlist++).move = make_ep_move(from, to);
375         }
376     }
377   }
378   return int(mlist - mlist_start);
379 }
380
381
382 /// generate_legal_moves() computes a complete list of legal moves in the
383 /// current position.  This function is not very fast, and should be used
384 /// only in situations where performance is unimportant.  It wouldn't be
385 /// very hard to write an efficient legal move generator, but for the moment
386 /// we don't need it.
387
388 int generate_legal_moves(const Position& pos, MoveStack* mlist) {
389
390   assert(pos.is_ok());
391
392   if (pos.is_check())
393       return generate_evasions(pos, mlist);
394
395   // Generate pseudo-legal moves
396   int n = generate_captures(pos, mlist);
397   n += generate_noncaptures(pos, mlist + n);
398
399   Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
400
401   // Remove illegal moves from the list
402   for (int i = 0; i < n; i++)
403       if (!pos.pl_move_is_legal(mlist[i].move, pinned))
404           mlist[i--].move = mlist[--n].move;
405
406   return n;
407 }
408
409
410 /// move_is_legal() takes a position and a (not necessarily pseudo-legal)
411 /// move and a pinned pieces bitboard as input, and tests whether
412 /// the move is legal.  If the move is legal, the move itself is
413 /// returned. If not, the function returns false.  This function must
414 /// only be used when the side to move is not in check.
415
416 bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) {
417
418   assert(pos.is_ok());
419   assert(!pos.is_check());
420   assert(move_is_ok(m));
421   assert(pinned == pos.pinned_pieces(pos.side_to_move()));
422
423   Color us = pos.side_to_move();
424   Color them = opposite_color(us);
425   Square from = move_from(m);
426   Piece pc = pos.piece_on(from);
427
428   // If the from square is not occupied by a piece belonging to the side to
429   // move, the move is obviously not legal.
430   if (color_of_piece(pc) != us)
431       return false;
432
433   Square to = move_to(m);
434
435   // En passant moves
436   if (move_is_ep(m))
437   {
438       // The piece must be a pawn and destination square must be the
439       // en passant square.
440       if (   type_of_piece(pc) != PAWN
441           || to != pos.ep_square())
442           return false;
443
444       assert(pos.square_is_empty(to));
445       assert(pos.piece_on(to - pawn_push(us)) == pawn_of_color(them));
446
447       // The move is pseudo-legal, check if it is also legal
448       return pos.pl_move_is_legal(m, pinned);
449   }
450
451   // Castling moves
452   if (move_is_short_castle(m))
453   {
454       // The piece must be a king and side to move must still have
455       // the right to castle kingside.
456       if (   type_of_piece(pc) != KING
457           ||!pos.can_castle_kingside(us))
458           return false;
459
460       assert(from == pos.king_square(us));
461       assert(to == pos.initial_kr_square(us));
462       assert(pos.piece_on(to) == rook_of_color(us));
463
464       Square g1 = relative_square(us, SQ_G1);
465       Square f1 = relative_square(us, SQ_F1);
466       Square s;
467       bool illegal = false;
468
469       // Check if any of the squares between king and rook
470       // is occupied or under attack.
471       for (s = Min(from, g1); s <= Max(from, g1); s++)
472           if (  (s != from && s != to && !pos.square_is_empty(s))
473               || pos.square_is_attacked(s, them))
474               illegal = true;
475
476       // Check if any of the squares between king and rook
477       // is occupied.
478       for (s = Min(to, f1); s <= Max(to, f1); s++)
479           if (s != from && s != to && !pos.square_is_empty(s))
480               illegal = true;
481
482       return !illegal;
483   }
484
485   if (move_is_long_castle(m))
486   {
487       // The piece must be a king and side to move must still have
488       // the right to castle kingside.
489       if (   type_of_piece(pc) != KING
490           ||!pos.can_castle_queenside(us))
491           return false;
492
493       assert(from == pos.king_square(us));
494       assert(to == pos.initial_qr_square(us));
495       assert(pos.piece_on(to) == rook_of_color(us));
496
497       Square c1 = relative_square(us, SQ_C1);
498       Square d1 = relative_square(us, SQ_D1);
499       Square s;
500       bool illegal = false;
501
502       for (s = Min(from, c1); s <= Max(from, c1); s++)
503           if(  (s != from && s != to && !pos.square_is_empty(s))
504              || pos.square_is_attacked(s, them))
505               illegal = true;
506
507       for (s = Min(to, d1); s <= Max(to, d1); s++)
508           if(s != from && s != to && !pos.square_is_empty(s))
509               illegal = true;
510
511       if (   square_file(to) == FILE_B
512           && (   pos.piece_on(to + DELTA_W) == rook_of_color(them)
513               || pos.piece_on(to + DELTA_W) == queen_of_color(them)))
514           illegal = true;
515
516       return !illegal;
517   }
518
519   // Normal moves
520
521   // The destination square cannot be occupied by a friendly piece
522   if (pos.color_of_piece_on(to) == us)
523       return false;
524
525   // Proceed according to the type of the moving piece.
526   if (type_of_piece(pc) == PAWN)
527   {
528       // If the destination square is on the 8/1th rank, the move must
529       // be a promotion.
530       if (   (  (square_rank(to) == RANK_8 && us == WHITE)
531               ||(square_rank(to) == RANK_1 && us != WHITE))
532            && !move_promotion(m))
533           return false;
534
535       // Proceed according to the square delta between the source and
536       // destionation squares.
537       switch (to - from)
538       {
539       case DELTA_NW:
540       case DELTA_NE:
541       case DELTA_SW:
542       case DELTA_SE:
543       // Capture. The destination square must be occupied by an enemy
544       // piece (en passant captures was handled earlier).
545           if (pos.color_of_piece_on(to) != them)
546               return false;
547           break;
548
549       case DELTA_N:
550       case DELTA_S:
551       // Pawn push. The destination square must be empty.
552           if (!pos.square_is_empty(to))
553               return false;
554           break;
555
556       case DELTA_NN:
557       // Double white pawn push. The destination square must be on the fourth
558       // rank, and both the destination square and the square between the
559       // source and destination squares must be empty.
560       if (   square_rank(to) != RANK_4
561           || !pos.square_is_empty(to)
562           || !pos.square_is_empty(from + DELTA_N))
563           return false;
564           break;
565
566       case DELTA_SS:
567       // Double black pawn push. The destination square must be on the fifth
568       // rank, and both the destination square and the square between the
569       // source and destination squares must be empty.
570           if (   square_rank(to) != RANK_5
571               || !pos.square_is_empty(to)
572               || !pos.square_is_empty(from + DELTA_S))
573               return false;
574           break;
575
576       default:
577           return false;
578       }
579       // The move is pseudo-legal, check if it is also legal
580       return pos.pl_move_is_legal(m, pinned);
581   }
582
583   // Luckly we can handle all the other pieces in one go
584   return (   pos.piece_attacks_square(from, to)
585           && pos.pl_move_is_legal(m, pinned)
586           && !move_promotion(m));
587 }
588
589
590 namespace {
591
592   template<PieceType Piece>
593   MoveStack* generate_piece_moves(const Position& pos, MoveStack* mlist, Color us, Bitboard target) {
594
595     Square from;
596     Bitboard b;
597
598     for (int i = 0, e = pos.piece_count(us, Piece); i < e; i++)
599     {
600         from = pos.piece_list(us, Piece, i);
601         b = pos.piece_attacks<Piece>(from) & target;
602         SERIALIZE_MOVES(b);
603     }
604     return mlist;
605   }
606
607   template<>
608   MoveStack* generate_piece_moves<KING>(const Position& pos, MoveStack* mlist, Color us, Bitboard target) {
609
610     Bitboard b;
611     Square from = pos.king_square(us);
612
613     b = pos.piece_attacks<KING>(from) & target;
614     SERIALIZE_MOVES(b);
615     return mlist;
616   }
617
618   template<PieceType Piece>
619   MoveStack* generate_piece_blocking_evasions(const Position& pos, Bitboard b,
620                                               Bitboard blockSquares, MoveStack* mlist) {
621     while (b)
622     {
623         Square from = pop_1st_bit(&b);
624         Bitboard bb = pos.piece_attacks<Piece>(from) & blockSquares;
625         SERIALIZE_MOVES(bb);
626     }
627     return mlist;
628   }
629
630
631   template<Color Us, Color Them, Bitboard TRank8BB, SquareDelta TDELTA_NE,
632            SquareDelta TDELTA_NW, SquareDelta TDELTA_N
633           >
634   MoveStack* do_generate_pawn_captures(const Position& pos, MoveStack* mlist) {
635
636     Square to;
637     Bitboard pawns = pos.pawns(Us);
638     Bitboard enemyPieces = pos.pieces_of_color(Them);
639
640     // Captures in the a1-h8 (a8-h1 for black) direction
641     Bitboard b1 = (Us == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces;
642
643     // Capturing promotions
644     Bitboard b2 = b1 & TRank8BB;
645     while (b2)
646     {
647         to = pop_1st_bit(&b2);
648         (*mlist++).move = make_promotion_move(to - TDELTA_NE, to, QUEEN);
649     }
650
651     // Capturing non-promotions
652     b2 = b1 & ~TRank8BB;
653     while (b2)
654     {
655         to = pop_1st_bit(&b2);
656         (*mlist++).move = make_move(to - TDELTA_NE, to);
657     }
658
659     // Captures in the h1-a8 (h8-a1 for black) direction
660     b1 = (Us == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces;
661
662     // Capturing promotions
663     b2 = b1 & TRank8BB;
664     while (b2)
665     {
666         to = pop_1st_bit(&b2);
667         (*mlist++).move = make_promotion_move(to - TDELTA_NW, to, QUEEN);
668     }
669
670     // Capturing non-promotions
671     b2 = b1 & ~TRank8BB;
672     while (b2)
673     {
674         to = pop_1st_bit(&b2);
675         (*mlist++).move = make_move(to - TDELTA_NW, to);
676     }
677
678     // Non-capturing promotions
679     b1 = (Us == WHITE ? pawns << 8 : pawns >> 8) & pos.empty_squares() & TRank8BB;
680     while (b1)
681     {
682         to = pop_1st_bit(&b1);
683         (*mlist++).move = make_promotion_move(to - TDELTA_N, to, QUEEN);
684     }
685
686     // En passant captures
687     if (pos.ep_square() != SQ_NONE)
688     {
689         assert(Us != WHITE || square_rank(pos.ep_square()) == RANK_6);
690         assert(Us != BLACK || square_rank(pos.ep_square()) == RANK_3);
691
692         b1 = pawns & pos.pawn_attacks(Them, pos.ep_square());
693         assert(b1 != EmptyBoardBB);
694
695         while (b1)
696         {
697             to = pop_1st_bit(&b1);
698             (*mlist++).move = make_ep_move(to, pos.ep_square());
699         }
700     }
701     return mlist;
702   }
703
704   template<Color Us, Color Them, Bitboard TRank8BB, Bitboard TRank3BB,
705            SquareDelta TDELTA_NE, SquareDelta TDELTA_NW, SquareDelta TDELTA_N
706           >
707   MoveStack* do_generate_pawn_noncaptures(const Position& pos, MoveStack* mlist) {
708
709     Bitboard pawns = pos.pawns(Us);
710     Bitboard enemyPieces = pos.pieces_of_color(Them);
711     Bitboard emptySquares = pos.empty_squares();
712     Bitboard b1, b2;
713     Square to;
714
715     // Underpromotion captures in the a1-h8 (a8-h1 for black) direction
716     b1 = (Us == WHITE ? pawns << 9 : pawns >> 7) & ~FileABB & enemyPieces & TRank8BB;
717     while (b1)
718     {
719         to = pop_1st_bit(&b1);
720         (*mlist++).move = make_promotion_move(to - TDELTA_NE, to, ROOK);
721         (*mlist++).move = make_promotion_move(to - TDELTA_NE, to, BISHOP);
722         (*mlist++).move = make_promotion_move(to - TDELTA_NE, to, KNIGHT);
723     }
724
725     // Underpromotion captures in the h1-a8 (h8-a1 for black) direction
726     b1 = (Us == WHITE ? pawns << 7 : pawns >> 9) & ~FileHBB & enemyPieces & TRank8BB;
727     while (b1)
728     {
729         to = pop_1st_bit(&b1);
730         (*mlist++).move = make_promotion_move(to - TDELTA_NW, to, ROOK);
731         (*mlist++).move = make_promotion_move(to - TDELTA_NW, to, BISHOP);
732         (*mlist++).move = make_promotion_move(to - TDELTA_NW, to, KNIGHT);
733     }
734
735     // Single pawn pushes
736     b1 = (Us == WHITE ? pawns << 8 : pawns >> 8) & emptySquares;
737     b2 = b1 & TRank8BB;
738     while (b2)
739     {
740       to = pop_1st_bit(&b2);
741       (*mlist++).move = make_promotion_move(to - TDELTA_N, to, ROOK);
742       (*mlist++).move = make_promotion_move(to - TDELTA_N, to, BISHOP);
743       (*mlist++).move = make_promotion_move(to - TDELTA_N, to, KNIGHT);
744     }
745     b2 = b1 & ~TRank8BB;
746     while (b2)
747     {
748         to = pop_1st_bit(&b2);
749         (*mlist++).move = make_move(to - TDELTA_N, to);
750     }
751
752     // Double pawn pushes
753     b2 = (Us == WHITE ? (b1 & TRank3BB) << 8 : (b1 & TRank3BB) >> 8) & emptySquares;
754     while (b2)
755     {
756       to = pop_1st_bit(&b2);
757       (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
758     }
759     return mlist;
760   }
761
762
763   template<Color Us, Color Them, Bitboard TRank8BB, Bitboard TRank3BB, SquareDelta TDELTA_N>
764   MoveStack* do_generate_pawn_checks(const Position& pos, Bitboard dc, Square ksq, MoveStack* mlist)
765   {
766     // Pawn moves which give discovered check. This is possible only if the
767     // pawn is not on the same file as the enemy king, because we don't
768     // generate captures.
769     Bitboard empty = pos.empty_squares();
770
771     // Find all friendly pawns not on the enemy king's file
772     Bitboard b1 = pos.pawns(Us) & ~file_bb(ksq), b2, b3;
773
774     // Discovered checks, single pawn pushes
775     b2 = b3 = (Us == WHITE ? (b1 & dc) << 8 : (b1 & dc) >> 8) & ~TRank8BB & empty;
776     while (b3)
777     {
778         Square to = pop_1st_bit(&b3);
779         (*mlist++).move = make_move(to - TDELTA_N, to);
780     }
781
782     // Discovered checks, double pawn pushes
783     b3 = (Us == WHITE ? (b2 & TRank3BB) << 8 : (b2 & TRank3BB) >> 8) & empty;
784     while (b3)
785     {
786         Square to = pop_1st_bit(&b3);
787         (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
788     }
789
790     // Direct checks. These are possible only for pawns on neighboring files
791     // of the enemy king
792
793     b1 &= (~dc & neighboring_files_bb(ksq)); // FIXME why ~dc ??
794
795     // Direct checks, single pawn pushes
796     b2 = (Us == WHITE ? b1 << 8 : b1 >> 8) & empty;
797     b3 = b2 & pos.pawn_attacks(Them, ksq);
798     while (b3)
799     {
800         Square to = pop_1st_bit(&b3);
801         (*mlist++).move = make_move(to - TDELTA_N, to);
802     }
803
804     // Direct checks, double pawn pushes
805     b3 =  (Us == WHITE ? (b2 & TRank3BB) << 8 : (b2 & TRank3BB) >> 8)
806         & empty
807         & pos.pawn_attacks(Them, ksq);
808
809     while (b3)
810     {
811         Square to = pop_1st_bit(&b3);
812         (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
813     }
814     return mlist;
815   }
816
817   template<PieceType Piece>
818   MoveStack* generate_piece_checks(const Position& pos, Bitboard target, Bitboard dc,
819                                    Square ksq, MoveStack* mlist) {
820     // Discovered checks
821     Bitboard b = target & dc;
822     while (b)
823     {
824         Square from = pop_1st_bit(&b);
825         Bitboard bb = pos.piece_attacks<Piece>(from) & pos.empty_squares();
826         SERIALIZE_MOVES(bb);
827     }
828     // Direct checks
829     b = target & ~dc;
830     Bitboard checkSqs = pos.piece_attacks<Piece>(ksq) & pos.empty_squares();
831     while (b)
832     {
833         Square from = pop_1st_bit(&b);
834         Bitboard bb = pos.piece_attacks<Piece>(from) & checkSqs;
835         SERIALIZE_MOVES(bb);
836     }
837     return mlist;
838   }
839
840   MoveStack* generate_piece_checks_king(const Position& pos, Square from, Bitboard dc,
841                                         Square ksq, MoveStack* mlist) {
842     if (bit_is_set(dc, from))
843     {
844         Bitboard b =   pos.piece_attacks<KING>(from)
845                      & pos.empty_squares()
846                      & ~QueenPseudoAttacks[ksq];
847         SERIALIZE_MOVES(b);
848     }
849     return mlist;
850   }
851
852
853   template<Color Us, Rank TRANK_8, Bitboard TRank3BB, SquareDelta TDELTA_N>
854   MoveStack* do_generate_pawn_blocking_evasions(const Position& pos, Bitboard not_pinned,
855                                                 Bitboard blockSquares, MoveStack* mlist) {
856     Square to;
857
858     // Find non-pinned pawns
859     Bitboard b1 = pos.pawns(Us) & not_pinned;
860
861     // Single pawn pushes. We don't have to AND with empty squares here,
862     // because the blocking squares will always be empty.
863     Bitboard b2 = (Us == WHITE ? b1 << 8 : b1 >> 8) & blockSquares;
864     while (b2)
865     {
866         to = pop_1st_bit(&b2);
867
868         assert(pos.piece_on(to) == EMPTY);
869
870         if (square_rank(to) == TRANK_8)
871         {
872             (*mlist++).move = make_promotion_move(to - TDELTA_N, to, QUEEN);
873             (*mlist++).move = make_promotion_move(to - TDELTA_N, to, ROOK);
874             (*mlist++).move = make_promotion_move(to - TDELTA_N, to, BISHOP);
875             (*mlist++).move = make_promotion_move(to - TDELTA_N, to, KNIGHT);
876         } else
877             (*mlist++).move = make_move(to - TDELTA_N, to);
878     }
879
880     // Double pawn pushes
881     b2 = (Us == WHITE ? b1 << 8 : b1 >> 8) & pos.empty_squares() & TRank3BB;
882     b2 = (Us == WHITE ? b2 << 8 : b2 >> 8) & blockSquares;;
883     while (b2)
884     {
885         to = pop_1st_bit(&b2);
886
887         assert(pos.piece_on(to) == EMPTY);
888         assert(Us != WHITE || square_rank(to) == RANK_4);
889         assert(Us != BLACK || square_rank(to) == RANK_5);
890
891         (*mlist++).move = make_move(to - TDELTA_N - TDELTA_N, to);
892     }
893     return mlist;
894   }
895
896   MoveStack* generate_castle_moves(const Position& pos, MoveStack* mlist, unsigned side) {
897
898     Color us = pos.side_to_move();
899
900     if (pos.can_castle_kingside(us) && (side & KING_SIDE))
901     {
902         Color them = opposite_color(us);
903         Square ksq = pos.king_square(us);
904
905         assert(pos.piece_on(ksq) == king_of_color(us));
906
907         Square rsq = pos.initial_kr_square(us);
908         Square g1 = relative_square(us, SQ_G1);
909         Square f1 = relative_square(us, SQ_F1);
910         Square s;
911         bool illegal = false;
912
913         assert(pos.piece_on(rsq) == rook_of_color(us));
914
915         for (s = Min(ksq, g1); s <= Max(ksq, g1); s++)
916             if (  (s != ksq && s != rsq && pos.square_is_occupied(s))
917                 || pos.square_is_attacked(s, them))
918                 illegal = true;
919
920         for (s = Min(rsq, f1); s <= Max(rsq, f1); s++)
921             if (s != ksq && s != rsq && pos.square_is_occupied(s))
922                 illegal = true;
923
924         if (!illegal)
925             (*mlist++).move = make_castle_move(ksq, rsq);
926     }
927
928     if (pos.can_castle_queenside(us) && (side & QUEEN_SIDE))
929     {
930         Color them = opposite_color(us);
931         Square ksq = pos.king_square(us);
932
933         assert(pos.piece_on(ksq) == king_of_color(us));
934
935         Square rsq = pos.initial_qr_square(us);
936         Square c1 = relative_square(us, SQ_C1);
937         Square d1 = relative_square(us, SQ_D1);
938         Square s;
939         bool illegal = false;
940
941         assert(pos.piece_on(rsq) == rook_of_color(us));
942
943         for (s = Min(ksq, c1); s <= Max(ksq, c1); s++)
944             if (  (s != ksq && s != rsq && pos.square_is_occupied(s))
945                 || pos.square_is_attacked(s, them))
946                 illegal = true;
947
948         for (s = Min(rsq, d1); s <= Max(rsq, d1); s++)
949             if (s != ksq && s != rsq && pos.square_is_occupied(s))
950                 illegal = true;
951
952       if (   square_file(rsq) == FILE_B
953           && (   pos.piece_on(relative_square(us, SQ_A1)) == rook_of_color(them)
954               || pos.piece_on(relative_square(us, SQ_A1)) == queen_of_color(them)))
955           illegal = true;
956
957       if (!illegal)
958           (*mlist++).move = make_castle_move(ksq, rsq);
959     }
960     return mlist;
961   }
962
963   bool castling_is_check(const Position& pos, CastlingSide side) {
964
965     // After castling opponent king is attacked by the castled rook?
966     File rookFile = (side == QUEEN_SIDE ? FILE_D : FILE_F);
967     Color us = pos.side_to_move();
968     Square ksq = pos.king_square(us);
969     Bitboard occ = pos.occupied_squares(), oppKingBB = EmptyBoardBB;
970
971     set_bit(&oppKingBB, pos.king_square(opposite_color(us)));
972     clear_bit(&occ, ksq); // Remove our king from the board
973     Square rsq = make_square(rookFile, square_rank(ksq));
974     return (rook_attacks_bb(rsq, occ) & oppKingBB);
975   }
976 }