5 #define DropB( PIECE, piece ) Xor( to, BB_B ## PIECE ); \
6 HASH_KEY ^= ( b_ ## piece ## _rand )[to]; \
7 HAND_B -= flag_hand_ ## piece; \
10 #define DropW( PIECE, piece ) Xor( to, BB_W ## PIECE ); \
11 HASH_KEY ^= ( w_ ## piece ## _rand )[to]; \
12 HAND_W -= flag_hand_ ## piece; \
15 #define CapB( PIECE, piece, pro_piece ) \
16 Xor( to, BB_B ## PIECE ); \
17 HASH_KEY ^= ( b_ ## pro_piece ## _rand )[to]; \
18 HAND_W += flag_hand_ ## piece; \
19 MATERIAL -= MT_CAP_ ## PIECE
21 #define CapW( PIECE, piece, pro_piece ) \
22 Xor( to, BB_W ## PIECE ); \
23 HASH_KEY ^= ( w_ ## pro_piece ## _rand )[to]; \
24 HAND_B += flag_hand_ ## piece; \
25 MATERIAL += MT_CAP_ ## PIECE
27 #define NocapProB( PIECE, PRO_PIECE, piece, pro_piece ) \
28 Xor( from, BB_B ## PIECE ); \
29 Xor( to, BB_B ## PRO_PIECE ); \
30 HASH_KEY ^= ( b_ ## pro_piece ## _rand )[to] \
31 ^ ( b_ ## piece ## _rand )[from]; \
32 MATERIAL += MT_PRO_ ## PIECE; \
35 #define NocapProW( PIECE, PRO_PIECE, piece, pro_piece ) \
36 Xor( from, BB_W ## PIECE ); \
37 Xor( to, BB_W ## PRO_PIECE ); \
38 HASH_KEY ^= ( w_ ## pro_piece ## _rand )[to] \
39 ^ ( w_ ## piece ## _rand )[from]; \
40 MATERIAL -= MT_PRO_ ## PIECE; \
41 BOARD[to] = - pro_piece
43 #define NocapNoproB( PIECE, piece ) \
44 SetClear( BB_B ## PIECE ); \
45 HASH_KEY ^= ( b_ ## piece ## _rand )[to] \
46 ^ ( b_ ## piece ## _rand )[from]; \
49 #define NocapNoproW( PIECE, piece ) \
50 SetClear( BB_W ## PIECE ); \
51 HASH_KEY ^= ( w_ ## piece ## _rand )[to] \
52 ^ ( w_ ## piece ## _rand )[from]; \
57 make_move_b( tree_t * restrict ptree, unsigned int move, int ply )
59 const int from = (int)I2From(move);
60 const int to = (int)I2To(move);
61 const int nrep = root_nrep + ply - 1;
63 assert( UToCap(move) != king );
65 assert( is_move_valid( ptree, move, black ) );
67 ptree->rep_board_list[nrep] = HASH_KEY;
68 ptree->rep_hand_list[nrep] = HAND_B;
69 ptree->save_material[ply] = (short)MATERIAL;
70 ptree->stand_pat[ply+1] = score_bound;
72 if ( from >= nsquare )
74 switch ( From2Drop(from) )
76 case pawn: Xor( to-nfile, BB_BPAWN_ATK );
77 DropB( PAWN, pawn ); break;
78 case lance: DropB( LANCE, lance ); break;
79 case knight: DropB( KNIGHT, knight ); break;
80 case silver: DropB( SILVER, silver ); break;
81 case gold: DropB( GOLD, gold );
82 Xor( to, BB_BTGOLD ); break;
83 case bishop: DropB( BISHOP, bishop );
84 Xor( to, BB_B_BH ); break;
85 default: assert( From2Drop(from) == rook );
87 Xor( to, BB_B_RD ); break;
89 Xor( to, BB_BOCCUPY );
90 XorFile( to, OCCUPIED_FILE );
91 XorDiag2( to, OCCUPIED_DIAG2 );
92 XorDiag1( to, OCCUPIED_DIAG1 );
95 const int ipiece_move = (int)I2PieceMove(move);
96 const int ipiece_cap = (int)UToCap(move);
97 const int is_promote = (int)I2IsPromote(move);
98 bitboard_t bb_set_clear;
100 BBOr( bb_set_clear, abb_mask[from], abb_mask[to] );
101 SetClear( BB_BOCCUPY );
104 if ( is_promote ) switch( ipiece_move )
106 case pawn: Xor( to, BB_BPAWN_ATK );
107 Xor( to, BB_BTGOLD );
108 NocapProB( PAWN, PRO_PAWN, pawn, pro_pawn ); break;
109 case lance: Xor( to, BB_BTGOLD );
110 NocapProB( LANCE, PRO_LANCE, lance, pro_lance ); break;
111 case knight: Xor( to, BB_BTGOLD );
112 NocapProB( KNIGHT, PRO_KNIGHT, knight, pro_knight ); break;
113 case silver: Xor( to, BB_BTGOLD );
114 NocapProB( SILVER, PRO_SILVER, silver, pro_silver ); break;
115 case bishop: Xor( to, BB_B_HDK );
117 NocapProB( BISHOP, HORSE, bishop, horse ); break;
118 default: assert( ipiece_move == rook );
121 NocapProB( ROOK, DRAGON, rook, dragon ); break;
123 else switch ( ipiece_move )
125 case pawn: Xor( to-nfile, BB_BPAWN_ATK );
126 Xor( to, BB_BPAWN_ATK );
127 NocapNoproB( PAWN, pawn); break;
128 case lance: NocapNoproB( LANCE, lance); break;
129 case knight: NocapNoproB( KNIGHT, knight); break;
130 case silver: NocapNoproB( SILVER, silver); break;
131 case gold: NocapNoproB( GOLD, gold);
132 SetClear( BB_BTGOLD ); break;
133 case bishop: SetClear( BB_B_BH );
134 NocapNoproB( BISHOP, bishop); break;
135 case rook: NocapNoproB( ROOK, rook);
136 SetClear( BB_B_RD ); break;
137 case king: HASH_KEY ^= b_king_rand[to] ^ b_king_rand[from];
138 SetClear( BB_B_HDK );
140 SQ_BKING = (char)to; break;
141 case pro_pawn: NocapNoproB( PRO_PAWN, pro_pawn );
142 SetClear( BB_BTGOLD ); break;
143 case pro_lance: NocapNoproB( PRO_LANCE, pro_lance );
144 SetClear( BB_BTGOLD ); break;
145 case pro_knight: NocapNoproB( PRO_KNIGHT, pro_knight );
146 SetClear( BB_BTGOLD ); break;
147 case pro_silver: NocapNoproB( PRO_SILVER, pro_silver );
148 SetClear( BB_BTGOLD ); break;
149 case horse: NocapNoproB( HORSE, horse );
150 SetClear( BB_B_HDK );
151 SetClear( BB_B_BH ); break;
152 default: assert( ipiece_move == dragon );
153 NocapNoproB( DRAGON, dragon );
154 SetClear( BB_B_HDK );
155 SetClear( BB_B_RD ); break;
162 case pawn: CapW( PAWN, pawn, pawn );
163 Xor( to+nfile, BB_WPAWN_ATK ); break;
164 case lance: CapW( LANCE, lance, lance ); break;
165 case knight: CapW( KNIGHT, knight, knight ); break;
166 case silver: CapW( SILVER, silver, silver ); break;
167 case gold: CapW( GOLD, gold, gold );
168 Xor( to, BB_WTGOLD ); break;
169 case bishop: CapW( BISHOP, bishop, bishop );
170 Xor( to, BB_W_BH ); break;
171 case rook: CapW( ROOK, rook, rook);
172 Xor( to, BB_W_RD ); break;
173 case pro_pawn: CapW( PRO_PAWN, pawn, pro_pawn );
174 Xor( to, BB_WTGOLD ); break;
175 case pro_lance: CapW( PRO_LANCE, lance, pro_lance );
176 Xor( to, BB_WTGOLD ); break;
177 case pro_knight: CapW( PRO_KNIGHT, knight, pro_knight );
178 Xor( to, BB_WTGOLD ); break;
179 case pro_silver: CapW( PRO_SILVER, silver, pro_silver );
180 Xor( to, BB_WTGOLD ); break;
181 case horse: CapW( HORSE, bishop, horse );
183 Xor( to, BB_W_BH ); break;
184 default: assert( ipiece_cap == dragon );
185 CapW( DRAGON, rook, dragon );
187 Xor( to, BB_W_RD ); break;
189 Xor( to, BB_WOCCUPY );
190 XorFile( from, OCCUPIED_FILE );
191 XorDiag2( from, OCCUPIED_DIAG2 );
192 XorDiag1( from, OCCUPIED_DIAG1 );
195 SetClearFile( from, to, OCCUPIED_FILE );
196 SetClearDiag1( from, to, OCCUPIED_DIAG1 );
197 SetClearDiag2( from, to, OCCUPIED_DIAG2 );
201 assert( exam_bb( ptree ) );
206 make_move_w( tree_t * restrict ptree, unsigned int move, int ply )
208 const int from = (int)I2From(move);
209 const int to = (int)I2To(move);
210 const int nrep = root_nrep + ply - 1;
212 assert( UToCap(move) != king );
214 assert( is_move_valid( ptree, move, white ) );
216 ptree->rep_board_list[nrep] = HASH_KEY;
217 ptree->rep_hand_list[nrep] = HAND_B;
218 ptree->save_material[ply] = (short)MATERIAL;
219 ptree->stand_pat[ply+1] = score_bound;
221 if ( from >= nsquare )
223 switch( From2Drop(from) )
225 case pawn: Xor( to+nfile, BB_WPAWN_ATK );
226 DropW( PAWN, pawn ); break;
227 case lance: DropW( LANCE, lance ); break;
228 case knight: DropW( KNIGHT, knight ); break;
229 case silver: DropW( SILVER, silver ); break;
230 case gold: DropW( GOLD, gold );
231 Xor( to, BB_WTGOLD ); break;
232 case bishop: DropW( BISHOP, bishop );
233 Xor( to, BB_W_BH ); break;
234 default: DropW( ROOK, rook );
235 Xor( to, BB_W_RD ); break;
237 Xor( to, BB_WOCCUPY );
238 XorFile( to, OCCUPIED_FILE );
239 XorDiag2( to, OCCUPIED_DIAG2 );
240 XorDiag1( to, OCCUPIED_DIAG1 );
243 const int ipiece_move = (int)I2PieceMove(move);
244 const int ipiece_cap = (int)UToCap(move);
245 const int is_promote = (int)I2IsPromote(move);
246 bitboard_t bb_set_clear;
248 BBOr( bb_set_clear, abb_mask[from], abb_mask[to] );
249 SetClear( BB_WOCCUPY );
252 if ( is_promote) switch( ipiece_move )
254 case pawn: NocapProW( PAWN, PRO_PAWN, pawn, pro_pawn );
255 Xor( to, BB_WPAWN_ATK );
256 Xor( to, BB_WTGOLD ); break;
257 case lance: NocapProW( LANCE, PRO_LANCE, lance, pro_lance );
258 Xor( to, BB_WTGOLD ); break;
259 case knight: NocapProW( KNIGHT, PRO_KNIGHT, knight, pro_knight );
260 Xor( to, BB_WTGOLD ); break;
261 case silver: NocapProW( SILVER, PRO_SILVER, silver, pro_silver );
262 Xor( to, BB_WTGOLD ); break;
263 case bishop: NocapProW( BISHOP, HORSE, bishop, horse );
265 SetClear( BB_W_BH ); break;
266 default: NocapProW( ROOK, DRAGON, rook, dragon);
268 SetClear( BB_W_RD ); break;
270 else switch ( ipiece_move )
272 case pawn: NocapNoproW( PAWN, pawn );
273 Xor( to+nfile, BB_WPAWN_ATK );
274 Xor( to, BB_WPAWN_ATK ); break;
275 case lance: NocapNoproW( LANCE, lance); break;
276 case knight: NocapNoproW( KNIGHT, knight); break;
277 case silver: NocapNoproW( SILVER, silver); break;
278 case gold: NocapNoproW( GOLD, gold);
279 SetClear( BB_WTGOLD ); break;
280 case bishop: NocapNoproW( BISHOP, bishop);
281 SetClear( BB_W_BH ); break;
282 case rook: NocapNoproW( ROOK, rook);
283 SetClear( BB_W_RD ); break;
284 case king: HASH_KEY ^= w_king_rand[to] ^ w_king_rand[from];
287 SetClear( BB_W_HDK ); break;
288 case pro_pawn: NocapNoproW( PRO_PAWN, pro_pawn);
289 SetClear( BB_WTGOLD ); break;
290 case pro_lance: NocapNoproW( PRO_LANCE, pro_lance);
291 SetClear( BB_WTGOLD ); break;
292 case pro_knight: NocapNoproW( PRO_KNIGHT, pro_knight);
293 SetClear( BB_WTGOLD ); break;
294 case pro_silver: NocapNoproW( PRO_SILVER, pro_silver);
295 SetClear( BB_WTGOLD ); break;
296 case horse: NocapNoproW( HORSE, horse );
297 SetClear( BB_W_HDK );
298 SetClear( BB_W_BH ); break;
299 default: NocapNoproW( DRAGON, dragon );
300 SetClear( BB_W_HDK );
301 SetClear( BB_W_RD ); break;
308 case pawn: CapB( PAWN, pawn, pawn );
309 Xor( to-nfile, BB_BPAWN_ATK ); break;
310 case lance: CapB( LANCE, lance, lance ); break;
311 case knight: CapB( KNIGHT, knight, knight ); break;
312 case silver: CapB( SILVER, silver, silver ); break;
313 case gold: CapB( GOLD, gold, gold );
314 Xor( to, BB_BTGOLD ); break;
315 case bishop: CapB( BISHOP, bishop, bishop );
316 Xor( to, BB_B_BH ); break;
317 case rook: CapB( ROOK, rook, rook );
318 Xor( to, BB_B_RD ); break;
319 case pro_pawn: CapB( PRO_PAWN, pawn, pro_pawn );
320 Xor( to, BB_BTGOLD ); break;
321 case pro_lance: CapB( PRO_LANCE, lance, pro_lance );
322 Xor( to, BB_BTGOLD ); break;
323 case pro_knight: CapB( PRO_KNIGHT, knight, pro_knight );
324 Xor( to, BB_BTGOLD ); break;
325 case pro_silver: CapB( PRO_SILVER, silver, pro_silver );
326 Xor( to, BB_BTGOLD ); break;
327 case horse: CapB( HORSE, bishop, horse );
329 Xor( to, BB_B_BH ); break;
330 default: CapB( DRAGON, rook, dragon );
332 Xor( to, BB_B_RD ); break;
334 Xor( to, BB_BOCCUPY );
335 XorFile( from, OCCUPIED_FILE );
336 XorDiag1( from, OCCUPIED_DIAG1 );
337 XorDiag2( from, OCCUPIED_DIAG2 );
340 SetClearFile( from, to, OCCUPIED_FILE );
341 SetClearDiag1( from, to, OCCUPIED_DIAG1 );
342 SetClearDiag2( from, to, OCCUPIED_DIAG2 );
346 assert( exam_bb( ptree ) );
367 make_move_root( tree_t * restrict ptree, unsigned int move, int flag )
369 int check, drawn, iret, i, n;
371 ptree->save_material[0] = (short)MATERIAL;
372 MakeMove( root_turn, move, 1 );
374 /* detect hang-king */
375 if ( ( flag & flag_detect_hang ) && InCheck(root_turn) )
377 str_error = str_king_hang;
378 UnMakeMove( root_turn, move, 1 );
383 check = InCheck( Flip(root_turn) );
384 ptree->move_last[1] = ptree->move_last[0];
387 ptree->nsuc_check[2] = (unsigned char)( ptree->nsuc_check[0] + 1U );
389 else { ptree->nsuc_check[2] = 0; }
391 /* detect repetitions */
392 if ( flag & flag_rep )
394 switch ( detect_repetition( ptree, 2, Flip(root_turn), 3 ) )
396 case perpetual_check:
397 str_error = str_perpet_check;
398 UnMakeMove( root_turn, move, 1 );
407 /* return, since all of rule-checks were done */
408 if ( flag & flag_nomake_move )
410 UnMakeMove( root_turn, move, 1 );
411 return drawn ? 2 : 1;
414 if ( drawn ) { game_status |= flag_drawn; }
417 if ( flag & flag_time )
419 iret = renovate_time( root_turn );
420 if ( iret < 0 ) { return iret; }
423 root_turn = Flip( root_turn );
424 move_list[move_ptr++] = move; // [HGM] undo: remember all moves played in root
426 /* detect checkmate */
427 if ( check && is_mate( ptree, 1 ) ) { game_status |= flag_mated; }
430 if ( flag & flag_history )
432 /* save history for book learning */
433 if ( record_game.moves < HASH_REG_HIST_LEN )
435 history_book_learn[ record_game.moves ].move_played = move;
436 history_book_learn[ record_game.moves ].hand_played
437 = ptree->rep_hand_list[ root_nrep ];
438 history_book_learn[ record_game.moves ].key_played
439 = (unsigned int)ptree->rep_board_list[ root_nrep ];
442 out_CSA( ptree, &record_game, move );
446 if ( flag & flag_rejections ) { add_rejections_root( ptree, move ); }
448 /* renew repetition table */
450 if ( n >= REP_HIST_LEN - PLY_MAX -1 )
452 for ( i = 0; i < n; i++ )
454 ptree->rep_board_list[i] = ptree->rep_board_list[i+1];
455 ptree->rep_hand_list[i] = ptree->rep_hand_list[i+1];
458 else { root_nrep++; }
460 ptree->nsuc_check[PLY_MAX] = ptree->nsuc_check[0];
461 ptree->nsuc_check[0] = ptree->nsuc_check[1];
462 ptree->nsuc_check[1] = ptree->nsuc_check[2];
465 last_root_value_save = last_root_value;
466 last_pv_save = last_pv;
467 if ( last_pv.a[1] == move && last_pv.length >= 2 )
471 #if PLY_INC == EXT_CHECK
477 memmove( &(last_pv.a[1]), &(last_pv.a[2]),
478 last_pv.length * sizeof( unsigned int ) );
493 unmake_move_root( tree_t * restrict ptree, unsigned int move )
495 last_root_value = last_root_value_save;
496 last_pv = last_pv_save;
498 ptree->nsuc_check[1] = ptree->nsuc_check[0];
499 ptree->nsuc_check[0] = ptree->nsuc_check[PLY_MAX];
502 game_status &= ~( flag_drawn | flag_mated );
503 root_turn = Flip(root_turn);
504 move_ptr--; // [HGM] undo: clip last move off game history
506 ptree->save_material[1] = ptree->save_material[0];
507 UnMakeMove( root_turn, move, 1 );
509 sub_rejections_root( ptree, move );