-\r
-// move_do.c\r
-\r
-// includes\r
-\r
-#include <stdlib.h>\r
-\r
-#include "board.h"\r
-#include "colour.h"\r
-#include "hash.h"\r
-#include "move.h"\r
-#include "move_do.h"\r
-#include "move_legal.h"\r
-#include "piece.h"\r
-#include "random.h"\r
-#include "util.h"\r
-\r
-// prototypes\r
-\r
-static void square_clear (board_t * board, int square, int piece);\r
-static void square_set (board_t * board, int square, int piece, int pos);\r
-static void square_move (board_t * board, int from, int to, int piece);\r
-\r
-// functions\r
-\r
-// move_do()\r
-\r
-void move_do(board_t * board, int move) {\r
-\r
- int me, opp;\r
- int from, to;\r
- int piece, pos, capture;\r
- int old_flags, new_flags;\r
- int sq, ep_square;\r
- int pawn;\r
-\r
- ASSERT(board_is_ok(board));\r
- ASSERT(move_is_ok(move));\r
-\r
- ASSERT(move_is_pseudo(move,board));\r
-\r
- // init\r
-\r
- me = board->turn;\r
- opp = colour_opp(me);\r
-\r
- from = move_from(move);\r
- to = move_to(move);\r
-\r
- piece = board->square[from];\r
- ASSERT(colour_equal(piece,me));\r
-\r
- pos = board->pos[from];\r
- ASSERT(pos>=0);\r
-\r
- // update turn\r
-\r
- board->turn = opp;\r
- board->key ^= random_64(RandomTurn);\r
-\r
- // update castling rights\r
-\r
- old_flags = board_flags(board);\r
-\r
- if (piece_is_king(piece)) {\r
- board->castle[me][SideH] = SquareNone;\r
- board->castle[me][SideA] = SquareNone;\r
- }\r
-\r
- if (board->castle[me][SideH] == from) board->castle[me][SideH] = SquareNone;\r
- if (board->castle[me][SideA] == from) board->castle[me][SideA] = SquareNone;\r
-\r
- if (board->castle[opp][SideH] == to) board->castle[opp][SideH] = SquareNone;\r
- if (board->castle[opp][SideA] == to) board->castle[opp][SideA] = SquareNone;\r
-\r
- new_flags = board_flags(board);\r
-\r
- board->key ^= hash_castle_key(new_flags^old_flags); // HACK\r
-\r
- // update en-passant square\r
-\r
- ep_square = sq = board->ep_square;\r
- if (sq != SquareNone) {\r
- board->key ^= random_64(RandomEnPassant+square_file(sq));\r
- board->ep_square = SquareNone;\r
- }\r
-\r
- if (piece_is_pawn(piece) && abs(to-from) == 32) {\r
- pawn = piece_make_pawn(opp);\r
- if (board->square[to-1] == pawn || board->square[to+1] == pawn) {\r
- board->ep_square = sq = (from + to) / 2;\r
- board->key ^= random_64(RandomEnPassant+square_file(sq));\r
- }\r
- }\r
-\r
- // update ply number (captures are handled later)\r
-\r
- board->ply_nb++;\r
- if (piece_is_pawn(piece)) board->ply_nb = 0; // conversion\r
-\r
- // update move number\r
-\r
- if (me == Black) board->move_nb++;\r
-\r
- // castle\r
-\r
- if (colour_equal(board->square[to],me)) {\r
-\r
- int rank;\r
- int king_from, king_to;\r
- int rook_from, rook_to;\r
- int rook;\r
-\r
- rank = colour_is_white(me) ? Rank1 : Rank8;\r
-\r
- king_from = from;\r
- rook_from = to;\r
-\r
- if (to > from) { // h side\r
- king_to = square_make(FileG,rank);\r
- rook_to = square_make(FileF,rank);\r
- } else { // a side\r
- king_to = square_make(FileC,rank);\r
- rook_to = square_make(FileD,rank);\r
- }\r
-\r
- // remove the rook\r
-\r
- pos = board->pos[rook_from];\r
- ASSERT(pos>=0);\r
-\r
- rook = Rook64 | me; // HACK\r
-\r
- square_clear(board,rook_from,rook);\r
-\r
- // move the king\r
-\r
- square_move(board,king_from,king_to,piece);\r
-\r
- // put the rook back\r
-\r
- square_set(board,rook_to,rook,pos);\r
-\r
- ASSERT(board->key==hash_key(board));\r
-\r
- return;\r
- }\r
-\r
- // remove the captured piece\r
-\r
- if (piece_is_pawn(piece) && to == ep_square) {\r
-\r
- // en-passant capture\r
-\r
- sq = square_ep_dual(to);\r
- capture = board->square[sq];\r
- ASSERT(capture==piece_make_pawn(opp));\r
-\r
- square_clear(board,sq,capture);\r
-\r
- board->ply_nb = 0; // conversion\r
-\r
- } else {\r
-\r
- capture = board->square[to];\r
-\r
- if (capture != Empty) {\r
-\r
- // normal capture\r
-\r
- ASSERT(colour_equal(capture,opp));\r
- ASSERT(!piece_is_king(capture));\r
-\r
- square_clear(board,to,capture);\r
-\r
- board->ply_nb = 0; // conversion\r
- }\r
- }\r
-\r
- // move the piece\r
-\r
- if (move_is_promote(move)) {\r
-\r
- // promote\r
-\r
- square_clear(board,from,piece);\r
- piece = move_promote_hack(move) | me; // HACK\r
- square_set(board,to,piece,pos);\r
-\r
- } else {\r
-\r
- // normal move\r
-\r
- square_move(board,from,to,piece);\r
- }\r
-\r
- ASSERT(board->key==hash_key(board));\r
-}\r
-\r
-// square_clear()\r
-\r
-static void square_clear(board_t * board, int square, int piece) {\r
-\r
- int pos, piece_12, colour;\r
- int sq, size;\r
-\r
- ASSERT(board!=NULL);\r
- ASSERT(square_is_ok(square));\r
- ASSERT(piece_is_ok(piece));\r
-\r
- // init\r
-\r
- pos = board->pos[square];\r
- ASSERT(pos>=0);\r
-\r
- colour = piece_colour(piece);\r
- piece_12 = piece_to_12(piece);\r
-\r
- // square\r
-\r
- ASSERT(board->square[square]==piece);\r
- board->square[square] = Empty;\r
-\r
- ASSERT(board->pos[square]==pos);\r
- board->pos[square] = -1; // not needed\r
-\r
- // piece list\r
-\r
- ASSERT(board->list_size[colour]>=2);\r
- size = --board->list_size[colour];\r
- ASSERT(pos<=size);\r
-\r
- if (pos != size) {\r
-\r
- sq = board->list[colour][size];\r
- ASSERT(square_is_ok(sq));\r
- ASSERT(sq!=square);\r
-\r
- ASSERT(board->pos[sq]==size);\r
- board->pos[sq] = pos;\r
-\r
- ASSERT(board->list[colour][pos]==square);\r
- board->list[colour][pos] = sq;\r
- }\r
-\r
- board->list[colour][size] = SquareNone;\r
-\r
- // material\r
-\r
- ASSERT(board->number[piece_12]>=1);\r
- board->number[piece_12]--;\r
-\r
- // hash key\r
-\r
- board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));\r
-}\r
-\r
-// square_set()\r
-\r
-static void square_set(board_t * board, int square, int piece, int pos) {\r
-\r
- int piece_12, colour;\r
- int sq, size;\r
-\r
- ASSERT(board!=NULL);\r
- ASSERT(square_is_ok(square));\r
- ASSERT(piece_is_ok(piece));\r
- ASSERT(pos>=0);\r
-\r
- // init\r
-\r
- colour = piece_colour(piece);\r
- piece_12 = piece_to_12(piece);\r
-\r
- // square\r
-\r
- ASSERT(board->square[square]==Empty);\r
- board->square[square] = piece;\r
-\r
- ASSERT(board->pos[square]==-1);\r
- board->pos[square] = pos;\r
-\r
- // piece list\r
-\r
- size = board->list_size[colour]++;\r
- ASSERT(board->list[colour][size]==SquareNone);\r
- ASSERT(pos<=size);\r
-\r
- if (pos != size) {\r
-\r
- sq = board->list[colour][pos];\r
- ASSERT(square_is_ok(sq));\r
- ASSERT(sq!=square);\r
-\r
- ASSERT(board->pos[sq]==pos);\r
- board->pos[sq] = size;\r
-\r
- ASSERT(board->list[colour][size]==SquareNone);\r
- board->list[colour][size] = sq;\r
- }\r
-\r
- board->list[colour][pos] = square;\r
-\r
- // material\r
-\r
- ASSERT(board->number[piece_12]<=8);\r
- board->number[piece_12]++;\r
-\r
- // hash key\r
-\r
- board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));\r
-}\r
-\r
-// square_move()\r
-\r
-static void square_move(board_t * board, int from, int to, int piece) {\r
-\r
- int colour, pos;\r
- int piece_index;\r
-\r
- ASSERT(board!=NULL);\r
- ASSERT(square_is_ok(from));\r
- ASSERT(square_is_ok(to));\r
- ASSERT(piece_is_ok(piece));\r
-\r
- // init\r
-\r
- colour = piece_colour(piece);\r
-\r
- pos = board->pos[from];\r
- ASSERT(pos>=0);\r
-\r
- // from\r
-\r
- ASSERT(board->square[from]==piece);\r
- board->square[from] = Empty;\r
-\r
- ASSERT(board->pos[from]==pos);\r
- board->pos[from] = -1; // not needed\r
-\r
- // to\r
-\r
- ASSERT(board->square[to]==Empty);\r
- board->square[to] = piece;\r
-\r
- ASSERT(board->pos[to]==-1);\r
- board->pos[to] = pos;\r
-\r
- // piece list\r
-\r
- ASSERT(board->list[colour][pos]==from);\r
- board->list[colour][pos] = to;\r
-\r
- // hash key\r
-\r
- piece_index = RandomPiece + piece_to_12(piece) * 64;\r
-\r
- board->key ^= random_64(piece_index+square_to_64(from))\r
- ^ random_64(piece_index+square_to_64(to));\r
-}\r
-\r
-// end of move_do.cpp\r
-\r
+
+// move_do.c
+
+// includes
+
+#include <stdlib.h>
+
+#include "board.h"
+#include "colour.h"
+#include "hash.h"
+#include "move.h"
+#include "move_do.h"
+#include "move_legal.h"
+#include "piece.h"
+#include "random.h"
+#include "util.h"
+
+// prototypes
+
+static void square_clear (board_t * board, int square, int piece);
+static void square_set (board_t * board, int square, int piece, int pos);
+static void square_move (board_t * board, int from, int to, int piece);
+
+// functions
+
+// move_do()
+
+void move_do(board_t * board, int move) {
+
+ int me, opp;
+ int from, to;
+ int piece, pos, capture;
+ int old_flags, new_flags;
+ int sq, ep_square;
+ int pawn;
+
+ ASSERT(board_is_ok(board));
+ ASSERT(move_is_ok(move));
+
+ ASSERT(move_is_pseudo(move,board));
+
+ // init
+
+ me = board->turn;
+ opp = colour_opp(me);
+
+ from = move_from(move);
+ to = move_to(move);
+
+ piece = board->square[from];
+ ASSERT(colour_equal(piece,me));
+
+ pos = board->pos[from];
+ ASSERT(pos>=0);
+
+ // update turn
+
+ board->turn = opp;
+ board->key ^= random_64(RandomTurn);
+
+ // update castling rights
+
+ old_flags = board_flags(board);
+
+ if (piece_is_king(piece)) {
+ board->castle[me][SideH] = SquareNone;
+ board->castle[me][SideA] = SquareNone;
+ }
+
+ if (board->castle[me][SideH] == from) board->castle[me][SideH] = SquareNone;
+ if (board->castle[me][SideA] == from) board->castle[me][SideA] = SquareNone;
+
+ if (board->castle[opp][SideH] == to) board->castle[opp][SideH] = SquareNone;
+ if (board->castle[opp][SideA] == to) board->castle[opp][SideA] = SquareNone;
+
+ new_flags = board_flags(board);
+
+ board->key ^= hash_castle_key(new_flags^old_flags); // HACK
+
+ // update en-passant square
+
+ ep_square = sq = board->ep_square;
+ if (sq != SquareNone) {
+ board->key ^= random_64(RandomEnPassant+square_file(sq));
+ board->ep_square = SquareNone;
+ }
+
+ if (piece_is_pawn(piece) && abs(to-from) == 32) {
+ pawn = piece_make_pawn(opp);
+ if (board->square[to-1] == pawn || board->square[to+1] == pawn) {
+ board->ep_square = sq = (from + to) / 2;
+ board->key ^= random_64(RandomEnPassant+square_file(sq));
+ }
+ }
+
+ // update ply number (captures are handled later)
+
+ board->ply_nb++;
+ if (piece_is_pawn(piece)) board->ply_nb = 0; // conversion
+
+ // update move number
+
+ if (me == Black) board->move_nb++;
+
+ // castle
+
+ if (colour_equal(board->square[to],me)) {
+
+ int rank;
+ int king_from, king_to;
+ int rook_from, rook_to;
+ int rook;
+
+ rank = colour_is_white(me) ? Rank1 : Rank8;
+
+ king_from = from;
+ rook_from = to;
+
+ if (to > from) { // h side
+ king_to = square_make(FileG,rank);
+ rook_to = square_make(FileF,rank);
+ } else { // a side
+ king_to = square_make(FileC,rank);
+ rook_to = square_make(FileD,rank);
+ }
+
+ // remove the rook
+
+ pos = board->pos[rook_from];
+ ASSERT(pos>=0);
+
+ rook = Rook64 | me; // HACK
+
+ square_clear(board,rook_from,rook);
+
+ // move the king
+
+ square_move(board,king_from,king_to,piece);
+
+ // put the rook back
+
+ square_set(board,rook_to,rook,pos);
+
+ ASSERT(board->key==hash_key(board));
+
+ return;
+ }
+
+ // remove the captured piece
+
+ if (piece_is_pawn(piece) && to == ep_square) {
+
+ // en-passant capture
+
+ sq = square_ep_dual(to);
+ capture = board->square[sq];
+ ASSERT(capture==piece_make_pawn(opp));
+
+ square_clear(board,sq,capture);
+
+ board->ply_nb = 0; // conversion
+
+ } else {
+
+ capture = board->square[to];
+
+ if (capture != Empty) {
+
+ // normal capture
+
+ ASSERT(colour_equal(capture,opp));
+ ASSERT(!piece_is_king(capture));
+
+ square_clear(board,to,capture);
+
+ board->ply_nb = 0; // conversion
+ }
+ }
+
+ // move the piece
+
+ if (move_is_promote(move)) {
+
+ // promote
+
+ square_clear(board,from,piece);
+ piece = move_promote_hack(move) | me; // HACK
+ square_set(board,to,piece,pos);
+
+ } else {
+
+ // normal move
+
+ square_move(board,from,to,piece);
+ }
+
+ ASSERT(board->key==hash_key(board));
+}
+
+// square_clear()
+
+static void square_clear(board_t * board, int square, int piece) {
+
+ int pos, piece_12, colour;
+ int sq, size;
+
+ ASSERT(board!=NULL);
+ ASSERT(square_is_ok(square));
+ ASSERT(piece_is_ok(piece));
+
+ // init
+
+ pos = board->pos[square];
+ ASSERT(pos>=0);
+
+ colour = piece_colour(piece);
+ piece_12 = piece_to_12(piece);
+
+ // square
+
+ ASSERT(board->square[square]==piece);
+ board->square[square] = Empty;
+
+ ASSERT(board->pos[square]==pos);
+ board->pos[square] = -1; // not needed
+
+ // piece list
+
+ ASSERT(board->list_size[colour]>=2);
+ size = --board->list_size[colour];
+ ASSERT(pos<=size);
+
+ if (pos != size) {
+
+ sq = board->list[colour][size];
+ ASSERT(square_is_ok(sq));
+ ASSERT(sq!=square);
+
+ ASSERT(board->pos[sq]==size);
+ board->pos[sq] = pos;
+
+ ASSERT(board->list[colour][pos]==square);
+ board->list[colour][pos] = sq;
+ }
+
+ board->list[colour][size] = SquareNone;
+
+ // material
+
+ ASSERT(board->number[piece_12]>=1);
+ board->number[piece_12]--;
+
+ // hash key
+
+ board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));
+}
+
+// square_set()
+
+static void square_set(board_t * board, int square, int piece, int pos) {
+
+ int piece_12, colour;
+ int sq, size;
+
+ ASSERT(board!=NULL);
+ ASSERT(square_is_ok(square));
+ ASSERT(piece_is_ok(piece));
+ ASSERT(pos>=0);
+
+ // init
+
+ colour = piece_colour(piece);
+ piece_12 = piece_to_12(piece);
+
+ // square
+
+ ASSERT(board->square[square]==Empty);
+ board->square[square] = piece;
+
+ ASSERT(board->pos[square]==-1);
+ board->pos[square] = pos;
+
+ // piece list
+
+ size = board->list_size[colour]++;
+ ASSERT(board->list[colour][size]==SquareNone);
+ ASSERT(pos<=size);
+
+ if (pos != size) {
+
+ sq = board->list[colour][pos];
+ ASSERT(square_is_ok(sq));
+ ASSERT(sq!=square);
+
+ ASSERT(board->pos[sq]==pos);
+ board->pos[sq] = size;
+
+ ASSERT(board->list[colour][size]==SquareNone);
+ board->list[colour][size] = sq;
+ }
+
+ board->list[colour][pos] = square;
+
+ // material
+
+ ASSERT(board->number[piece_12]<=8);
+ board->number[piece_12]++;
+
+ // hash key
+
+ board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));
+}
+
+// square_move()
+
+static void square_move(board_t * board, int from, int to, int piece) {
+
+ int colour, pos;
+ int piece_index;
+
+ ASSERT(board!=NULL);
+ ASSERT(square_is_ok(from));
+ ASSERT(square_is_ok(to));
+ ASSERT(piece_is_ok(piece));
+
+ // init
+
+ colour = piece_colour(piece);
+
+ pos = board->pos[from];
+ ASSERT(pos>=0);
+
+ // from
+
+ ASSERT(board->square[from]==piece);
+ board->square[from] = Empty;
+
+ ASSERT(board->pos[from]==pos);
+ board->pos[from] = -1; // not needed
+
+ // to
+
+ ASSERT(board->square[to]==Empty);
+ board->square[to] = piece;
+
+ ASSERT(board->pos[to]==-1);
+ board->pos[to] = pos;
+
+ // piece list
+
+ ASSERT(board->list[colour][pos]==from);
+ board->list[colour][pos] = to;
+
+ // hash key
+
+ piece_index = RandomPiece + piece_to_12(piece) * 64;
+
+ board->key ^= random_64(piece_index+square_to_64(from))
+ ^ random_64(piece_index+square_to_64(to));
+}
+
+// end of move_do.cpp
+