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