13 #include "move_do.h"
\r
14 #include "move_gen.h"
\r
15 #include "move_legal.h"
\r
23 static const uint8 PromotePiece[5] = { PieceNone64, Knight64, Bishop64, Rook64, Queen64 };
\r
29 bool move_is_ok(int move) {
\r
31 if (move < 0 || move >= 65536) return false;
\r
33 if (move == MoveNone) return false;
\r
40 int move_make(int from, int to) {
\r
42 ASSERT(square_is_ok(from));
\r
43 ASSERT(square_is_ok(to));
\r
45 return (square_to_64(from) << 6) | square_to_64(to);
\r
48 // move_make_flags()
\r
50 int move_make_flags(int from, int to, int flags) {
\r
52 ASSERT(square_is_ok(from));
\r
53 ASSERT(square_is_ok(to));
\r
54 ASSERT((flags&~0xF000)==0);
\r
58 return (square_to_64(from) << 6) | square_to_64(to) | flags;
\r
63 int move_from(int move) {
\r
67 ASSERT(move_is_ok(move));
\r
69 from_64 = (move >> 6) & 077;
\r
71 return square_from_64(from_64);
\r
76 int move_to(int move) {
\r
80 ASSERT(move_is_ok(move));
\r
84 return square_from_64(to_64);
\r
87 // move_promote_hack()
\r
89 int move_promote_hack(int move) {
\r
93 ASSERT(move_is_ok(move));
\r
95 ASSERT(move_is_promote(move));
\r
98 ASSERT(code>=1&&code<=4);
\r
100 return PromotePiece[code];
\r
103 // move_is_capture()
\r
105 bool move_is_capture(int move, const board_t * board) {
\r
107 ASSERT(move_is_ok(move));
\r
108 ASSERT(board_is_ok(board));
\r
110 if (move_is_en_passant(move,board)) return true;
\r
111 if (board->square[move_to(move)] != Empty) return true;
\r
116 // move_is_promote()
\r
118 bool move_is_promote(int move) {
\r
120 ASSERT(move_is_ok(move));
\r
122 return (move & MoveFlags) != 0;
\r
125 // move_is_en_passant()
\r
127 bool move_is_en_passant(int move, const board_t * board) {
\r
129 ASSERT(move_is_ok(move));
\r
130 ASSERT(board_is_ok(board));
\r
132 return piece_is_pawn(move_piece(move,board))
\r
133 && move_to(move) == board->ep_square;
\r
136 // move_is_castle()
\r
138 bool move_is_castle(int move, const board_t * board) {
\r
140 ASSERT(move_is_ok(move));
\r
141 ASSERT(board_is_ok(board));
\r
143 return colour_equal(board->square[move_to(move)],board->turn);
\r
148 int move_piece(int move, const board_t * board) {
\r
150 ASSERT(move_is_ok(move));
\r
151 ASSERT(board_is_ok(board));
\r
153 return board->square[move_from(move)];
\r
158 int move_capture(int move, const board_t * board) {
\r
160 ASSERT(move_is_ok(move));
\r
161 ASSERT(board_is_ok(board));
\r
163 if (move_is_en_passant(move,board)) {
\r
164 return piece_pawn_opp(move_piece(move,board));
\r
167 return board->square[move_to(move)];
\r
172 int move_promote(int move, const board_t * board) {
\r
176 ASSERT(move_is_ok(move));
\r
177 ASSERT(board_is_ok(board));
\r
179 if (move_is_promote(move)) {
\r
181 ASSERT(code>=1&&code<=4);
\r
182 return PromotePiece[code] | board->turn;
\r
190 bool move_is_check(int move, const board_t * board) {
\r
192 board_t new_board[1];
\r
194 ASSERT(move_is_ok(move));
\r
195 ASSERT(board_is_ok(board));
\r
197 board_copy(new_board,board);
\r
198 move_do(new_board,move);
\r
199 ASSERT(!is_in_check(new_board,colour_opp(new_board->turn)));
\r
201 return board_is_check(new_board);
\r
206 bool move_is_mate(int move, const board_t * board) {
\r
208 board_t new_board[1];
\r
210 ASSERT(move_is_ok(move));
\r
211 ASSERT(board_is_ok(board));
\r
213 board_copy(new_board,board);
\r
214 move_do(new_board,move);
\r
215 ASSERT(!is_in_check(new_board,colour_opp(new_board->turn)));
\r
217 return board_is_mate(new_board);
\r
222 bool move_to_can(int move, const board_t * board, char string[], int size) {
\r
226 ASSERT(move_is_ok(move));
\r
227 ASSERT(board_is_ok(board));
\r
228 ASSERT(string!=NULL);
\r
231 ASSERT(move_is_legal(move,board));
\r
233 if (size < 6) return false;
\r
237 from = move_from(move);
\r
238 to = move_to(move);
\r
240 // king-slide castling
\r
242 if (move_is_castle(move,board) && !option_get_bool("Chess960")) {
\r
244 } else if (from == E1 && to == H1) {
\r
246 } else if (from == E1 && to == A1) {
\r
248 } else if (from == E8 && to == H8) {
\r
250 } else if (from == E8 && to == A8) {
\r
257 if (!square_to_string(from,&string[0],3)) ASSERT(false);
\r
258 if (!square_to_string(to,&string[2],3)) ASSERT(false);
\r
259 ASSERT(strlen(string)==4);
\r
263 if (move_is_promote(move)) {
\r
264 string[4] = piece_to_char(move_promote_hack(move)|Black); // HACK: black => lower-case
\r
270 ASSERT(move_from_can(string,board)==move);
\r
277 int move_from_can(const char string[], const board_t * board) {
\r
279 char tmp_string[256];
\r
284 ASSERT(string!=NULL);
\r
285 ASSERT(board_is_ok(board));
\r
289 tmp_string[0] = string[0];
\r
290 tmp_string[1] = string[1];
\r
291 tmp_string[2] = '\0';
\r
293 from = square_from_string(tmp_string);
\r
294 if (from == SquareNone) return MoveNone;
\r
298 tmp_string[0] = string[2];
\r
299 tmp_string[1] = string[3];
\r
300 tmp_string[2] = '\0';
\r
302 to = square_from_string(tmp_string);
\r
303 if (to == SquareNone) return MoveNone;
\r
305 // convert "king slide" castling to KxR
\r
307 if (piece_is_king(board->square[from])
\r
308 && square_rank(to) == square_rank(from)
\r
309 && abs(to-from) > 1) {
\r
310 side = (to > from) ? SideH : SideA;
\r
311 to = board->castle[board->turn][side];
\r
312 if (to == SquareNone) return MoveNone;
\r
317 move = move_make(from,to);
\r
321 switch (string[4]) {
\r
322 case '\0': // not a promotion
\r
323 if (piece_is_pawn(board->square[from])
\r
324 && square_side_rank(to,board->turn) == Rank8
\r
325 && option_get_bool("PromoteWorkAround")) {
\r
326 move |= MovePromoteQueen;
\r
331 move |= MovePromoteKnight;
\r
335 move |= MovePromoteBishop;
\r
339 move |= MovePromoteRook;
\r
343 move |= MovePromoteQueen;
\r
352 ASSERT(move_is_legal(move,board));
\r
359 int move_order(int move) {
\r
361 ASSERT(move_is_ok(move));
\r
363 return ((move & 07777) << 3) | (move >> 12); // from, to, promote
\r
368 void move_disp(int move, const board_t * board) {
\r
372 ASSERT(move_is_ok(move));
\r
373 ASSERT(board_is_ok(board));
\r
375 if (!move_to_can(move,board,string,256)) ASSERT(false);
\r
376 my_log("POLYGLOT %s\n",string);
\r