Add forgotten files 1.4.70b
[polyglot.git] / move_gen.c
index 2d45564..6ebaf42 100644 (file)
-\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
+