Add forgotten files 1.4.70b
[polyglot.git] / move.c
diff --git a/move.c b/move.c
index 8d5699f..90191f9 100644 (file)
--- a/move.c
+++ b/move.c
-\r
-// move.c\r
-\r
-// includes\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include "attack.h"\r
-#include "colour.h"\r
-#include "list.h"\r
-#include "move.h"\r
-#include "move_do.h"\r
-#include "move_gen.h"\r
-#include "move_legal.h"\r
-#include "option.h"\r
-#include "piece.h"\r
-#include "square.h"\r
-#include "util.h"\r
-\r
-// "constants"\r
-\r
-static const uint8 PromotePiece[5] = { PieceNone64, Knight64, Bishop64, Rook64, Queen64 };\r
-\r
-// functions\r
-\r
-// move_is_ok()\r
-\r
-bool move_is_ok(int move) {\r
-\r
-   if (move < 0 || move >= 65536) return FALSE;\r
-\r
-   if (move == MoveNone) return FALSE;\r
-\r
-   return TRUE;\r
-}\r
-\r
-// move_make()\r
-\r
-int move_make(int from, int to) {\r
-\r
-   ASSERT(square_is_ok(from));\r
-   ASSERT(square_is_ok(to));\r
-\r
-   return (square_to_64(from) << 6) | square_to_64(to);\r
-}\r
-\r
-// move_make_flags()\r
-\r
-int move_make_flags(int from, int to, int flags) {\r
-\r
-   ASSERT(square_is_ok(from));\r
-   ASSERT(square_is_ok(to));\r
-   ASSERT((flags&~0xF000)==0);\r
-\r
-   ASSERT(to!=from);\r
-\r
-   return (square_to_64(from) << 6) | square_to_64(to) | flags;\r
-}\r
-\r
-// move_from()\r
-\r
-int move_from(int move) {\r
-\r
-   int from_64;\r
-\r
-   ASSERT(move_is_ok(move));\r
-\r
-   from_64 = (move >> 6) & 077;\r
-\r
-   return square_from_64(from_64);\r
-}\r
-\r
-// move_to()\r
-\r
-int move_to(int move) {\r
-\r
-   int to_64;\r
-\r
-   ASSERT(move_is_ok(move));\r
-\r
-   to_64 = move & 077;\r
-\r
-   return square_from_64(to_64);\r
-}\r
-\r
-// move_promote_hack()\r
-\r
-int move_promote_hack(int move) {\r
-\r
-   int code;\r
-\r
-   ASSERT(move_is_ok(move));\r
-\r
-   ASSERT(move_is_promote(move));\r
-\r
-   code = move >> 12;\r
-   ASSERT(code>=1&&code<=4);\r
-\r
-   return PromotePiece[code];\r
-}\r
-\r
-// move_is_capture()\r
-\r
-bool move_is_capture(int move, const board_t * board) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   if (move_is_en_passant(move,board)) return TRUE;\r
-   if (board->square[move_to(move)] != Empty) return TRUE;\r
-\r
-   return FALSE;\r
-}\r
-\r
-// move_is_promote()\r
-\r
-bool move_is_promote(int move) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-\r
-   return (move & MoveFlags) != 0;\r
-}\r
-\r
-// move_is_en_passant()\r
-\r
-bool move_is_en_passant(int move, const board_t * board) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   return piece_is_pawn(move_piece(move,board))\r
-       && move_to(move) == board->ep_square;\r
-}\r
-\r
-// move_is_castle()\r
-\r
-bool move_is_castle(int move, const board_t * board) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   return colour_equal(board->square[move_to(move)],board->turn);\r
-}\r
-\r
-// move_piece()\r
-\r
-int move_piece(int move, const board_t * board) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   return board->square[move_from(move)];\r
-}\r
-\r
-// move_capture()\r
-\r
-int move_capture(int move, const board_t * board) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   if (move_is_en_passant(move,board)) {\r
-      return piece_pawn_opp(move_piece(move,board));\r
-   }\r
-\r
-   return board->square[move_to(move)];\r
-}\r
-\r
-// move_promote()\r
-\r
-int move_promote(int move, const board_t * board) {\r
-\r
-   int code;\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   if (move_is_promote(move)) {\r
-      code = move >> 12;\r
-      ASSERT(code>=1&&code<=4);\r
-      return PromotePiece[code] | board->turn;\r
-   }\r
-\r
-   return Empty;\r
-}\r
-\r
-// move_is_check()\r
-\r
-bool move_is_check(int move, const board_t * board) {\r
-\r
-   board_t new_board[1];\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   board_copy(new_board,board);\r
-   move_do(new_board,move);\r
-   ASSERT(!is_in_check(new_board,colour_opp(new_board->turn)));\r
-\r
-   return board_is_check(new_board);\r
-}\r
-\r
-// move_is_mate()\r
-\r
-bool move_is_mate(int move, const board_t * board) {\r
-\r
-   board_t new_board[1];\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   board_copy(new_board,board);\r
-   move_do(new_board,move);\r
-   ASSERT(!is_in_check(new_board,colour_opp(new_board->turn)));\r
-\r
-   return board_is_mate(new_board);\r
-}\r
-\r
-// move_to_can()\r
-\r
-bool move_to_can(int move, const board_t * board, char string[], int size) {\r
-\r
-   int from, to;\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-   ASSERT(string!=NULL);\r
-   ASSERT(size>=6);\r
-\r
-   ASSERT(move_is_legal(move,board));\r
-\r
-   if (size < 6) return FALSE;\r
-\r
-   // init\r
-\r
-   from = move_from(move);\r
-   to = move_to(move);\r
-\r
-   // king-slide castling\r
-\r
-   if (move_is_castle(move,board) && !option_get_bool("Chess960")) {\r
-      if (FALSE) {\r
-      } else if (from == E1 && to == H1) {\r
-         to = G1;\r
-      } else if (from == E1 && to == A1) {\r
-         to = C1;\r
-      } else if (from == E8 && to == H8) {\r
-         to = G8;\r
-      } else if (from == E8 && to == A8) {\r
-         to = C8;\r
-      }\r
-   }\r
-\r
-   // normal moves\r
-\r
-   if (!square_to_string(from,&string[0],3)) ASSERT(FALSE);\r
-   if (!square_to_string(to,&string[2],3)) ASSERT(FALSE);\r
-   ASSERT(strlen(string)==4);\r
-\r
-   // promotes\r
-\r
-   if (move_is_promote(move)) {\r
-      string[4] = piece_to_char(move_promote_hack(move)|Black); // HACK: black => lower-case\r
-      string[5] = '\0';\r
-   }\r
-\r
-   // debug\r
-\r
-   ASSERT(move_from_can(string,board)==move);\r
-\r
-   return TRUE;\r
-}\r
-\r
-// move_from_can()\r
-\r
-int move_from_can(const char string[], const board_t * board) {\r
-\r
-   char tmp_string[256];\r
-   int from, to;\r
-   int side;\r
-   int move;\r
-\r
-   ASSERT(string!=NULL);\r
-   ASSERT(board_is_ok(board));\r
-\r
-   // from\r
-\r
-   tmp_string[0] = string[0];\r
-   tmp_string[1] = string[1];\r
-   tmp_string[2] = '\0';\r
-\r
-   from = square_from_string(tmp_string);\r
-   if (from == SquareNone) return MoveNone;\r
-\r
-   // to\r
-\r
-   tmp_string[0] = string[2];\r
-   tmp_string[1] = string[3];\r
-   tmp_string[2] = '\0';\r
-\r
-   to = square_from_string(tmp_string);\r
-   if (to == SquareNone) return MoveNone;\r
-\r
-   // convert "king slide" castling to KxR\r
-\r
-   if (piece_is_king(board->square[from])\r
-    && square_rank(to) == square_rank(from)\r
-    && abs(to-from) > 1) {\r
-      side = (to > from) ? SideH : SideA;\r
-      to = board->castle[board->turn][side];\r
-      if (to == SquareNone) return MoveNone;\r
-   }\r
-   // move\r
-\r
-   move = move_make(from,to);\r
-\r
-   // promote\r
-   switch (string[4]) {\r
-   case '\0': // not a promotion\r
-      if (piece_is_pawn(board->square[from])\r
-       && square_side_rank(to,board->turn) == Rank8\r
-       && option_get_bool("PromoteWorkAround")) {\r
-         move |= MovePromoteQueen;\r
-      }\r
-      break;\r
-   case 'N':\r
-   case 'n':\r
-      move |= MovePromoteKnight;\r
-      break;\r
-   case 'B':\r
-   case 'b':\r
-      move |= MovePromoteBishop;\r
-      break;\r
-   case 'R':\r
-   case 'r':\r
-      move |= MovePromoteRook;\r
-      break;\r
-   case 'Q':\r
-   case 'q':\r
-      move |= MovePromoteQueen;\r
-      break;\r
-   default:\r
-      return MoveNone;\r
-      break;\r
-   }\r
-   // debug\r
-\r
-   ASSERT(move_is_legal(move,board));\r
-   return move;\r
-}\r
-\r
-// move_order()\r
-\r
-int move_order(int move) {\r
-\r
-   ASSERT(move_is_ok(move));\r
-\r
-   return ((move & 07777) << 3) | (move >> 12); // from, to, promote\r
-}\r
-\r
-// move_disp()\r
-\r
-void move_disp(int move, const board_t * board) {\r
-\r
-   char string[256];\r
-\r
-   ASSERT(move_is_ok(move));\r
-   ASSERT(board_is_ok(board));\r
-\r
-   if (!move_to_can(move,board,string,256)) ASSERT(FALSE);\r
-   my_log("POLYGLOT %s\n",string);\r
-}\r
-\r
-// end of move.cpp\r
-\r
+
+// move.c
+
+// includes
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "attack.h"
+#include "colour.h"
+#include "list.h"
+#include "move.h"
+#include "move_do.h"
+#include "move_gen.h"
+#include "move_legal.h"
+#include "option.h"
+#include "piece.h"
+#include "square.h"
+#include "util.h"
+
+// "constants"
+
+static const uint8 PromotePiece[5] = { PieceNone64, Knight64, Bishop64, Rook64, Queen64 };
+
+// functions
+
+// move_is_ok()
+
+bool move_is_ok(int move) {
+
+   if (move < 0 || move >= 65536) return FALSE;
+
+   if (move == MoveNone) return FALSE;
+
+   return TRUE;
+}
+
+// move_make()
+
+int move_make(int from, int to) {
+
+   ASSERT(square_is_ok(from));
+   ASSERT(square_is_ok(to));
+
+   return (square_to_64(from) << 6) | square_to_64(to);
+}
+
+// move_make_flags()
+
+int move_make_flags(int from, int to, int flags) {
+
+   ASSERT(square_is_ok(from));
+   ASSERT(square_is_ok(to));
+   ASSERT((flags&~0xF000)==0);
+
+   ASSERT(to!=from);
+
+   return (square_to_64(from) << 6) | square_to_64(to) | flags;
+}
+
+// move_from()
+
+int move_from(int move) {
+
+   int from_64;
+
+   ASSERT(move_is_ok(move));
+
+   from_64 = (move >> 6) & 077;
+
+   return square_from_64(from_64);
+}
+
+// move_to()
+
+int move_to(int move) {
+
+   int to_64;
+
+   ASSERT(move_is_ok(move));
+
+   to_64 = move & 077;
+
+   return square_from_64(to_64);
+}
+
+// move_promote_hack()
+
+int move_promote_hack(int move) {
+
+   int code;
+
+   ASSERT(move_is_ok(move));
+
+   ASSERT(move_is_promote(move));
+
+   code = move >> 12;
+   ASSERT(code>=1&&code<=4);
+
+   return PromotePiece[code];
+}
+
+// move_is_capture()
+
+bool move_is_capture(int move, const board_t * board) {
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   if (move_is_en_passant(move,board)) return TRUE;
+   if (board->square[move_to(move)] != Empty) return TRUE;
+
+   return FALSE;
+}
+
+// move_is_promote()
+
+bool move_is_promote(int move) {
+
+   ASSERT(move_is_ok(move));
+
+   return (move & MoveFlags) != 0;
+}
+
+// move_is_en_passant()
+
+bool move_is_en_passant(int move, const board_t * board) {
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   return piece_is_pawn(move_piece(move,board))
+       && move_to(move) == board->ep_square;
+}
+
+// move_is_castle()
+
+bool move_is_castle(int move, const board_t * board) {
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   return colour_equal(board->square[move_to(move)],board->turn);
+}
+
+// move_piece()
+
+int move_piece(int move, const board_t * board) {
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   return board->square[move_from(move)];
+}
+
+// move_capture()
+
+int move_capture(int move, const board_t * board) {
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   if (move_is_en_passant(move,board)) {
+      return piece_pawn_opp(move_piece(move,board));
+   }
+
+   return board->square[move_to(move)];
+}
+
+// move_promote()
+
+int move_promote(int move, const board_t * board) {
+
+   int code;
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   if (move_is_promote(move)) {
+      code = move >> 12;
+      ASSERT(code>=1&&code<=4);
+      return PromotePiece[code] | board->turn;
+   }
+
+   return Empty;
+}
+
+// move_is_check()
+
+bool move_is_check(int move, const board_t * board) {
+
+   board_t new_board[1];
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   board_copy(new_board,board);
+   move_do(new_board,move);
+   ASSERT(!is_in_check(new_board,colour_opp(new_board->turn)));
+
+   return board_is_check(new_board);
+}
+
+// move_is_mate()
+
+bool move_is_mate(int move, const board_t * board) {
+
+   board_t new_board[1];
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   board_copy(new_board,board);
+   move_do(new_board,move);
+   ASSERT(!is_in_check(new_board,colour_opp(new_board->turn)));
+
+   return board_is_mate(new_board);
+}
+
+// move_to_can()
+
+bool move_to_can(int move, const board_t * board, char string[], int size) {
+
+   int from, to;
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+   ASSERT(string!=NULL);
+   ASSERT(size>=6);
+
+   ASSERT(move_is_legal(move,board));
+
+   if (size < 6) return FALSE;
+
+   // init
+
+   from = move_from(move);
+   to = move_to(move);
+
+   // king-slide castling
+
+   if (move_is_castle(move,board) && !option_get_bool(Option,"Chess960")) {
+      if (FALSE) {
+      } else if (from == E1 && to == H1) {
+         to = G1;
+      } else if (from == E1 && to == A1) {
+         to = C1;
+      } else if (from == E8 && to == H8) {
+         to = G8;
+      } else if (from == E8 && to == A8) {
+         to = C8;
+      }
+   }
+
+   // normal moves
+
+   if (!square_to_string(from,&string[0],3)) ASSERT(FALSE);
+   if (!square_to_string(to,&string[2],3)) ASSERT(FALSE);
+   ASSERT(strlen(string)==4);
+
+   // promotes
+
+   if (move_is_promote(move)) {
+      string[4] = piece_to_char(move_promote_hack(move)|Black); // HACK: black => lower-case
+      string[5] = '\0';
+   }
+
+   // debug
+
+   ASSERT(move_from_can(string,board)==move);
+
+   return TRUE;
+}
+
+// move_from_can()
+
+int move_from_can(const char string[], const board_t * board) {
+
+   char tmp_string[256];
+   int from, to;
+   int side;
+   int move;
+
+   ASSERT(string!=NULL);
+   ASSERT(board_is_ok(board));
+
+   // from
+
+   tmp_string[0] = string[0];
+   tmp_string[1] = string[1];
+   tmp_string[2] = '\0';
+
+   from = square_from_string(tmp_string);
+   if (from == SquareNone) return MoveNone;
+
+   // to
+
+   tmp_string[0] = string[2];
+   tmp_string[1] = string[3];
+   tmp_string[2] = '\0';
+
+   to = square_from_string(tmp_string);
+   if (to == SquareNone) return MoveNone;
+
+   // convert "king slide" castling to KxR
+
+   if (piece_is_king(board->square[from])
+    && square_rank(to) == square_rank(from)
+    && abs(to-from) > 1) {
+      side = (to > from) ? SideH : SideA;
+      to = board->castle[board->turn][side];
+      if (to == SquareNone) return MoveNone;
+   }
+   // move
+
+   move = move_make(from,to);
+
+   // promote
+   switch (string[4]) {
+   case '\0': // not a promotion
+      if (piece_is_pawn(board->square[from])
+       && square_side_rank(to,board->turn) == Rank8
+          && option_get_bool(Option,"PromoteWorkAround")) {
+         move |= MovePromoteQueen;
+      }
+      break;
+   case 'N':
+   case 'n':
+      move |= MovePromoteKnight;
+      break;
+   case 'B':
+   case 'b':
+      move |= MovePromoteBishop;
+      break;
+   case 'R':
+   case 'r':
+      move |= MovePromoteRook;
+      break;
+   case 'Q':
+   case 'q':
+      move |= MovePromoteQueen;
+      break;
+   default:
+      return MoveNone;
+      break;
+   }
+   // debug
+
+   ASSERT(move_is_legal(move,board));
+   return move;
+}
+
+// move_order()
+
+int move_order(int move) {
+
+   ASSERT(move_is_ok(move));
+
+   return ((move & 07777) << 3) | (move >> 12); // from, to, promote
+}
+
+// move_disp()
+
+void move_disp(int move, const board_t * board) {
+
+   char string[256];
+
+   ASSERT(move_is_ok(move));
+   ASSERT(board_is_ok(board));
+
+   if (!move_to_can(move,board,string,256)) ASSERT(FALSE);
+   my_log("POLYGLOT %s\n",string);
+}
+
+// end of move.cpp
+