13 #include "move_legal.h"
20 static void square_clear (board_t * board, int square, int piece);
21 static void square_set (board_t * board, int square, int piece, int pos);
22 static void square_move (board_t * board, int from, int to, int piece);
28 void move_do(board_t * board, int move) {
32 int piece, pos, capture;
33 int old_flags, new_flags;
37 ASSERT(board_is_ok(board));
38 ASSERT(move_is_ok(move));
40 ASSERT(move_is_pseudo(move,board));
47 from = move_from(move);
50 piece = board->square[from];
51 ASSERT(colour_equal(piece,me));
53 pos = board->pos[from];
59 board->key ^= random_64(RandomTurn);
61 // update castling rights
63 old_flags = board_flags(board);
65 if (piece_is_king(piece)) {
66 board->castle[me][SideH] = SquareNone;
67 board->castle[me][SideA] = SquareNone;
70 if (board->castle[me][SideH] == from) board->castle[me][SideH] = SquareNone;
71 if (board->castle[me][SideA] == from) board->castle[me][SideA] = SquareNone;
73 if (board->castle[opp][SideH] == to) board->castle[opp][SideH] = SquareNone;
74 if (board->castle[opp][SideA] == to) board->castle[opp][SideA] = SquareNone;
76 new_flags = board_flags(board);
78 board->key ^= hash_castle_key(new_flags^old_flags); // HACK
80 // update en-passant square
82 ep_square = sq = board->ep_square;
83 if (sq != SquareNone) {
84 board->key ^= random_64(RandomEnPassant+square_file(sq));
85 board->ep_square = SquareNone;
88 if (piece_is_pawn(piece) && abs(to-from) == 32) {
89 pawn = piece_make_pawn(opp);
90 if (board->square[to-1] == pawn || board->square[to+1] == pawn) {
91 board->ep_square = sq = (from + to) / 2;
92 board->key ^= random_64(RandomEnPassant+square_file(sq));
96 // update ply number (captures are handled later)
99 if (piece_is_pawn(piece)) board->ply_nb = 0; // conversion
101 // update move number
103 if (me == Black) board->move_nb++;
107 if (colour_equal(board->square[to],me)) {
110 int king_from, king_to;
111 int rook_from, rook_to;
114 rank = colour_is_white(me) ? Rank1 : Rank8;
119 if (to > from) { // h side
120 king_to = square_make(FileG,rank);
121 rook_to = square_make(FileF,rank);
123 king_to = square_make(FileC,rank);
124 rook_to = square_make(FileD,rank);
129 pos = board->pos[rook_from];
132 rook = Rook64 | me; // HACK
134 square_clear(board,rook_from,rook);
138 square_move(board,king_from,king_to,piece);
142 square_set(board,rook_to,rook,pos);
144 ASSERT(board->key==hash_key(board));
149 // remove the captured piece
151 if (piece_is_pawn(piece) && to == ep_square) {
153 // en-passant capture
155 sq = square_ep_dual(to);
156 capture = board->square[sq];
157 ASSERT(capture==piece_make_pawn(opp));
159 square_clear(board,sq,capture);
161 board->ply_nb = 0; // conversion
165 capture = board->square[to];
167 if (capture != Empty) {
171 ASSERT(colour_equal(capture,opp));
172 ASSERT(!piece_is_king(capture));
174 square_clear(board,to,capture);
176 board->ply_nb = 0; // conversion
182 if (move_is_promote(move)) {
186 square_clear(board,from,piece);
187 piece = move_promote_hack(move) | me; // HACK
188 square_set(board,to,piece,pos);
194 square_move(board,from,to,piece);
197 ASSERT(board->key==hash_key(board));
202 static void square_clear(board_t * board, int square, int piece) {
204 int pos, piece_12, colour;
208 ASSERT(square_is_ok(square));
209 ASSERT(piece_is_ok(piece));
213 pos = board->pos[square];
216 colour = piece_colour(piece);
217 piece_12 = piece_to_12(piece);
221 ASSERT(board->square[square]==piece);
222 board->square[square] = Empty;
224 ASSERT(board->pos[square]==pos);
225 board->pos[square] = -1; // not needed
229 ASSERT(board->list_size[colour]>=2);
230 size = --board->list_size[colour];
235 sq = board->list[colour][size];
236 ASSERT(square_is_ok(sq));
239 ASSERT(board->pos[sq]==size);
240 board->pos[sq] = pos;
242 ASSERT(board->list[colour][pos]==square);
243 board->list[colour][pos] = sq;
246 board->list[colour][size] = SquareNone;
250 ASSERT(board->number[piece_12]>=1);
251 board->number[piece_12]--;
255 board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));
260 static void square_set(board_t * board, int square, int piece, int pos) {
262 int piece_12, colour;
266 ASSERT(square_is_ok(square));
267 ASSERT(piece_is_ok(piece));
272 colour = piece_colour(piece);
273 piece_12 = piece_to_12(piece);
277 ASSERT(board->square[square]==Empty);
278 board->square[square] = piece;
280 ASSERT(board->pos[square]==-1);
281 board->pos[square] = pos;
285 size = board->list_size[colour]++;
286 ASSERT(board->list[colour][size]==SquareNone);
291 sq = board->list[colour][pos];
292 ASSERT(square_is_ok(sq));
295 ASSERT(board->pos[sq]==pos);
296 board->pos[sq] = size;
298 ASSERT(board->list[colour][size]==SquareNone);
299 board->list[colour][size] = sq;
302 board->list[colour][pos] = square;
306 ASSERT(board->number[piece_12]<=8);
307 board->number[piece_12]++;
311 board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));
316 static void square_move(board_t * board, int from, int to, int piece) {
322 ASSERT(square_is_ok(from));
323 ASSERT(square_is_ok(to));
324 ASSERT(piece_is_ok(piece));
328 colour = piece_colour(piece);
330 pos = board->pos[from];
335 ASSERT(board->square[from]==piece);
336 board->square[from] = Empty;
338 ASSERT(board->pos[from]==pos);
339 board->pos[from] = -1; // not needed
343 ASSERT(board->square[to]==Empty);
344 board->square[to] = piece;
346 ASSERT(board->pos[to]==-1);
347 board->pos[to] = pos;
351 ASSERT(board->list[colour][pos]==from);
352 board->list[colour][pos] = to;
356 piece_index = RandomPiece + piece_to_12(piece) * 64;
358 board->key ^= random_64(piece_index+square_to_64(from))
359 ^ random_64(piece_index+square_to_64(to));
362 // end of move_do.cpp