-\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
+