6 #define DropB( PIECE, piece ) Xor( to, BB_B ## PIECE ); \
7 HASH_KEY ^= ( b_ ## piece ## _rand )[to]; \
8 HAND_B -= flag_hand_ ## piece; \
11 #define DropW( PIECE, piece ) Xor( to, BB_W ## PIECE ); \
12 HASH_KEY ^= ( w_ ## piece ## _rand )[to]; \
13 HAND_W -= flag_hand_ ## piece; \
16 #define CapB( PIECE, piece, pro_piece ) \
17 Xor( to, BB_B ## PIECE ); \
18 HASH_KEY ^= ( b_ ## pro_piece ## _rand )[to]; \
19 HAND_W += flag_hand_ ## piece; \
20 MATERIAL -= MT_CAP_ ## PIECE
22 #define CapW( PIECE, piece, pro_piece ) \
23 Xor( to, BB_W ## PIECE ); \
24 HASH_KEY ^= ( w_ ## pro_piece ## _rand )[to]; \
25 HAND_B += flag_hand_ ## piece; \
26 MATERIAL += MT_CAP_ ## PIECE
28 #define NocapProB( PIECE, PRO_PIECE, piece, pro_piece ) \
29 Xor( from, BB_B ## PIECE ); \
30 Xor( to, BB_B ## PRO_PIECE ); \
31 HASH_KEY ^= ( b_ ## pro_piece ## _rand )[to] \
32 ^ ( b_ ## piece ## _rand )[from]; \
33 MATERIAL += MT_PRO_ ## PIECE; \
36 #define NocapProW( PIECE, PRO_PIECE, piece, pro_piece ) \
37 Xor( from, BB_W ## PIECE ); \
38 Xor( to, BB_W ## PRO_PIECE ); \
39 HASH_KEY ^= ( w_ ## pro_piece ## _rand )[to] \
40 ^ ( w_ ## piece ## _rand )[from]; \
41 MATERIAL -= MT_PRO_ ## PIECE; \
42 BOARD[to] = - pro_piece
44 #define NocapNoproB( PIECE, piece ) \
45 SetClear( BB_B ## PIECE ); \
46 HASH_KEY ^= ( b_ ## piece ## _rand )[to] \
47 ^ ( b_ ## piece ## _rand )[from]; \
50 #define NocapNoproW( PIECE, piece ) \
51 SetClear( BB_W ## PIECE ); \
52 HASH_KEY ^= ( w_ ## piece ## _rand )[to] \
53 ^ ( w_ ## piece ## _rand )[from]; \
58 make_move_b( tree_t * restrict ptree, unsigned int move, int ply )
60 const int from = (int)I2From(move);
61 const int to = (int)I2To(move);
62 const int nrep = ptree->nrep + ply - 1;
64 assert( UToCap(move) != king );
66 assert( is_move_valid( ptree, move, black ) );
68 ptree->rep_board_list[nrep] = HASH_KEY;
69 ptree->rep_hand_list[nrep] = HAND_B;
70 ptree->save_material[ply] = (short)MATERIAL;
71 ptree->save_eval[ply+1] = INT_MAX;
73 if ( from >= nsquare )
75 switch ( From2Drop(from) )
77 case pawn: Xor( to-nfile, BB_BPAWN_ATK );
78 DropB( PAWN, pawn ); break;
79 case lance: DropB( LANCE, lance ); break;
80 case knight: DropB( KNIGHT, knight ); break;
81 case silver: DropB( SILVER, silver ); break;
82 case gold: DropB( GOLD, gold );
83 Xor( to, BB_BTGOLD ); break;
84 case bishop: DropB( BISHOP, bishop );
85 Xor( to, BB_B_BH ); break;
86 default: assert( From2Drop(from) == rook );
88 Xor( to, BB_B_RD ); break;
90 Xor( to, BB_BOCCUPY );
91 XorFile( to, OCCUPIED_FILE );
92 XorDiag2( to, OCCUPIED_DIAG2 );
93 XorDiag1( to, OCCUPIED_DIAG1 );
96 const int ipiece_move = (int)I2PieceMove(move);
97 const int ipiece_cap = (int)UToCap(move);
98 const int is_promote = (int)I2IsPromote(move);
99 bitboard_t bb_set_clear;
101 BBOr( bb_set_clear, abb_mask[from], abb_mask[to] );
102 SetClear( BB_BOCCUPY );
105 if ( is_promote ) switch( ipiece_move )
107 case pawn: Xor( to, BB_BPAWN_ATK );
108 Xor( to, BB_BTGOLD );
109 NocapProB( PAWN, PRO_PAWN, pawn, pro_pawn ); break;
110 case lance: Xor( to, BB_BTGOLD );
111 NocapProB( LANCE, PRO_LANCE, lance, pro_lance ); break;
112 case knight: Xor( to, BB_BTGOLD );
113 NocapProB( KNIGHT, PRO_KNIGHT, knight, pro_knight ); break;
114 case silver: Xor( to, BB_BTGOLD );
115 NocapProB( SILVER, PRO_SILVER, silver, pro_silver ); break;
116 case bishop: Xor( to, BB_B_HDK );
118 NocapProB( BISHOP, HORSE, bishop, horse ); break;
119 default: assert( ipiece_move == rook );
122 NocapProB( ROOK, DRAGON, rook, dragon ); break;
124 else switch ( ipiece_move )
126 case pawn: Xor( to-nfile, BB_BPAWN_ATK );
127 Xor( to, BB_BPAWN_ATK );
128 NocapNoproB( PAWN, pawn); break;
129 case lance: NocapNoproB( LANCE, lance); break;
130 case knight: NocapNoproB( KNIGHT, knight); break;
131 case silver: NocapNoproB( SILVER, silver); break;
132 case gold: NocapNoproB( GOLD, gold);
133 SetClear( BB_BTGOLD ); break;
134 case bishop: SetClear( BB_B_BH );
135 NocapNoproB( BISHOP, bishop); break;
136 case rook: NocapNoproB( ROOK, rook);
137 SetClear( BB_B_RD ); break;
138 case king: HASH_KEY ^= b_king_rand[to] ^ b_king_rand[from];
139 SetClear( BB_B_HDK );
141 SQ_BKING = (char)to; break;
142 case pro_pawn: NocapNoproB( PRO_PAWN, pro_pawn );
143 SetClear( BB_BTGOLD ); break;
144 case pro_lance: NocapNoproB( PRO_LANCE, pro_lance );
145 SetClear( BB_BTGOLD ); break;
146 case pro_knight: NocapNoproB( PRO_KNIGHT, pro_knight );
147 SetClear( BB_BTGOLD ); break;
148 case pro_silver: NocapNoproB( PRO_SILVER, pro_silver );
149 SetClear( BB_BTGOLD ); break;
150 case horse: NocapNoproB( HORSE, horse );
151 SetClear( BB_B_HDK );
152 SetClear( BB_B_BH ); break;
153 default: assert( ipiece_move == dragon );
154 NocapNoproB( DRAGON, dragon );
155 SetClear( BB_B_HDK );
156 SetClear( BB_B_RD ); break;
163 case pawn: CapW( PAWN, pawn, pawn );
164 Xor( to+nfile, BB_WPAWN_ATK ); break;
165 case lance: CapW( LANCE, lance, lance ); break;
166 case knight: CapW( KNIGHT, knight, knight ); break;
167 case silver: CapW( SILVER, silver, silver ); break;
168 case gold: CapW( GOLD, gold, gold );
169 Xor( to, BB_WTGOLD ); break;
170 case bishop: CapW( BISHOP, bishop, bishop );
171 Xor( to, BB_W_BH ); break;
172 case rook: CapW( ROOK, rook, rook);
173 Xor( to, BB_W_RD ); break;
174 case pro_pawn: CapW( PRO_PAWN, pawn, pro_pawn );
175 Xor( to, BB_WTGOLD ); break;
176 case pro_lance: CapW( PRO_LANCE, lance, pro_lance );
177 Xor( to, BB_WTGOLD ); break;
178 case pro_knight: CapW( PRO_KNIGHT, knight, pro_knight );
179 Xor( to, BB_WTGOLD ); break;
180 case pro_silver: CapW( PRO_SILVER, silver, pro_silver );
181 Xor( to, BB_WTGOLD ); break;
182 case horse: CapW( HORSE, bishop, horse );
184 Xor( to, BB_W_BH ); break;
185 default: assert( ipiece_cap == dragon );
186 CapW( DRAGON, rook, dragon );
188 Xor( to, BB_W_RD ); break;
190 Xor( to, BB_WOCCUPY );
191 XorFile( from, OCCUPIED_FILE );
192 XorDiag2( from, OCCUPIED_DIAG2 );
193 XorDiag1( from, OCCUPIED_DIAG1 );
196 SetClearFile( from, to, OCCUPIED_FILE );
197 SetClearDiag1( from, to, OCCUPIED_DIAG1 );
198 SetClearDiag2( from, to, OCCUPIED_DIAG2 );
202 assert( exam_bb( ptree ) );
207 make_move_w( tree_t * restrict ptree, unsigned int move, int ply )
209 const int from = (int)I2From(move);
210 const int to = (int)I2To(move);
211 const int nrep = ptree->nrep + ply - 1;
213 assert( UToCap(move) != king );
215 assert( is_move_valid( ptree, move, white ) );
217 ptree->rep_board_list[nrep] = HASH_KEY;
218 ptree->rep_hand_list[nrep] = HAND_B;
219 ptree->save_material[ply] = (short)MATERIAL;
220 ptree->save_eval[ply+1] = INT_MAX;
222 if ( from >= nsquare )
224 switch( From2Drop(from) )
226 case pawn: Xor( to+nfile, BB_WPAWN_ATK );
227 DropW( PAWN, pawn ); break;
228 case lance: DropW( LANCE, lance ); break;
229 case knight: DropW( KNIGHT, knight ); break;
230 case silver: DropW( SILVER, silver ); break;
231 case gold: DropW( GOLD, gold );
232 Xor( to, BB_WTGOLD ); break;
233 case bishop: DropW( BISHOP, bishop );
234 Xor( to, BB_W_BH ); break;
235 default: DropW( ROOK, rook );
236 Xor( to, BB_W_RD ); break;
238 Xor( to, BB_WOCCUPY );
239 XorFile( to, OCCUPIED_FILE );
240 XorDiag2( to, OCCUPIED_DIAG2 );
241 XorDiag1( to, OCCUPIED_DIAG1 );
244 const int ipiece_move = (int)I2PieceMove(move);
245 const int ipiece_cap = (int)UToCap(move);
246 const int is_promote = (int)I2IsPromote(move);
247 bitboard_t bb_set_clear;
249 BBOr( bb_set_clear, abb_mask[from], abb_mask[to] );
250 SetClear( BB_WOCCUPY );
253 if ( is_promote) switch( ipiece_move )
255 case pawn: NocapProW( PAWN, PRO_PAWN, pawn, pro_pawn );
256 Xor( to, BB_WPAWN_ATK );
257 Xor( to, BB_WTGOLD ); break;
258 case lance: NocapProW( LANCE, PRO_LANCE, lance, pro_lance );
259 Xor( to, BB_WTGOLD ); break;
260 case knight: NocapProW( KNIGHT, PRO_KNIGHT, knight, pro_knight );
261 Xor( to, BB_WTGOLD ); break;
262 case silver: NocapProW( SILVER, PRO_SILVER, silver, pro_silver );
263 Xor( to, BB_WTGOLD ); break;
264 case bishop: NocapProW( BISHOP, HORSE, bishop, horse );
266 SetClear( BB_W_BH ); break;
267 default: NocapProW( ROOK, DRAGON, rook, dragon);
269 SetClear( BB_W_RD ); break;
271 else switch ( ipiece_move )
273 case pawn: NocapNoproW( PAWN, pawn );
274 Xor( to+nfile, BB_WPAWN_ATK );
275 Xor( to, BB_WPAWN_ATK ); break;
276 case lance: NocapNoproW( LANCE, lance); break;
277 case knight: NocapNoproW( KNIGHT, knight); break;
278 case silver: NocapNoproW( SILVER, silver); break;
279 case gold: NocapNoproW( GOLD, gold);
280 SetClear( BB_WTGOLD ); break;
281 case bishop: NocapNoproW( BISHOP, bishop);
282 SetClear( BB_W_BH ); break;
283 case rook: NocapNoproW( ROOK, rook);
284 SetClear( BB_W_RD ); break;
285 case king: HASH_KEY ^= w_king_rand[to] ^ w_king_rand[from];
288 SetClear( BB_W_HDK ); break;
289 case pro_pawn: NocapNoproW( PRO_PAWN, pro_pawn);
290 SetClear( BB_WTGOLD ); break;
291 case pro_lance: NocapNoproW( PRO_LANCE, pro_lance);
292 SetClear( BB_WTGOLD ); break;
293 case pro_knight: NocapNoproW( PRO_KNIGHT, pro_knight);
294 SetClear( BB_WTGOLD ); break;
295 case pro_silver: NocapNoproW( PRO_SILVER, pro_silver);
296 SetClear( BB_WTGOLD ); break;
297 case horse: NocapNoproW( HORSE, horse );
298 SetClear( BB_W_HDK );
299 SetClear( BB_W_BH ); break;
300 default: NocapNoproW( DRAGON, dragon );
301 SetClear( BB_W_HDK );
302 SetClear( BB_W_RD ); break;
309 case pawn: CapB( PAWN, pawn, pawn );
310 Xor( to-nfile, BB_BPAWN_ATK ); break;
311 case lance: CapB( LANCE, lance, lance ); break;
312 case knight: CapB( KNIGHT, knight, knight ); break;
313 case silver: CapB( SILVER, silver, silver ); break;
314 case gold: CapB( GOLD, gold, gold );
315 Xor( to, BB_BTGOLD ); break;
316 case bishop: CapB( BISHOP, bishop, bishop );
317 Xor( to, BB_B_BH ); break;
318 case rook: CapB( ROOK, rook, rook );
319 Xor( to, BB_B_RD ); break;
320 case pro_pawn: CapB( PRO_PAWN, pawn, pro_pawn );
321 Xor( to, BB_BTGOLD ); break;
322 case pro_lance: CapB( PRO_LANCE, lance, pro_lance );
323 Xor( to, BB_BTGOLD ); break;
324 case pro_knight: CapB( PRO_KNIGHT, knight, pro_knight );
325 Xor( to, BB_BTGOLD ); break;
326 case pro_silver: CapB( PRO_SILVER, silver, pro_silver );
327 Xor( to, BB_BTGOLD ); break;
328 case horse: CapB( HORSE, bishop, horse );
330 Xor( to, BB_B_BH ); break;
331 default: CapB( DRAGON, rook, dragon );
333 Xor( to, BB_B_RD ); break;
335 Xor( to, BB_BOCCUPY );
336 XorFile( from, OCCUPIED_FILE );
337 XorDiag1( from, OCCUPIED_DIAG1 );
338 XorDiag2( from, OCCUPIED_DIAG2 );
341 SetClearFile( from, to, OCCUPIED_FILE );
342 SetClearDiag1( from, to, OCCUPIED_DIAG1 );
343 SetClearDiag2( from, to, OCCUPIED_DIAG2 );
347 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 MakeMove( root_turn, move, 1 );
373 /* detect hang-king */
374 if ( ( flag & flag_detect_hang ) && InCheck(root_turn) )
376 str_error = str_king_hang;
377 UnMakeMove( root_turn, move, 1 );
382 check = InCheck( Flip(root_turn) );
383 ptree->move_last[1] = ptree->move_last[0];
386 ptree->nsuc_check[2] = (unsigned char)( ptree->nsuc_check[0] + 1U );
388 else { ptree->nsuc_check[2] = 0; }
390 /* detect repetitions */
391 if ( flag & flag_rep )
393 switch ( detect_repetition( ptree, 2, Flip(root_turn), 3 ) )
395 case perpetual_check:
396 str_error = str_perpet_check;
397 UnMakeMove( root_turn, move, 1 );
406 /* return, since all of rule-checks were done */
407 if ( flag & flag_nomake_move )
409 UnMakeMove( root_turn, move, 1 );
410 return drawn ? 2 : 1;
413 if ( drawn ) { game_status |= flag_drawn; }
416 if ( flag & flag_time )
418 iret = update_time( root_turn );
419 if ( iret < 0 ) { return -1; }
422 root_turn = Flip( root_turn );
423 move_list[move_ptr++] = move; // [HGM] undo: remember all moves played in root
425 /* detect checkmate */
426 if ( check && is_mate( ptree, 1 ) ) { game_status |= flag_mated; }
429 if ( flag & flag_history ) { out_CSA( ptree, &record_game, move ); }
431 /* renew repetition table */
433 if ( n >= REP_HIST_LEN - PLY_MAX -1 )
435 for ( i = 0; i < n; i++ )
437 ptree->rep_board_list[i] = ptree->rep_board_list[i+1];
438 ptree->rep_hand_list[i] = ptree->rep_hand_list[i+1];
441 else { ptree->nrep++; }
443 for ( i = 1; i < NUM_UNMAKE; i += 1 )
445 amove_save[i-1] = amove_save[i];
446 amaterial_save[i-1] = amaterial_save[i];
447 ansuc_check_save[i-1] = ansuc_check_save[i];
448 alast_root_value_save[i-1] = alast_root_value_save[i];
449 alast_pv_save[i-1] = alast_pv_save[i];
451 amove_save [NUM_UNMAKE-1] = move;
452 amaterial_save [NUM_UNMAKE-1] = ptree->save_material[1];
453 ansuc_check_save[NUM_UNMAKE-1] = ptree->nsuc_check[0];
454 ptree->nsuc_check[0] = ptree->nsuc_check[1];
455 ptree->nsuc_check[1] = ptree->nsuc_check[2];
458 alast_root_value_save[NUM_UNMAKE-1] = last_root_value;
459 alast_pv_save[NUM_UNMAKE-1] = last_pv;
461 if ( last_pv.a[1] == move && last_pv.length >= 2 )
465 #if PLY_INC == EXT_CHECK
471 memmove( &(last_pv.a[1]), &(last_pv.a[2]),
472 last_pv.length * sizeof( unsigned int ) );
482 #if defined(DFPN_CLIENT)
483 lock( &dfpn_client_lock );
484 snprintf( (char *)dfpn_client_signature, DFPN_CLIENT_SIZE_SIGNATURE,
485 "%" PRIx64 "_%x_%x_%x", HASH_KEY, HAND_B, HAND_W, root_turn );
486 dfpn_client_signature[DFPN_CLIENT_SIZE_SIGNATURE-1] = '\0';
487 dfpn_client_rresult = dfpn_client_na;
488 dfpn_client_num_cresult = 0;
489 dfpn_client_flag_read = 0;
490 dfpn_client_out( "%s %s\n", str_CSA_move(move), dfpn_client_signature );
491 unlock( &dfpn_client_lock );
498 int CONV unmake_move_root( tree_t * restrict ptree )
503 if ( ptree->nrep == 0 || amove_save[NUM_UNMAKE-1] == MOVE_NA )
505 str_error = "no more undo infomation at root";
509 ptree->nsuc_check[1] = ptree->nsuc_check[0];
510 ptree->nsuc_check[0] = ansuc_check_save[NUM_UNMAKE-1];
511 ptree->save_material[1] = (short)amaterial_save[NUM_UNMAKE-1];
512 move = amove_save[NUM_UNMAKE-1];
513 last_root_value = alast_root_value_save[NUM_UNMAKE-1];
514 last_pv = alast_pv_save[NUM_UNMAKE-1];
517 game_status &= ~( flag_drawn | flag_mated );
518 root_turn = Flip(root_turn);
519 move_ptr--; // [HGM] undo: clip last move off game history
521 for ( i = NUM_UNMAKE-1; i > 0; i -= 1 )
523 amove_save[i] = amove_save[i-1];
524 amaterial_save[i] = amaterial_save[i-1];
525 ansuc_check_save[i] = ansuc_check_save[i-1];
526 alast_root_value_save[i] = alast_root_value_save[i-1];
527 alast_pv_save[i] = alast_pv_save[i-1];
529 amove_save[0] = MOVE_NA;
530 amaterial_save[0] = 0;
531 ansuc_check_save[0] = 0;
532 alast_root_value_save[0] = 0;
533 alast_pv_save[0].a[0] = 0;
534 alast_pv_save[0].a[1] = 0;
535 alast_pv_save[0].depth = 0;
536 alast_pv_save[0].length = 0;
538 UnMakeMove( root_turn, move, 1 );
540 #if defined(DFPN_CLIENT)
541 lock( &dfpn_client_lock );
542 snprintf( (char *)dfpn_client_signature, DFPN_CLIENT_SIZE_SIGNATURE,
543 "%" PRIx64 "_%x_%x_%x", HASH_KEY, HAND_B, HAND_W, root_turn );
544 dfpn_client_signature[DFPN_CLIENT_SIZE_SIGNATURE-1] = '\0';
545 dfpn_client_rresult = dfpn_client_na;
546 dfpn_client_flag_read = 0;
547 dfpn_client_num_cresult = 0;
548 dfpn_client_out( "unmake\n" );
549 unlock( &dfpn_client_lock );