12 #include "move_legal.h"
18 static void add_all_moves (list_t * list, const board_t * board);
19 static void add_castle_moves (list_t * list, const board_t * board);
21 static void add_pawn_move (list_t * list, int from, int to);
27 void gen_legal_moves(list_t * list, const board_t * board) {
30 ASSERT(board_is_ok(board));
32 gen_moves(list,board);
33 filter_legal(list,board);
38 void gen_moves(list_t * list, const board_t * board) {
41 ASSERT(board_is_ok(board));
45 add_all_moves(list,board);
46 if (!is_in_check(board,board->turn)) add_castle_moves(list,board);
51 static void add_all_moves(list_t * list, const board_t * board) {
55 const sint8 * ptr_inc;
60 ASSERT(list_is_ok(list));
61 ASSERT(board_is_ok(board));
66 for (ptr = board->list[me]; (from=*ptr) != SquareNone; ptr++) {
68 piece = board->square[from];
69 ASSERT(colour_equal(piece,me));
71 switch (piece_type(piece)) {
76 if (to == board->ep_square || colour_equal(board->square[to],opp)) {
77 add_pawn_move(list,from,to);
81 if (to == board->ep_square || colour_equal(board->square[to],opp)) {
82 add_pawn_move(list,from,to);
86 if (board->square[to] == Empty) {
87 add_pawn_move(list,from,to);
88 if (square_rank(from) == Rank2) {
90 if (board->square[to] == Empty) {
91 ASSERT(!square_is_promote(to));
92 list_add(list,move_make(from,to));
102 if (to == board->ep_square || colour_equal(board->square[to],opp)) {
103 add_pawn_move(list,from,to);
107 if (to == board->ep_square || colour_equal(board->square[to],opp)) {
108 add_pawn_move(list,from,to);
112 if (board->square[to] == Empty) {
113 add_pawn_move(list,from,to);
114 if (square_rank(from) == Rank7) {
116 if (board->square[to] == Empty) {
117 ASSERT(!square_is_promote(to));
118 list_add(list,move_make(from,to));
127 for (ptr_inc = KnightInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
129 capture = board->square[to];
130 if (capture == Empty || colour_equal(capture,opp)) {
131 list_add(list,move_make(from,to));
139 for (ptr_inc = BishopInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
140 for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {
141 list_add(list,move_make(from,to));
143 if (colour_equal(capture,opp)) {
144 list_add(list,move_make(from,to));
152 for (ptr_inc = RookInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
153 for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {
154 list_add(list,move_make(from,to));
156 if (colour_equal(capture,opp)) {
157 list_add(list,move_make(from,to));
165 for (ptr_inc = QueenInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
166 for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {
167 list_add(list,move_make(from,to));
169 if (colour_equal(capture,opp)) {
170 list_add(list,move_make(from,to));
178 for (ptr_inc = KingInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
180 capture = board->square[to];
181 if (capture == Empty || colour_equal(capture,opp)) {
182 list_add(list,move_make(from,to));
196 // add_castle_moves()
198 static void add_castle_moves(list_t * list, const board_t * board) {
202 int king_from, king_to;
203 int rook_from, rook_to;
208 ASSERT(list_is_ok(list));
209 ASSERT(board_is_ok(board));
211 ASSERT(!is_in_check(board,board->turn));
214 opp = colour_opp(me);
216 rank = colour_is_white(me) ? Rank1 : Rank8;
220 if (board->castle[me][SideH] != SquareNone) {
222 king_from = king_pos(board,me);
223 king_to = square_make(FileG,rank);
224 rook_from = board->castle[me][SideH];
225 rook_to = square_make(FileF,rank);
227 ASSERT(square_rank(king_from)==rank);
228 ASSERT(square_rank(rook_from)==rank);
229 ASSERT(board->square[king_from]==(King64|me)); // HACK
230 ASSERT(board->square[rook_from]==(Rook64|me)); // HACK
231 ASSERT(rook_from>king_from);
235 if (king_to != king_from) {
237 inc = (king_to > king_from) ? +1 : -1;
239 for (sq = king_from+inc; TRUE; sq += inc) {
241 if (sq != rook_from && board->square[sq] != Empty) legal = FALSE;
242 if (is_attacked(board,sq,opp)) legal = FALSE;
244 if (sq == king_to) break;
248 if (rook_to != rook_from) {
250 inc = (rook_to > rook_from) ? +1 : -1;
252 for (sq = rook_from+inc; TRUE; sq += inc) {
253 if (sq != king_from && board->square[sq] != Empty) legal = FALSE;
254 if (sq == rook_to) break;
258 if (legal) list_add(list,move_make(king_from,rook_from));
263 if (board->castle[me][SideA] != SquareNone) {
265 king_from = king_pos(board,me);
266 king_to = square_make(FileC,rank);
267 rook_from = board->castle[me][SideA];
268 rook_to = square_make(FileD,rank);
270 ASSERT(square_rank(king_from)==rank);
271 ASSERT(square_rank(rook_from)==rank);
272 ASSERT(board->square[king_from]==(King64|me)); // HACK
273 ASSERT(board->square[rook_from]==(Rook64|me)); // HACK
274 ASSERT(rook_from<king_from);
278 if (king_to != king_from) {
280 inc = (king_to > king_from) ? +1 : -1;
282 for (sq = king_from+inc; TRUE; sq += inc) {
284 if (sq != rook_from && board->square[sq] != Empty) legal = FALSE;
285 if (is_attacked(board,sq,opp)) legal = FALSE;
287 if (sq == king_to) break;
291 if (rook_to != rook_from) {
293 inc = (rook_to > rook_from) ? +1 : -1;
295 for (sq = rook_from+inc; TRUE; sq += inc) {
296 if (sq != king_from && board->square[sq] != Empty) legal = FALSE;
297 if (sq == rook_to) break;
301 if (legal) list_add(list,move_make(king_from,rook_from));
307 static void add_pawn_move(list_t * list, int from, int to) {
311 ASSERT(list_is_ok(list));
312 ASSERT(square_is_ok(from));
313 ASSERT(square_is_ok(to));
315 move = move_make(from,to);
317 if (square_is_promote(to)) {
318 list_add(list,move|MovePromoteKnight);
319 list_add(list,move|MovePromoteBishop);
320 list_add(list,move|MovePromoteRook);
321 list_add(list,move|MovePromoteQueen);
327 // end of move_gen.cpp