Movegen: further simplify generate_move_if_legal
[stockfish] / src / movegen.cpp
1 /*
2   Glaurung, a UCI chess playing engine.
3   Copyright (C) 2004-2008 Tord Romstad
4
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.
9   
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.
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   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);
45
46 }
47
48
49 ////
50 //// Functions
51 ////
52
53
54 /// generate_captures generates() all pseudo-legal captures and queen
55 /// promotions.  The return value is the number of moves generated.
56
57 int generate_captures(const Position& pos, MoveStack* mlist) {
58
59   assert(pos.is_ok());
60   assert(!pos.is_check());
61
62   Color us = pos.side_to_move();
63   Bitboard target = pos.pieces_of_color(opposite_color(us));
64   int n;
65
66   if (us == WHITE)
67       n = generate_white_pawn_captures(pos, mlist);
68   else
69       n = generate_black_pawn_captures(pos, mlist);
70
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);
76   return n;
77 }
78
79
80 /// generate_noncaptures() generates all pseudo-legal non-captures and 
81 /// underpromotions.  The return value is the number of moves generated.
82
83 int generate_noncaptures(const Position& pos, MoveStack *mlist) {
84
85   assert(pos.is_ok());
86   assert(!pos.is_check());
87
88   Color us = pos.side_to_move();
89   Bitboard target = pos.empty_squares();
90   int n;
91
92   if (us == WHITE)
93       n = generate_white_pawn_noncaptures(pos, mlist);
94   else
95       n = generate_black_pawn_noncaptures(pos, mlist);
96
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);
103   return n;
104 }
105
106
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.  
110
111 int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) {
112
113   assert(pos.is_ok());
114   assert(!pos.is_check());
115
116   Color us, them;
117   Square ksq, from, to;
118   Bitboard empty, checkSqs, b1, b2, b3;
119   int n = 0;
120
121   us = pos.side_to_move();
122   them = opposite_color(us);
123
124   ksq = pos.king_square(them);
125   assert(pos.piece_on(ksq) == king_of_color(them));
126
127   dc = pos.discovered_check_candidates(us);
128   empty = pos.empty_squares();
129   
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++.  :-(
132
133   if (us == WHITE)
134   {
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.
138
139     // Find all friendly pawns not on the enemy king's file:
140     b1 = pos.pawns(us) & ~file_bb(ksq);
141
142     // Discovered checks, single pawn pushes:
143     b2 = b3 = ((b1 & dc) << 8) & ~Rank8BB & empty;
144     while(b3) {
145       to = pop_1st_bit(&b3);
146       mlist[n++].move = make_move(to - DELTA_N, to);
147     }
148
149     // Discovered checks, double pawn pushes:
150     b3 = ((b2 & Rank3BB) << 8) & empty;
151     while(b3) {
152       to = pop_1st_bit(&b3);
153       mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to);
154     }
155
156     // Direct checks.  These are possible only for pawns on neighboring files
157     // of the enemy king:
158
159     b1 &= (~dc & neighboring_files_bb(ksq));
160
161     // Direct checks, single pawn pushes:
162     b2 = (b1 << 8) & empty;
163     b3 = b2 & pos.black_pawn_attacks(ksq);
164     while(b3) {
165       to = pop_1st_bit(&b3);
166       mlist[n++].move = make_move(to - DELTA_N, to);
167     }
168
169     // Direct checks, double pawn pushes:
170     b3 = ((b2 & Rank3BB) << 8) & empty & pos.black_pawn_attacks(ksq);
171     while(b3) {
172       to = pop_1st_bit(&b3);
173       mlist[n++].move = make_move(to - DELTA_N - DELTA_N, to);
174     }
175   }
176   else { // (us == BLACK)
177
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.
181
182     // Find all friendly pawns not on the enemy king's file:
183     b1 = pos.pawns(us) & ~file_bb(ksq);
184
185     // Discovered checks, single pawn pushes:
186     b2 = b3 = ((b1 & dc) >> 8) & ~Rank1BB & empty;
187     while(b3) {
188       to = pop_1st_bit(&b3);
189       mlist[n++].move = make_move(to - DELTA_S, to);
190     }
191
192     // Discovered checks, double pawn pushes:
193     b3 = ((b2 & Rank6BB) >> 8) & empty;
194     while(b3) {
195       to = pop_1st_bit(&b3);
196       mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to);
197     }
198
199     // Direct checks.  These are possible only for pawns on neighboring files
200     // of the enemy king:
201
202     b1 &= (~dc & neighboring_files_bb(ksq));
203
204     // Direct checks, single pawn pushes:
205     b2 = (b1 >> 8) & empty;
206     b3 = b2 & pos.white_pawn_attacks(ksq);
207     while(b3) {
208       to = pop_1st_bit(&b3);
209       mlist[n++].move = make_move(to - DELTA_S, to);
210     }
211
212     // Direct checks, double pawn pushes:
213     b3 = ((b2 & Rank6BB) >> 8) & empty & pos.black_pawn_attacks(ksq);
214     while(b3) {
215       to = pop_1st_bit(&b3);
216       mlist[n++].move = make_move(to - DELTA_S - DELTA_S, to);
217     }
218   }
219
220   // Knight moves
221   b1 = pos.knights(us);
222   if(b1) {
223     // Discovered knight checks:
224     b2 = b1 & dc;
225     while(b2) {
226       from = pop_1st_bit(&b2);
227       b3 = pos.knight_attacks(from) & empty;
228       while(b3) {
229         to = pop_1st_bit(&b3);
230         mlist[n++].move = make_move(from, to);
231       }
232     }
233     
234     // Direct knight checks:
235     b2 = b1 & ~dc;
236     checkSqs = pos.knight_attacks(ksq) & empty;
237     while(b2) {
238       from = pop_1st_bit(&b2);
239       b3 = pos.knight_attacks(from) & checkSqs;
240       while(b3) {
241         to = pop_1st_bit(&b3);
242         mlist[n++].move = make_move(from, to);
243       }
244     }
245   }
246
247   // Bishop moves
248   b1 = pos.bishops(us);
249   if(b1) {
250     // Discovered bishop checks:
251     b2 = b1 & dc;
252     while(b2) {
253       from = pop_1st_bit(&b2);
254       b3 = pos.bishop_attacks(from) & empty;
255       while(b3) {
256         to = pop_1st_bit(&b3);
257         mlist[n++].move = make_move(from, to);
258       }
259     }
260     
261     // Direct bishop checks:
262     b2 = b1 & ~dc;
263     checkSqs = pos.bishop_attacks(ksq) & empty;
264     while(b2) {
265       from = pop_1st_bit(&b2);
266       b3 = pos.bishop_attacks(from) & checkSqs;
267       while(b3) {
268         to = pop_1st_bit(&b3);
269         mlist[n++].move = make_move(from, to);
270       }
271     }
272   }
273
274   // Rook moves
275   b1 = pos.rooks(us);
276   if(b1) {
277     // Discovered rook checks:
278     b2 = b1 & dc;
279     while(b2) {
280       from = pop_1st_bit(&b2);
281       b3 = pos.rook_attacks(from) & empty;
282       while(b3) {
283         to = pop_1st_bit(&b3);
284         mlist[n++].move = make_move(from, to);
285       }
286     }
287     
288     // Direct rook checks:
289     b2 = b1 & ~dc;
290     checkSqs = pos.rook_attacks(ksq) & empty;
291     while(b2) {
292       from = pop_1st_bit(&b2);
293       b3 = pos.rook_attacks(from) & checkSqs;
294       while(b3) {
295         to = pop_1st_bit(&b3);
296         mlist[n++].move = make_move(from, to);
297       }
298     }
299   }
300
301   // Queen moves
302   b1 = pos.queens(us);
303   if(b1) {
304     // Discovered queen checks are impossible!
305
306     // Direct queen checks:
307     checkSqs = pos.queen_attacks(ksq) & empty;
308     while(b1) {
309       from = pop_1st_bit(&b1);
310       b2 = pos.queen_attacks(from) & checkSqs;
311       while(b2) {
312         to = pop_1st_bit(&b2);
313         mlist[n++].move = make_move(from, to);
314       }
315     }
316   }
317
318   // King moves
319   from = pos.king_square(us);
320   if(bit_is_set(dc, from)) {
321     b1 = pos.king_attacks(from) & empty & ~QueenPseudoAttacks[ksq];
322     while(b1) {
323       to = pop_1st_bit(&b1);
324       mlist[n++].move = make_move(from, to);
325     }
326   }
327
328   // TODO: Castling moves!
329   
330   return n;
331 }
332
333
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
338
339 int generate_evasions(const Position &pos, MoveStack *mlist) {
340
341   assert(pos.is_ok());
342   assert(pos.is_check());
343
344   Color us, them;
345   Bitboard checkers = pos.checkers();
346   Bitboard pinned, b1, b2;
347   Square ksq, from, to;
348   int n = 0;
349
350   us = pos.side_to_move();
351   them = opposite_color(us);
352
353   ksq = pos.king_square(us);
354   assert(pos.piece_on(ksq) == king_of_color(us));
355   
356   // Generate evasions for king:
357   b1 = pos.king_attacks(ksq) & ~pos.pieces_of_color(us);
358   b2 = pos.occupied_squares();
359   clear_bit(&b2, ksq);
360   while(b1) {
361     to = pop_1st_bit(&b1);
362
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))
372         == EmptyBoardBB) &&
373        ((rook_attacks_bb(to, b2) & pos.rooks_and_queens(them)) == EmptyBoardBB))
374       mlist[n++].move = make_move(ksq, to);
375   }
376
377
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);
384
385     // Find pinned pieces:
386     pinned = pos.pinned_pieces(us);
387
388     // Generate captures of the checking piece:
389
390     // Pawn captures:
391     b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & ~pinned;
392     while(b1) {
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);
399       }
400       else
401         mlist[n++].move = make_move(from, checksq);
402     }
403
404     // Knight captures:
405     b1 = pos.knight_attacks(checksq) & pos.knights(us) & ~pinned;
406     while(b1) {
407       from = pop_1st_bit(&b1);
408       mlist[n++].move = make_move(from, checksq);
409     }
410
411     // Bishop and queen captures:
412     b1 = pos.bishop_attacks(checksq) & pos.bishops_and_queens(us)
413       & ~pinned;
414     while(b1) {
415       from = pop_1st_bit(&b1);
416       mlist[n++].move = make_move(from, checksq);
417     }
418
419     // Rook and queen captures:
420     b1 = pos.rook_attacks(checksq) & pos.rooks_and_queens(us)
421       & ~pinned;
422     while(b1) {
423       from = pop_1st_bit(&b1);
424       mlist[n++].move = make_move(from, checksq);
425     }
426
427     // Blocking check evasions are possible only if the checking piece is
428     // a slider:
429     if(checkers & pos.sliders()) {
430       Bitboard blockSquares = squares_between(checksq, ksq);
431       assert((pos.occupied_squares() & blockSquares) == EmptyBoardBB);
432
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. :-(
436       if(us == WHITE) {
437         // Find non-pinned pawns:
438         b1 = pos.pawns(WHITE) & ~pinned;
439
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;
443         while(b2) {
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);
451           }
452           else
453             mlist[n++].move = make_move(to - DELTA_N, to);
454         }
455         // Double pawn pushes.
456         b2 = (((b1 << 8) & pos.empty_squares() & Rank3BB) << 8) & blockSquares;
457         while(b2) {
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);
462         }
463       }
464       else { // (us == BLACK)
465         // Find non-pinned pawns:
466         b1 = pos.pawns(BLACK) & ~pinned;
467
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;
471         while(b2) {
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);
479           }
480           else
481             mlist[n++].move = make_move(to - DELTA_S, to);
482         }
483         // Double pawn pushes.
484         b2 = (((b1 >> 8) & pos.empty_squares() & Rank6BB) >> 8) & blockSquares;
485         while(b2) {
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);
490         }
491       }
492
493       // Knight moves
494       b1 = pos.knights(us) & ~pinned;
495       while(b1) {
496         from = pop_1st_bit(&b1);
497         b2 = pos.knight_attacks(from) & blockSquares;
498         while(b2) {
499           to = pop_1st_bit(&b2);
500           mlist[n++].move = make_move(from, to);
501         }
502       }
503       
504       // Bishop moves
505       b1 = pos.bishops(us) & ~pinned;
506       while(b1) {
507         from = pop_1st_bit(&b1);
508         b2 = pos.bishop_attacks(from) & blockSquares;
509         while(b2) {
510           to = pop_1st_bit(&b2);
511           mlist[n++].move = make_move(from, to);
512         }
513       }
514       
515       // Rook moves
516       b1 = pos.rooks(us) & ~pinned;
517       while(b1) {
518         from = pop_1st_bit(&b1);
519         b2 = pos.rook_attacks(from) & blockSquares;
520         while(b2) {
521           to = pop_1st_bit(&b2);
522           mlist[n++].move = make_move(from, to);
523         }
524       }
525       
526       // Queen moves
527       b1 = pos.queens(us) & ~pinned;
528       while(b1) {
529         from = pop_1st_bit(&b1);
530         b2 = pos.queen_attacks(from) & blockSquares;
531         while(b2) {
532           to = pop_1st_bit(&b2);
533           mlist[n++].move = make_move(from, to);
534         }
535       }
536     }
537
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);
547       b1 &= ~pinned;
548       while(b1) {
549         from = pop_1st_bit(&b1);
550
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))
560             == EmptyBoardBB) &&
561            ((rook_attacks_bb(ksq, b2) & pos.rooks_and_queens(them))
562             == EmptyBoardBB))
563           mlist[n++].move = make_ep_move(from, to);
564       }
565     }
566   }
567
568   return n;
569 }
570
571
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.
577
578 int generate_legal_moves(const Position& pos, MoveStack* mlist) {
579
580   assert(pos.is_ok());
581
582   if (pos.is_check())
583       return generate_evasions(pos, mlist);
584
585   // Generate pseudo-legal moves:
586   int n = generate_captures(pos, mlist);
587   n += generate_noncaptures(pos, mlist + n);
588
589   Bitboard pinned = pos.pinned_pieces(pos.side_to_move());
590
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;
595
596   return n;
597 }
598
599
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.
605
606 Move generate_move_if_legal(const Position &pos, Move m, Bitboard pinned) {
607
608   assert(pos.is_ok());
609   assert(!pos.is_check());
610   assert(move_is_ok(m));
611
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);
616
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)
620       return MOVE_NONE;
621
622   Square to = move_to(m);
623
624   // En passant moves
625   if (move_is_ep(m))
626   {
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())
631           return MOVE_NONE;
632
633       assert(pos.square_is_empty(to));
634       assert(pos.piece_on(to - pawn_push(us)) == pawn_of_color(them));
635
636       // The move is pseudo-legal.  If it is legal, return it.
637       return (pos.move_is_legal(m) ? m : MOVE_NONE);
638   }
639
640   // Castling moves
641   if (move_is_short_castle(m))
642   {
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))
647           return MOVE_NONE;
648
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));
652
653       Square g1 = relative_square(us, SQ_G1);
654       Square f1 = relative_square(us, SQ_F1);
655       Square s;
656       bool illegal = false;
657
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))
663               illegal = true;
664
665       // Check if any of the squares between king and rook
666       // is occupied.
667       for (s = Min(to, f1); s <= Max(to, f1); s++)
668           if (s != from && s != to && !pos.square_is_empty(s))
669               illegal = true;
670
671       return (!illegal ? m : MOVE_NONE);
672   }
673
674   if (move_is_long_castle(m))
675   {
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))
680           return MOVE_NONE;
681
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));
685
686       Square c1 = relative_square(us, SQ_C1);
687       Square d1 = relative_square(us, SQ_D1);
688       Square s;
689       bool illegal = false;
690
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))
694               illegal = true;
695
696       for (s = Min(to, d1); s <= Max(to, d1); s++)
697           if(s != from && s != to && !pos.square_is_empty(s))
698               illegal = true;
699
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)))
703           illegal = true;
704
705       return (!illegal ? m : MOVE_NONE);
706   }
707
708   // Normal moves
709
710   // The destination square cannot be occupied by a friendly piece
711   if (pos.color_of_piece_on(to) == us)
712       return MOVE_NONE;
713
714   // Proceed according to the type of the moving piece.
715   if (type_of_piece(pc) == PAWN)
716   {  
717       // If the destination square is on the 8/1th rank, the move must
718       // be a promotion.
719       if (   (  (square_rank(to) == RANK_8 && us == WHITE)
720               ||(square_rank(to) == RANK_1 && us != WHITE))
721            && !move_promotion(m))
722           return MOVE_NONE;
723
724       // Proceed according to the square delta between the source and
725       // destionation squares.
726       switch (to - from)
727       {
728       case DELTA_NW:
729       case DELTA_NE:
730       case DELTA_SW:
731       case DELTA_SE:
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)
735               return MOVE_NONE;
736           break;
737
738       case DELTA_N:
739       case DELTA_S:
740       // Pawn push. The destination square must be empty.
741           if (!pos.square_is_empty(to))
742               return MOVE_NONE;
743           break;
744
745       case DELTA_NN:
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))
752           return MOVE_NONE;
753           break;
754
755       case DELTA_SS:
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))
762               return MOVE_NONE;
763           break;
764
765       default:
766           return MOVE_NONE;
767       }
768       // The move is pseudo-legal.  Return it if it is legal.
769       return (pos.move_is_legal(m) ? m : MOVE_NONE);
770   }
771
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);
776 }
777
778
779 namespace {
780
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);
784     Bitboard b1, b2;
785     Square sq;
786     int n = 0;
787
788     // Captures in the a1-h8 direction:
789     b1 = (pawns << 9) & ~FileABB & enemyPieces;
790
791     // Promotions:
792     b2 = b1 & Rank8BB;
793     while(b2) {
794       sq = pop_1st_bit(&b2);
795       mlist[n++].move = make_promotion_move(sq - DELTA_NE, sq, QUEEN);
796     }
797
798     // Non-promotions:
799     b2 = b1 & ~Rank8BB;
800     while(b2) {
801       sq = pop_1st_bit(&b2);
802       mlist[n++].move = make_move(sq - DELTA_NE, sq);
803     }
804
805     // Captures in the h1-a8 direction:
806     b1 = (pawns << 7) & ~FileHBB & enemyPieces;
807
808     // Promotions:
809     b2 = b1 & Rank8BB;
810     while(b2) {
811       sq = pop_1st_bit(&b2);
812       mlist[n++].move = make_promotion_move(sq - DELTA_NW, sq, QUEEN);
813     }
814
815     // Non-promotions:
816     b2 = b1 & ~Rank8BB;
817     while(b2) {
818       sq = pop_1st_bit(&b2);
819       mlist[n++].move = make_move(sq - DELTA_NW, sq);
820     }
821
822     // Non-capturing promotions:
823     b1 = (pawns << 8) & pos.empty_squares() & Rank8BB;
824     while(b1)  {
825       sq = pop_1st_bit(&b1);
826       mlist[n++].move = make_promotion_move(sq - DELTA_N, sq, QUEEN);
827     }
828
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);
834       while(b1) {
835         sq = pop_1st_bit(&b1);
836         mlist[n++].move = make_ep_move(sq, pos.ep_square());
837       }
838     }
839
840     return n;
841   }
842
843
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);
847     Bitboard b1, b2;
848     Square sq;
849     int n = 0;
850
851     // Captures in the a8-h1 direction:
852     b1 = (pawns >> 7) & ~FileABB & enemyPieces;
853
854     // Promotions:
855     b2 = b1 & Rank1BB;
856     while(b2) {
857       sq = pop_1st_bit(&b2);
858       mlist[n++].move = make_promotion_move(sq - DELTA_SE, sq, QUEEN);
859     }
860
861     // Non-promotions:
862     b2 = b1 & ~Rank1BB;
863     while(b2) {
864       sq = pop_1st_bit(&b2);
865       mlist[n++].move = make_move(sq - DELTA_SE, sq);
866     }
867
868     // Captures in the h8-a1 direction:
869     b1 = (pawns >> 9) & ~FileHBB & enemyPieces;
870
871     // Promotions:
872     b2 = b1 & Rank1BB;
873     while(b2) {
874       sq = pop_1st_bit(&b2);
875       mlist[n++].move = make_promotion_move(sq - DELTA_SW, sq, QUEEN);
876     }
877
878     // Non-promotions:
879     b2 = b1 & ~Rank1BB;
880     while(b2) {
881       sq = pop_1st_bit(&b2);
882       mlist[n++].move = make_move(sq - DELTA_SW, sq);
883     }
884
885     // Non-capturing promotions:
886     b1 = (pawns >> 8) & pos.empty_squares() & Rank1BB;
887     while(b1)  {
888       sq = pop_1st_bit(&b1);
889       mlist[n++].move = make_promotion_move(sq - DELTA_S, sq, QUEEN);
890     }
891
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);
897       while(b1) {
898         sq = pop_1st_bit(&b1);
899         mlist[n++].move = make_ep_move(sq, pos.ep_square());
900       }
901     }
902
903     return n;
904   }
905     
906
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();
911     Bitboard b1, b2;
912     Square sq;
913     int n = 0;
914
915     // Underpromotion captures in the a1-h8 direction:
916     b1 = (pawns << 9) & ~FileABB & enemyPieces & Rank8BB;
917     while(b1) {
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);
922     }
923
924     // Underpromotion captures in the h1-a8 direction:
925     b1 = (pawns << 7) & ~FileHBB & enemyPieces & Rank8BB;
926     while(b1) {
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);
931     }
932
933     // Single pawn pushes:
934     b1 = (pawns << 8) & emptySquares;
935     b2 = b1 & Rank8BB;
936     while(b2) {
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);
941     }
942     b2 = b1 & ~Rank8BB;
943     while(b2) {
944       sq = pop_1st_bit(&b2);
945       mlist[n++].move = make_move(sq - DELTA_N, sq);
946     }
947
948     // Double pawn pushes:
949     b2 = ((b1 & Rank3BB) << 8) & emptySquares;
950     while(b2) {
951       sq = pop_1st_bit(&b2);
952       mlist[n++].move = make_move(sq - DELTA_N - DELTA_N, sq);
953     }
954
955     return n;
956   }
957
958
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();
963     Bitboard b1, b2;
964     Square sq;
965     int n = 0;
966
967     // Underpromotion captures in the a8-h1 direction:
968     b1 = (pawns >> 7) & ~FileABB & enemyPieces & Rank1BB;
969     while(b1) {
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);
974     }
975
976     // Underpromotion captures in the h8-a1 direction:
977     b1 = (pawns >> 9) & ~FileHBB & enemyPieces & Rank1BB;
978     while(b1) {
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);
983     }
984
985     // Single pawn pushes:
986     b1 = (pawns >> 8) & emptySquares;
987     b2 = b1 & Rank1BB;
988     while(b2) {
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);
993     }
994     b2 = b1 & ~Rank1BB;
995     while(b2) {
996       sq = pop_1st_bit(&b2);
997       mlist[n++].move = make_move(sq - DELTA_S, sq);
998     }
999     
1000     // Double pawn pushes:
1001     b2 = ((b1 & Rank6BB) >> 8) & emptySquares;
1002     while(b2) {
1003       sq = pop_1st_bit(&b2);
1004       mlist[n++].move = make_move(sq - DELTA_S - DELTA_S, sq);
1005     }
1006
1007     return n;
1008   }
1009
1010
1011   int generate_knight_moves(const Position &pos, MoveStack *mlist, 
1012                             Color side, Bitboard target) {
1013     Square from, to;
1014     Bitboard b;
1015     int i, n = 0;
1016
1017     for(i = 0; i < pos.knight_count(side); i++) {
1018       from = pos.knight_list(side, i);
1019       b = pos.knight_attacks(from) & target;
1020       while(b) {
1021         to = pop_1st_bit(&b);
1022         mlist[n++].move = make_move(from, to);
1023       }
1024     }
1025     return n;
1026   }
1027
1028
1029   int generate_bishop_moves(const Position &pos, MoveStack *mlist, 
1030                             Color side, Bitboard target) {
1031     Square from, to;
1032     Bitboard b;
1033     int i, n = 0;
1034
1035     for(i = 0; i < pos.bishop_count(side); i++) {
1036       from = pos.bishop_list(side, i);
1037       b = pos.bishop_attacks(from) & target;
1038       while(b) {
1039         to = pop_1st_bit(&b);
1040         mlist[n++].move = make_move(from, to);
1041       }
1042     }
1043     return n;
1044   }
1045
1046
1047   int generate_rook_moves(const Position &pos, MoveStack *mlist, 
1048                           Color side, Bitboard target) {
1049     Square from, to;
1050     Bitboard b;
1051     int i, n = 0;
1052
1053     for(i = 0; i < pos.rook_count(side); i++) {
1054       from = pos.rook_list(side, i);
1055       b = pos.rook_attacks(from) & target;
1056       while(b) {
1057         to = pop_1st_bit(&b);
1058         mlist[n++].move = make_move(from, to);
1059       }
1060     }
1061     return n;
1062   }
1063
1064
1065   int generate_queen_moves(const Position &pos, MoveStack *mlist, 
1066                            Color side, Bitboard target) {
1067     Square from, to;
1068     Bitboard b;
1069     int i, n = 0;
1070
1071     for(i = 0; i < pos.queen_count(side); i++) {
1072       from = pos.queen_list(side, i);
1073       b = pos.queen_attacks(from) & target;
1074       while(b) {
1075         to = pop_1st_bit(&b);
1076         mlist[n++].move = make_move(from, to);
1077       }
1078     }
1079     return n;
1080   }
1081
1082
1083   int generate_king_moves(const Position &pos, MoveStack *mlist, 
1084                           Square from, Bitboard target) {
1085     Square to;
1086     Bitboard b;
1087     int n = 0;
1088     
1089     b = pos.king_attacks(from) & target;
1090     while(b) {
1091       to = pop_1st_bit(&b);
1092       mlist[n++].move = make_move(from, to);
1093     }
1094     return n;
1095   }
1096
1097
1098   int generate_castle_moves(const Position &pos, MoveStack *mlist, Color us) {
1099     int n = 0;
1100
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));
1105       
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);
1110         Square s;
1111         bool illegal = false;
1112
1113         assert(pos.piece_on(rsq) == rook_of_color(us));
1114
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))
1118             illegal = true;
1119         for(s = Min(rsq, f1); s <= Max(rsq, f1); s++)
1120           if(s != ksq && s != rsq && pos.square_is_occupied(s))
1121             illegal = true;
1122
1123         if(!illegal)
1124           mlist[n++].move = make_castle_move(ksq, rsq);
1125       }
1126
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);
1131         Square s;
1132         bool illegal = false;
1133
1134         assert(pos.piece_on(rsq) == rook_of_color(us));
1135
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))
1139             illegal = true;
1140         for(s = Min(rsq, d1); s <= Max(rsq, d1); s++)
1141           if(s != ksq && s != rsq && pos.square_is_occupied(s))
1142             illegal = true;
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)))
1146            illegal = true;
1147                          
1148         if(!illegal)
1149           mlist[n++].move = make_castle_move(ksq, rsq);
1150       }
1151     }
1152
1153     return n;
1154   }
1155     
1156 }