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