-\r
-// move_gen.c\r
-\r
-// includes\r
-\r
-#include "attack.h"\r
-#include "board.h"\r
-#include "colour.h"\r
-#include "list.h"\r
-#include "move.h"\r
-#include "move_gen.h"\r
-#include "move_legal.h"\r
-#include "piece.h"\r
-#include "util.h"\r
-\r
-// prototypes\r
-\r
-static void add_all_moves (list_t * list, const board_t * board);\r
-static void add_castle_moves (list_t * list, const board_t * board);\r
-\r
-static void add_pawn_move (list_t * list, int from, int to);\r
-\r
-// functions\r
-\r
-// gen_legal_moves()\r
-\r
-void gen_legal_moves(list_t * list, const board_t * board) {\r
-\r
- ASSERT(list!=NULL);\r
- ASSERT(board_is_ok(board));\r
-\r
- gen_moves(list,board);\r
- filter_legal(list,board);\r
-}\r
-\r
-// gen_moves()\r
-\r
-void gen_moves(list_t * list, const board_t * board) {\r
-\r
- ASSERT(list!=NULL);\r
- ASSERT(board_is_ok(board));\r
-\r
- list_clear(list);\r
-\r
- add_all_moves(list,board);\r
- if (!is_in_check(board,board->turn)) add_castle_moves(list,board);\r
-}\r
-\r
-// add_all_moves()\r
-\r
-static void add_all_moves(list_t * list, const board_t * board) {\r
-\r
- int me, opp;\r
- const uint8 * ptr;\r
- const sint8 * ptr_inc;\r
- int from, to;\r
- int inc;\r
- int piece, capture;\r
-\r
- ASSERT(list_is_ok(list));\r
- ASSERT(board_is_ok(board));\r
-\r
- me = board->turn;\r
- opp = colour_opp(me);\r
-\r
- for (ptr = board->list[me]; (from=*ptr) != SquareNone; ptr++) {\r
-\r
- piece = board->square[from];\r
- ASSERT(colour_equal(piece,me));\r
-\r
- switch (piece_type(piece)) {\r
-\r
- case WhitePawn64:\r
-\r
- to = from + 15;\r
- if (to == board->ep_square || colour_equal(board->square[to],opp)) {\r
- add_pawn_move(list,from,to);\r
- }\r
-\r
- to = from + 17;\r
- if (to == board->ep_square || colour_equal(board->square[to],opp)) {\r
- add_pawn_move(list,from,to);\r
- }\r
-\r
- to = from + 16;\r
- if (board->square[to] == Empty) {\r
- add_pawn_move(list,from,to);\r
- if (square_rank(from) == Rank2) {\r
- to = from + 32;\r
- if (board->square[to] == Empty) {\r
- ASSERT(!square_is_promote(to));\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
- }\r
-\r
- break;\r
-\r
- case BlackPawn64:\r
-\r
- to = from - 17;\r
- if (to == board->ep_square || colour_equal(board->square[to],opp)) {\r
- add_pawn_move(list,from,to);\r
- }\r
-\r
- to = from - 15;\r
- if (to == board->ep_square || colour_equal(board->square[to],opp)) {\r
- add_pawn_move(list,from,to);\r
- }\r
-\r
- to = from - 16;\r
- if (board->square[to] == Empty) {\r
- add_pawn_move(list,from,to);\r
- if (square_rank(from) == Rank7) {\r
- to = from - 32;\r
- if (board->square[to] == Empty) {\r
- ASSERT(!square_is_promote(to));\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
- }\r
-\r
- break;\r
-\r
- case Knight64:\r
-\r
- for (ptr_inc = KnightInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {\r
- to = from + inc;\r
- capture = board->square[to];\r
- if (capture == Empty || colour_equal(capture,opp)) {\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
-\r
- break;\r
-\r
- case Bishop64:\r
-\r
- for (ptr_inc = BishopInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {\r
- for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {\r
- list_add(list,move_make(from,to));\r
- }\r
- if (colour_equal(capture,opp)) {\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
-\r
- break;\r
-\r
- case Rook64:\r
-\r
- for (ptr_inc = RookInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {\r
- for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {\r
- list_add(list,move_make(from,to));\r
- }\r
- if (colour_equal(capture,opp)) {\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
-\r
- break;\r
-\r
- case Queen64:\r
-\r
- for (ptr_inc = QueenInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {\r
- for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {\r
- list_add(list,move_make(from,to));\r
- }\r
- if (colour_equal(capture,opp)) {\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
-\r
- break;\r
-\r
- case King64:\r
-\r
- for (ptr_inc = KingInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {\r
- to = from + inc;\r
- capture = board->square[to];\r
- if (capture == Empty || colour_equal(capture,opp)) {\r
- list_add(list,move_make(from,to));\r
- }\r
- }\r
-\r
- break;\r
-\r
- default:\r
-\r
- ASSERT(FALSE);\r
- break;\r
- }\r
- }\r
-}\r
-\r
-// add_castle_moves()\r
-\r
-static void add_castle_moves(list_t * list, const board_t * board) {\r
-\r
- int me, opp;\r
- int rank;\r
- int king_from, king_to;\r
- int rook_from, rook_to;\r
- bool legal;\r
- int inc;\r
- int sq;\r
-\r
- ASSERT(list_is_ok(list));\r
- ASSERT(board_is_ok(board));\r
-\r
- ASSERT(!is_in_check(board,board->turn));\r
-\r
- me = board->turn;\r
- opp = colour_opp(me);\r
-\r
- rank = colour_is_white(me) ? Rank1 : Rank8;\r
-\r
- // h-side castling\r
-\r
- if (board->castle[me][SideH] != SquareNone) {\r
-\r
- king_from = king_pos(board,me);\r
- king_to = square_make(FileG,rank);\r
- rook_from = board->castle[me][SideH];\r
- rook_to = square_make(FileF,rank);\r
-\r
- ASSERT(square_rank(king_from)==rank);\r
- ASSERT(square_rank(rook_from)==rank);\r
- ASSERT(board->square[king_from]==(King64|me)); // HACK\r
- ASSERT(board->square[rook_from]==(Rook64|me)); // HACK\r
- ASSERT(rook_from>king_from);\r
-\r
- legal = TRUE;\r
-\r
- if (king_to != king_from) {\r
-\r
- inc = (king_to > king_from) ? +1 : -1;\r
-\r
- for (sq = king_from+inc; TRUE; sq += inc) {\r
-\r
- if (sq != rook_from && board->square[sq] != Empty) legal = FALSE;\r
- if (is_attacked(board,sq,opp)) legal = FALSE;\r
-\r
- if (sq == king_to) break;\r
- }\r
- }\r
-\r
- if (rook_to != rook_from) {\r
-\r
- inc = (rook_to > rook_from) ? +1 : -1;\r
-\r
- for (sq = rook_from+inc; TRUE; sq += inc) {\r
- if (sq != king_from && board->square[sq] != Empty) legal = FALSE;\r
- if (sq == rook_to) break;\r
- }\r
- }\r
-\r
- if (legal) list_add(list,move_make(king_from,rook_from));\r
- }\r
-\r
- // a-side castling\r
-\r
- if (board->castle[me][SideA] != SquareNone) {\r
-\r
- king_from = king_pos(board,me);\r
- king_to = square_make(FileC,rank);\r
- rook_from = board->castle[me][SideA];\r
- rook_to = square_make(FileD,rank);\r
-\r
- ASSERT(square_rank(king_from)==rank);\r
- ASSERT(square_rank(rook_from)==rank);\r
- ASSERT(board->square[king_from]==(King64|me)); // HACK\r
- ASSERT(board->square[rook_from]==(Rook64|me)); // HACK\r
- ASSERT(rook_from<king_from);\r
-\r
- legal = TRUE;\r
-\r
- if (king_to != king_from) {\r
-\r
- inc = (king_to > king_from) ? +1 : -1;\r
-\r
- for (sq = king_from+inc; TRUE; sq += inc) {\r
-\r
- if (sq != rook_from && board->square[sq] != Empty) legal = FALSE;\r
- if (is_attacked(board,sq,opp)) legal = FALSE;\r
-\r
- if (sq == king_to) break;\r
- }\r
- }\r
-\r
- if (rook_to != rook_from) {\r
-\r
- inc = (rook_to > rook_from) ? +1 : -1;\r
-\r
- for (sq = rook_from+inc; TRUE; sq += inc) {\r
- if (sq != king_from && board->square[sq] != Empty) legal = FALSE;\r
- if (sq == rook_to) break;\r
- }\r
- }\r
-\r
- if (legal) list_add(list,move_make(king_from,rook_from));\r
- }\r
-}\r
-\r
-// add_pawn_move()\r
-\r
-static void add_pawn_move(list_t * list, int from, int to) {\r
-\r
- int move;\r
-\r
- ASSERT(list_is_ok(list));\r
- ASSERT(square_is_ok(from));\r
- ASSERT(square_is_ok(to));\r
-\r
- move = move_make(from,to);\r
-\r
- if (square_is_promote(to)) {\r
- list_add(list,move|MovePromoteKnight);\r
- list_add(list,move|MovePromoteBishop);\r
- list_add(list,move|MovePromoteRook);\r
- list_add(list,move|MovePromoteQueen);\r
- } else {\r
- list_add(list,move);\r
- }\r
-}\r
-\r
-// end of move_gen.cpp\r
-\r
+
+// move_gen.c
+
+// includes
+
+#include "attack.h"
+#include "board.h"
+#include "colour.h"
+#include "list.h"
+#include "move.h"
+#include "move_gen.h"
+#include "move_legal.h"
+#include "piece.h"
+#include "util.h"
+
+// prototypes
+
+static void add_all_moves (list_t * list, const board_t * board);
+static void add_castle_moves (list_t * list, const board_t * board);
+
+static void add_pawn_move (list_t * list, int from, int to);
+
+// functions
+
+// gen_legal_moves()
+
+void gen_legal_moves(list_t * list, const board_t * board) {
+
+ ASSERT(list!=NULL);
+ ASSERT(board_is_ok(board));
+
+ gen_moves(list,board);
+ filter_legal(list,board);
+}
+
+// gen_moves()
+
+void gen_moves(list_t * list, const board_t * board) {
+
+ ASSERT(list!=NULL);
+ ASSERT(board_is_ok(board));
+
+ list_clear(list);
+
+ add_all_moves(list,board);
+ if (!is_in_check(board,board->turn)) add_castle_moves(list,board);
+}
+
+// add_all_moves()
+
+static void add_all_moves(list_t * list, const board_t * board) {
+
+ int me, opp;
+ const uint8 * ptr;
+ const sint8 * ptr_inc;
+ int from, to;
+ int inc;
+ int piece, capture;
+
+ ASSERT(list_is_ok(list));
+ ASSERT(board_is_ok(board));
+
+ me = board->turn;
+ opp = colour_opp(me);
+
+ for (ptr = board->list[me]; (from=*ptr) != SquareNone; ptr++) {
+
+ piece = board->square[from];
+ ASSERT(colour_equal(piece,me));
+
+ switch (piece_type(piece)) {
+
+ case WhitePawn64:
+
+ to = from + 15;
+ if (to == board->ep_square || colour_equal(board->square[to],opp)) {
+ add_pawn_move(list,from,to);
+ }
+
+ to = from + 17;
+ if (to == board->ep_square || colour_equal(board->square[to],opp)) {
+ add_pawn_move(list,from,to);
+ }
+
+ to = from + 16;
+ if (board->square[to] == Empty) {
+ add_pawn_move(list,from,to);
+ if (square_rank(from) == Rank2) {
+ to = from + 32;
+ if (board->square[to] == Empty) {
+ ASSERT(!square_is_promote(to));
+ list_add(list,move_make(from,to));
+ }
+ }
+ }
+
+ break;
+
+ case BlackPawn64:
+
+ to = from - 17;
+ if (to == board->ep_square || colour_equal(board->square[to],opp)) {
+ add_pawn_move(list,from,to);
+ }
+
+ to = from - 15;
+ if (to == board->ep_square || colour_equal(board->square[to],opp)) {
+ add_pawn_move(list,from,to);
+ }
+
+ to = from - 16;
+ if (board->square[to] == Empty) {
+ add_pawn_move(list,from,to);
+ if (square_rank(from) == Rank7) {
+ to = from - 32;
+ if (board->square[to] == Empty) {
+ ASSERT(!square_is_promote(to));
+ list_add(list,move_make(from,to));
+ }
+ }
+ }
+
+ break;
+
+ case Knight64:
+
+ for (ptr_inc = KnightInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
+ to = from + inc;
+ capture = board->square[to];
+ if (capture == Empty || colour_equal(capture,opp)) {
+ list_add(list,move_make(from,to));
+ }
+ }
+
+ break;
+
+ case Bishop64:
+
+ for (ptr_inc = BishopInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
+ for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {
+ list_add(list,move_make(from,to));
+ }
+ if (colour_equal(capture,opp)) {
+ list_add(list,move_make(from,to));
+ }
+ }
+
+ break;
+
+ case Rook64:
+
+ for (ptr_inc = RookInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
+ for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {
+ list_add(list,move_make(from,to));
+ }
+ if (colour_equal(capture,opp)) {
+ list_add(list,move_make(from,to));
+ }
+ }
+
+ break;
+
+ case Queen64:
+
+ for (ptr_inc = QueenInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
+ for (to = from+inc; (capture=board->square[to]) == Empty; to += inc) {
+ list_add(list,move_make(from,to));
+ }
+ if (colour_equal(capture,opp)) {
+ list_add(list,move_make(from,to));
+ }
+ }
+
+ break;
+
+ case King64:
+
+ for (ptr_inc = KingInc; (inc=*ptr_inc) != IncNone; ptr_inc++) {
+ to = from + inc;
+ capture = board->square[to];
+ if (capture == Empty || colour_equal(capture,opp)) {
+ list_add(list,move_make(from,to));
+ }
+ }
+
+ break;
+
+ default:
+
+ ASSERT(FALSE);
+ break;
+ }
+ }
+}
+
+// add_castle_moves()
+
+static void add_castle_moves(list_t * list, const board_t * board) {
+
+ int me, opp;
+ int rank;
+ int king_from, king_to;
+ int rook_from, rook_to;
+ bool legal;
+ int inc;
+ int sq;
+
+ ASSERT(list_is_ok(list));
+ ASSERT(board_is_ok(board));
+
+ ASSERT(!is_in_check(board,board->turn));
+
+ me = board->turn;
+ opp = colour_opp(me);
+
+ rank = colour_is_white(me) ? Rank1 : Rank8;
+
+ // h-side castling
+
+ if (board->castle[me][SideH] != SquareNone) {
+
+ king_from = king_pos(board,me);
+ king_to = square_make(FileG,rank);
+ rook_from = board->castle[me][SideH];
+ rook_to = square_make(FileF,rank);
+
+ ASSERT(square_rank(king_from)==rank);
+ ASSERT(square_rank(rook_from)==rank);
+ ASSERT(board->square[king_from]==(King64|me)); // HACK
+ ASSERT(board->square[rook_from]==(Rook64|me)); // HACK
+ ASSERT(rook_from>king_from);
+
+ legal = TRUE;
+
+ if (king_to != king_from) {
+
+ inc = (king_to > king_from) ? +1 : -1;
+
+ for (sq = king_from+inc; TRUE; sq += inc) {
+
+ if (sq != rook_from && board->square[sq] != Empty) legal = FALSE;
+ if (is_attacked(board,sq,opp)) legal = FALSE;
+
+ if (sq == king_to) break;
+ }
+ }
+
+ if (rook_to != rook_from) {
+
+ inc = (rook_to > rook_from) ? +1 : -1;
+
+ for (sq = rook_from+inc; TRUE; sq += inc) {
+ if (sq != king_from && board->square[sq] != Empty) legal = FALSE;
+ if (sq == rook_to) break;
+ }
+ }
+
+ if (legal) list_add(list,move_make(king_from,rook_from));
+ }
+
+ // a-side castling
+
+ if (board->castle[me][SideA] != SquareNone) {
+
+ king_from = king_pos(board,me);
+ king_to = square_make(FileC,rank);
+ rook_from = board->castle[me][SideA];
+ rook_to = square_make(FileD,rank);
+
+ ASSERT(square_rank(king_from)==rank);
+ ASSERT(square_rank(rook_from)==rank);
+ ASSERT(board->square[king_from]==(King64|me)); // HACK
+ ASSERT(board->square[rook_from]==(Rook64|me)); // HACK
+ ASSERT(rook_from<king_from);
+
+ legal = TRUE;
+
+ if (king_to != king_from) {
+
+ inc = (king_to > king_from) ? +1 : -1;
+
+ for (sq = king_from+inc; TRUE; sq += inc) {
+
+ if (sq != rook_from && board->square[sq] != Empty) legal = FALSE;
+ if (is_attacked(board,sq,opp)) legal = FALSE;
+
+ if (sq == king_to) break;
+ }
+ }
+
+ if (rook_to != rook_from) {
+
+ inc = (rook_to > rook_from) ? +1 : -1;
+
+ for (sq = rook_from+inc; TRUE; sq += inc) {
+ if (sq != king_from && board->square[sq] != Empty) legal = FALSE;
+ if (sq == rook_to) break;
+ }
+ }
+
+ if (legal) list_add(list,move_make(king_from,rook_from));
+ }
+}
+
+// add_pawn_move()
+
+static void add_pawn_move(list_t * list, int from, int to) {
+
+ int move;
+
+ ASSERT(list_is_ok(list));
+ ASSERT(square_is_ok(from));
+ ASSERT(square_is_ok(to));
+
+ move = move_make(from,to);
+
+ if (square_is_promote(to)) {
+ list_add(list,move|MovePromoteKnight);
+ list_add(list,move|MovePromoteBishop);
+ list_add(list,move|MovePromoteRook);
+ list_add(list,move|MovePromoteQueen);
+ } else {
+ list_add(list,move);
+ }
+}
+
+// end of move_gen.cpp
+