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