5 #define DebugOut { static int count = 0; \
6 if ( count++ < 16 ) { out_CSA_posi( ptree, stdout, 0 ); } }
8 static int can_w_king_escape( tree_t * restrict ptree, int to, bitboard_t bb );
9 static int can_b_king_escape( tree_t * restrict ptree, int to, bitboard_t bb );
10 static int can_w_piece_capture( const tree_t * restrict ptree, int to );
11 static int can_b_piece_capture( const tree_t * restrict ptree, int to );
15 is_b_mate_in_1ply( tree_t * restrict ptree )
17 bitboard_t bb, bb_temp, bb_check, bb_check_pro, bb_attacks, bb_drop, bb_move;
21 assert( ! is_black_attacked( ptree, SQ_BKING ) );
24 BBOr( bb_drop, BB_BOCCUPY, BB_WOCCUPY );
25 BBNot( bb_drop, bb_drop );
27 if ( IsHandRook(HAND_B) ) {
29 BBAnd( bb, abb_w_gold_attacks[SQ_WKING],
30 abb_b_gold_attacks[SQ_WKING] );
31 BBAnd( bb, bb, bb_drop );
37 if ( ! is_white_attacked( ptree, to ) ) { continue; }
39 bb_attacks = abb_file_attacks[to][0];
40 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
41 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
42 if ( can_w_piece_capture( ptree, to ) ) { continue; }
43 return To2Move(to) | Drop2Move(rook);
46 } else if ( IsHandLance(HAND_B) && SQ_WKING <= I2 ) {
49 if ( ! BOARD[to] && is_white_attacked( ptree, to ) )
51 bb_attacks = abb_file_attacks[to][0];
52 if ( ! can_w_king_escape( ptree, to, bb_attacks )
53 && ! can_w_piece_capture( ptree, to ) )
55 return To2Move(to) | Drop2Move(lance);
60 if ( IsHandBishop(HAND_B) ) {
62 BBAnd( bb, abb_w_silver_attacks[SQ_WKING],
63 abb_b_silver_attacks[SQ_WKING] );
64 BBAnd( bb, bb, bb_drop );
70 if ( ! is_white_attacked( ptree, to ) ) { continue; }
72 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
73 abb_bishop_attacks_rl45[to][0] );
74 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
75 if ( can_w_piece_capture( ptree, to ) ) { continue; }
76 return To2Move(to) | Drop2Move(bishop);
80 if ( IsHandGold(HAND_B) ) {
82 if ( IsHandRook(HAND_B) )
84 BBAnd( bb, abb_b_gold_attacks[SQ_WKING],
85 abb_b_silver_attacks[SQ_WKING] );
87 BBAnd( bb, bb, bb_drop );
88 BBAnd( bb, bb, abb_w_gold_attacks[SQ_WKING] );
90 else { BBAnd( bb, bb_drop, abb_w_gold_attacks[SQ_WKING] ); }
97 if ( ! is_white_attacked( ptree, to ) ) { continue; }
99 bb_attacks = abb_b_gold_attacks[to];
100 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
101 if ( can_w_piece_capture( ptree, to ) ) { continue; }
102 return To2Move(to) | Drop2Move(gold);
106 if ( IsHandSilver(HAND_B) ) {
108 if ( IsHandGold(HAND_B) )
110 if ( IsHandBishop(HAND_B) ) { goto b_silver_drop_end; }
111 BBNot( bb, abb_w_gold_attacks[SQ_WKING] );
112 BBAnd( bb, bb, abb_w_silver_attacks[SQ_WKING] );
113 BBAnd( bb, bb, bb_drop );
116 BBAnd( bb, bb_drop, abb_w_silver_attacks[SQ_WKING] );
117 if ( IsHandBishop(HAND_B) )
119 BBAnd( bb, bb, abb_w_gold_attacks[SQ_WKING] );
128 if ( ! is_white_attacked( ptree, to ) ) { continue; }
130 bb_attacks = abb_b_silver_attacks[to];
131 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
132 if ( can_w_piece_capture( ptree, to ) ) { continue; }
133 return To2Move(to) | Drop2Move(silver);
138 if ( IsHandKnight(HAND_B) ) {
140 BBAnd( bb, bb_drop, abb_w_knight_attacks[SQ_WKING] );
147 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
148 if ( can_w_piece_capture( ptree, to ) ) { continue; }
149 return To2Move(to) | Drop2Move(knight);
154 BBNot( bb_move, BB_BOCCUPY );
157 while ( BBToU(bb) ) {
158 from = FirstOne( bb );
161 AttackDragon( bb_attacks, from );
162 BBAnd( bb_check, bb_move, bb_attacks );
163 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
164 if ( ! BBToU(bb_check) ) { continue; }
166 Xor( from, BB_B_HDK );
167 Xor( from, BB_B_RD );
168 Xor( from, BB_BOCCUPY );
169 XorFile( from, OCCUPIED_FILE );
170 XorDiag2( from, OCCUPIED_DIAG2 );
171 XorDiag1( from, OCCUPIED_DIAG1 );
174 to = FirstOne( bb_check );
177 if ( ! is_white_attacked( ptree, to ) ) { continue; }
179 if ( (int)adirec[SQ_WKING][to] & flag_cross )
181 bb_attacks = abb_file_attacks[to][0];
182 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
183 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
185 else { AttackDragon( bb_attacks, to ); }
187 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
188 if ( IsDiscoverWK( from, to ) );
189 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
190 if ( IsDiscoverBK( from, to ) ) { continue; }
192 XorFile( from, OCCUPIED_FILE );
193 XorDiag2( from, OCCUPIED_DIAG2 );
194 XorDiag1( from, OCCUPIED_DIAG1 );
195 Xor( from, BB_BOCCUPY );
196 Xor( from, BB_B_RD );
197 Xor( from, BB_B_HDK );
198 return ( To2Move(to) | From2Move(from)
199 | Cap2Move(-BOARD[to]) | Piece2Move(dragon) );
200 } while ( BBToU(bb_check) );
202 XorFile( from, OCCUPIED_FILE );
203 XorDiag2( from, OCCUPIED_DIAG2 );
204 XorDiag1( from, OCCUPIED_DIAG1 );
205 Xor( from, BB_BOCCUPY );
206 Xor( from, BB_B_RD );
207 Xor( from, BB_B_HDK );
210 bb.p[0] = BB_BROOK.p[0];
212 from = last_one0( bb.p[0] );
213 bb.p[0] ^= abb_mask[from].p[0];
215 AttackRook( bb_attacks, from );
216 BBAnd( bb_check, bb_move, bb_attacks );
217 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
218 if ( ! BBToU(bb_check) ) { continue; }
220 BB_B_RD.p[0] ^= abb_mask[from].p[0];
221 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
222 XorFile( from, OCCUPIED_FILE );
223 XorDiag2( from, OCCUPIED_DIAG2 );
224 XorDiag1( from, OCCUPIED_DIAG1 );
227 to = FirstOne( bb_check );
230 if ( ! is_white_attacked( ptree, to ) ) { continue; }
232 if ( (int)adirec[SQ_WKING][to] & flag_cross )
234 bb_attacks = abb_file_attacks[to][0];
235 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
236 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
238 else { AttackDragon( bb_attacks, to ); }
240 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
241 if ( IsDiscoverWK( from, to ) );
242 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
243 if ( IsDiscoverBK( from, to ) ) { continue; }
245 XorFile( from, OCCUPIED_FILE );
246 XorDiag2( from, OCCUPIED_DIAG2 );
247 XorDiag1( from, OCCUPIED_DIAG1 );
248 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
249 BB_B_RD.p[0] ^= abb_mask[from].p[0];
250 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
251 | Cap2Move(-BOARD[to]) | Piece2Move(rook) );
252 } while ( BBToU(bb_check) );
254 XorFile( from, OCCUPIED_FILE );
255 XorDiag2( from, OCCUPIED_DIAG2 );
256 XorDiag1( from, OCCUPIED_DIAG1 );
257 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
258 BB_B_RD.p[0] ^= abb_mask[from].p[0];
261 bb.p[1] = BB_BROOK.p[1];
262 bb.p[2] = BB_BROOK.p[2];
263 while ( bb.p[1] | bb.p[2] ) {
264 from = first_one12( bb.p[1], bb.p[2] );
265 bb.p[1] ^= abb_mask[from].p[1];
266 bb.p[2] ^= abb_mask[from].p[2];
268 AttackRook( bb_attacks, from );
269 BBAnd( bb_check, bb_move, bb_attacks );
270 bb_check.p[0] &= abb_king_attacks[SQ_WKING].p[0];
271 bb_check.p[1] &= abb_b_gold_attacks[SQ_WKING].p[1];
272 bb_check.p[2] &= abb_b_gold_attacks[SQ_WKING].p[2];
273 bb_check.p[1] &= abb_w_gold_attacks[SQ_WKING].p[1];
274 bb_check.p[2] &= abb_w_gold_attacks[SQ_WKING].p[2];
275 if ( ! BBToU(bb_check) ) { continue; }
277 BB_B_RD.p[1] ^= abb_mask[from].p[1];
278 BB_B_RD.p[2] ^= abb_mask[from].p[2];
279 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
280 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
281 XorFile( from, OCCUPIED_FILE );
282 XorDiag2( from, OCCUPIED_DIAG2 );
283 XorDiag1( from, OCCUPIED_DIAG1 );
286 to = FirstOne( bb_check );
289 if ( ! is_white_attacked( ptree, to ) ) { continue; }
292 if ( (int)adirec[SQ_WKING][to] & flag_cross )
294 bb_attacks = abb_file_attacks[to][0];
295 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
296 bb_attacks.p[0] |= abb_king_attacks[to].p[0];
297 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
299 else { AttackDragon( bb_attacks, to ); }
302 bb_attacks = abb_file_attacks[to][0];
303 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
305 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
306 if ( IsDiscoverWK( from, to ) );
307 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
308 if ( IsDiscoverBK( from, to ) ) { continue; }
310 XorFile( from, OCCUPIED_FILE );
311 XorDiag2( from, OCCUPIED_DIAG2 );
312 XorDiag1( from, OCCUPIED_DIAG1 );
313 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
314 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
315 BB_B_RD.p[1] ^= abb_mask[from].p[1];
316 BB_B_RD.p[2] ^= abb_mask[from].p[2];
317 return ( To2Move(to) | From2Move(from)
318 | ( (to < A6) ? FLAG_PROMO : 0 )
319 | Cap2Move(-BOARD[to]) | Piece2Move(rook) );
320 } while ( BBToU(bb_check) );
322 XorFile( from, OCCUPIED_FILE );
323 XorDiag2( from, OCCUPIED_DIAG2 );
324 XorDiag1( from, OCCUPIED_DIAG1 );
325 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
326 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
327 BB_B_RD.p[1] ^= abb_mask[from].p[1];
328 BB_B_RD.p[2] ^= abb_mask[from].p[2];
332 while ( BBToU(bb) ) {
333 from = FirstOne( bb );
336 AttackHorse( bb_attacks, from );
337 BBAnd( bb_check, bb_move, bb_attacks );
338 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
339 if ( ! BBToU(bb_check) ) { continue; }
341 Xor( from, BB_B_HDK );
342 Xor( from, BB_B_BH );
343 Xor( from, BB_BOCCUPY );
344 XorFile( from, OCCUPIED_FILE );
345 XorDiag2( from, OCCUPIED_DIAG2 );
346 XorDiag1( from, OCCUPIED_DIAG1 );
349 to = FirstOne( bb_check );
352 if ( ! is_white_attacked( ptree, to ) ) { continue; }
354 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
355 abb_bishop_attacks_rl45[to][0] );
356 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
357 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
358 if ( IsDiscoverWK( from, to ) );
359 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
360 if ( IsDiscoverBK( from, to ) ) { continue; }
362 XorFile( from, OCCUPIED_FILE );
363 XorDiag2( from, OCCUPIED_DIAG2 );
364 XorDiag1( from, OCCUPIED_DIAG1 );
365 Xor( from, BB_BOCCUPY );
366 Xor( from, BB_B_BH );
367 Xor( from, BB_B_HDK );
368 return ( To2Move(to) | From2Move(from)
369 | Cap2Move(-BOARD[to]) | Piece2Move(horse) );
370 } while ( BBToU(bb_check) );
372 XorFile( from, OCCUPIED_FILE );
373 XorDiag2( from, OCCUPIED_DIAG2 );
374 XorDiag1( from, OCCUPIED_DIAG1 );
375 Xor( from, BB_BOCCUPY );
376 Xor( from, BB_B_BH );
377 Xor( from, BB_B_HDK );
380 bb.p[0] = BB_BBISHOP.p[0];
382 from = last_one0( bb.p[0] );
383 bb.p[0] ^= abb_mask[from].p[0];
385 AttackBishop( bb_attacks, from );
386 BBAnd( bb_check, bb_move, bb_attacks );
387 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
388 if ( ! BBToU(bb_check) ) { continue; }
390 BB_B_BH.p[0] ^= abb_mask[from].p[0];
391 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
392 XorFile( from, OCCUPIED_FILE );
393 XorDiag2( from, OCCUPIED_DIAG2 );
394 XorDiag1( from, OCCUPIED_DIAG1 );
397 to = FirstOne( bb_check );
400 if ( ! is_white_attacked( ptree, to ) ) { continue; }
402 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
403 abb_bishop_attacks_rl45[to][0] );
404 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
405 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
406 if ( IsDiscoverWK( from, to ) );
407 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
408 if ( IsDiscoverBK( from, to ) ) { continue; }
410 XorFile( from, OCCUPIED_FILE );
411 XorDiag2( from, OCCUPIED_DIAG2 );
412 XorDiag1( from, OCCUPIED_DIAG1 );
413 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
414 BB_B_BH.p[0] ^= abb_mask[from].p[0];
415 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
416 | Cap2Move(-BOARD[to]) | Piece2Move(bishop) );
417 } while ( BBToU(bb_check) );
419 XorFile( from, OCCUPIED_FILE );
420 XorDiag2( from, OCCUPIED_DIAG2 );
421 XorDiag1( from, OCCUPIED_DIAG1 );
422 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
423 BB_B_BH.p[0] ^= abb_mask[from].p[0];
426 bb.p[1] = BB_BBISHOP.p[1];
427 bb.p[2] = BB_BBISHOP.p[2];
428 while ( bb.p[1] | bb.p[2] ) {
429 from = first_one12( bb.p[1], bb.p[2] );
430 bb.p[1] ^= abb_mask[from].p[1];
431 bb.p[2] ^= abb_mask[from].p[2];
433 AttackBishop( bb_attacks, from );
434 BBAnd( bb_check, bb_move, bb_attacks );
435 bb_check.p[0] &= abb_king_attacks[SQ_WKING].p[0];
436 bb_check.p[1] &= abb_b_silver_attacks[SQ_WKING].p[1];
437 bb_check.p[2] &= abb_b_silver_attacks[SQ_WKING].p[2];
438 bb_check.p[1] &= abb_w_silver_attacks[SQ_WKING].p[1];
439 bb_check.p[2] &= abb_w_silver_attacks[SQ_WKING].p[2];
440 if ( ! BBToU(bb_check) ) { continue; }
442 BB_B_BH.p[1] ^= abb_mask[from].p[1];
443 BB_B_BH.p[2] ^= abb_mask[from].p[2];
444 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
445 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
446 XorFile( from, OCCUPIED_FILE );
447 XorDiag2( from, OCCUPIED_DIAG2 );
448 XorDiag1( from, OCCUPIED_DIAG1 );
451 to = FirstOne( bb_check );
454 if ( ! is_white_attacked( ptree, to ) ) { continue; }
456 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
457 abb_bishop_attacks_rl45[to][0] );
459 bb_attacks.p[0] |= abb_king_attacks[to].p[0];
460 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
462 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
463 if ( IsDiscoverWK( from, to ) );
464 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
465 if ( IsDiscoverBK( from, to ) ) { continue; }
467 XorFile( from, OCCUPIED_FILE );
468 XorDiag2( from, OCCUPIED_DIAG2 );
469 XorDiag1( from, OCCUPIED_DIAG1 );
470 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
471 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
472 BB_B_BH.p[1] ^= abb_mask[from].p[1];
473 BB_B_BH.p[2] ^= abb_mask[from].p[2];
474 return ( To2Move(to) | From2Move(from)
475 | ( (to < A6) ? FLAG_PROMO : 0 )
476 | Cap2Move(-BOARD[to]) | Piece2Move(bishop) );
477 } while ( BBToU(bb_check) );
479 XorFile( from, OCCUPIED_FILE );
480 XorDiag2( from, OCCUPIED_DIAG2 );
481 XorDiag1( from, OCCUPIED_DIAG1 );
482 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
483 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
484 BB_B_BH.p[1] ^= abb_mask[from].p[1];
485 BB_B_BH.p[2] ^= abb_mask[from].p[2];
488 BBAnd( bb, BB_BTGOLD, b_chk_tbl[SQ_WKING].gold );
489 while ( BBToU(bb) ) {
490 from = FirstOne( bb );
493 BBAnd( bb_check, bb_move, abb_b_gold_attacks[from] );
494 BBAnd( bb_check, bb_check, abb_w_gold_attacks[SQ_WKING] );
495 if ( ! BBToU(bb_check) ) { continue; }
497 Xor( from, BB_BTGOLD );
498 Xor( from, BB_BOCCUPY );
499 XorFile( from, OCCUPIED_FILE );
500 XorDiag2( from, OCCUPIED_DIAG2 );
501 XorDiag1( from, OCCUPIED_DIAG1 );
504 to = FirstOne( bb_check );
507 if ( ! is_white_attacked( ptree, to ) ) { continue; }
509 bb_attacks = abb_b_gold_attacks[to];
510 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
511 if ( IsDiscoverWK( from, to ) );
512 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
513 if ( IsDiscoverBK( from, to ) ) { continue; }
515 XorFile( from, OCCUPIED_FILE );
516 XorDiag2( from, OCCUPIED_DIAG2 );
517 XorDiag1( from, OCCUPIED_DIAG1 );
518 Xor( from, BB_BOCCUPY );
519 Xor( from, BB_BTGOLD );
520 return ( To2Move(to) | From2Move(from)
521 | Cap2Move(-BOARD[to]) | Piece2Move(BOARD[from]) );
522 } while ( BBToU(bb_check) );
524 XorFile( from, OCCUPIED_FILE );
525 XorDiag2( from, OCCUPIED_DIAG2 );
526 XorDiag1( from, OCCUPIED_DIAG1 );
527 Xor( from, BB_BOCCUPY );
528 Xor( from, BB_BTGOLD );
531 BBAnd( bb, BB_BSILVER, b_chk_tbl[SQ_WKING].silver );
533 from = last_one0( bb.p[0] );
534 bb.p[0] ^= abb_mask[from].p[0];
536 bb_check_pro.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
537 & abb_w_gold_attacks[SQ_WKING].p[0];
538 bb_check_pro.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
539 & abb_w_gold_attacks[SQ_WKING].p[1];
541 bb_check.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
542 & abb_w_silver_attacks[SQ_WKING].p[0]
543 & ~abb_w_gold_attacks[SQ_WKING].p[0];
544 bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
545 & abb_w_silver_attacks[SQ_WKING].p[1]
546 & ~abb_w_gold_attacks[SQ_WKING].p[1];
548 if ( ! ( bb_check_pro.p[0] | bb_check_pro.p[1]
549 | bb_check.p[0]| bb_check.p[1] ) ) { continue; }
551 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
552 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
553 XorFile( from, OCCUPIED_FILE );
554 XorDiag2( from, OCCUPIED_DIAG2 );
555 XorDiag1( from, OCCUPIED_DIAG1 );
557 while ( bb_check_pro.p[0] | bb_check_pro.p[1] ) {
558 to = first_one01( bb_check_pro.p[0], bb_check_pro.p[1] );
559 bb_check_pro.p[0] ^= abb_mask[to].p[0];
560 bb_check_pro.p[1] ^= abb_mask[to].p[1];
562 if ( ! is_white_attacked( ptree, to ) ) { continue; }
564 bb_attacks = abb_b_gold_attacks[to];
565 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
566 if ( IsDiscoverWK( from, to ) );
567 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
568 if ( IsDiscoverBK( from, to ) ) { continue; }
570 XorFile( from, OCCUPIED_FILE );
571 XorDiag2( from, OCCUPIED_DIAG2 );
572 XorDiag1( from, OCCUPIED_DIAG1 );
573 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
574 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
575 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
576 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
579 while ( bb_check.p[0] | bb_check.p[1] ) {
580 to = first_one01( bb_check.p[0], bb_check.p[1] );
581 bb_check.p[0] ^= abb_mask[to].p[0];
582 bb_check.p[1] ^= abb_mask[to].p[1];
584 if ( ! is_white_attacked( ptree, to ) ) { continue; }
586 bb_attacks = abb_b_silver_attacks[to];
587 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
588 if ( IsDiscoverWK( from, to ) );
589 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
590 if ( IsDiscoverBK( from, to ) ) { continue; }
592 XorFile( from, OCCUPIED_FILE );
593 XorDiag2( from, OCCUPIED_DIAG2 );
594 XorDiag1( from, OCCUPIED_DIAG1 );
595 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
596 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
597 return ( To2Move(to) | From2Move(from)
598 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
601 XorFile( from, OCCUPIED_FILE );
602 XorDiag2( from, OCCUPIED_DIAG2 );
603 XorDiag1( from, OCCUPIED_DIAG1 );
604 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
605 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
608 ubb = bb.p[1] & 0x7fc0000U;
610 from = last_one1( ubb );
611 ubb ^= abb_mask[from].p[1];
613 bb_check_pro.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
614 & abb_w_gold_attacks[SQ_WKING].p[0];
616 bb_check.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
617 & abb_w_silver_attacks[SQ_WKING].p[0]
618 & ~abb_w_gold_attacks[SQ_WKING].p[0];
619 bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
620 & abb_w_silver_attacks[SQ_WKING].p[1];
622 if ( ! (bb_check_pro.p[0]|bb_check.p[0]|bb_check.p[1]) ) { continue; }
624 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
625 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
626 XorFile( from, OCCUPIED_FILE );
627 XorDiag2( from, OCCUPIED_DIAG2 );
628 XorDiag1( from, OCCUPIED_DIAG1 );
630 while ( bb_check_pro.p[0] ) {
631 to = last_one0( bb_check_pro.p[0] );
632 bb_check_pro.p[0] ^= abb_mask[to].p[0];
634 if ( ! is_white_attacked( ptree, to ) ) { continue; }
636 bb_attacks = abb_b_gold_attacks[to];
637 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
638 if ( IsDiscoverWK( from, to ) );
639 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
640 if ( IsDiscoverBK( from, to ) ) { continue; }
642 XorFile( from, OCCUPIED_FILE );
643 XorDiag2( from, OCCUPIED_DIAG2 );
644 XorDiag1( from, OCCUPIED_DIAG1 );
645 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
646 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
647 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
648 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
651 while ( bb_check.p[0] | bb_check.p[1] ) {
652 to = first_one01( bb_check.p[0], bb_check.p[1] );
653 bb_check.p[0] ^= abb_mask[to].p[0];
654 bb_check.p[1] ^= abb_mask[to].p[1];
656 if ( ! is_white_attacked( ptree, to ) ) { continue; }
658 bb_attacks = abb_b_silver_attacks[to];
659 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
660 if ( IsDiscoverWK( from, to ) );
661 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
662 if ( IsDiscoverBK( from, to ) ) { continue; }
664 XorFile( from, OCCUPIED_FILE );
665 XorDiag2( from, OCCUPIED_DIAG2 );
666 XorDiag1( from, OCCUPIED_DIAG1 );
667 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
668 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
669 return ( To2Move(to) | From2Move(from)
670 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
673 XorFile( from, OCCUPIED_FILE );
674 XorDiag2( from, OCCUPIED_DIAG2 );
675 XorDiag1( from, OCCUPIED_DIAG1 );
676 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
677 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
680 bb.p[1] &= 0x003ffffU;
681 while ( bb.p[1] | bb.p[2] ) {
682 from = first_one12( bb.p[1], bb.p[2] );
683 bb.p[1] ^= abb_mask[from].p[1];
684 bb.p[2] ^= abb_mask[from].p[2];
686 bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
687 & abb_w_silver_attacks[SQ_WKING].p[1];
688 bb_check.p[2] = bb_move.p[2] & abb_b_silver_attacks[from].p[2]
689 & abb_w_silver_attacks[SQ_WKING].p[2];
690 if ( ! ( bb_check.p[1] | bb_check.p[2] ) ) { continue; }
692 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
693 BB_BSILVER.p[2] ^= abb_mask[from].p[2];
694 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
695 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
696 XorFile( from, OCCUPIED_FILE );
697 XorDiag2( from, OCCUPIED_DIAG2 );
698 XorDiag1( from, OCCUPIED_DIAG1 );
701 to = first_one12( bb_check.p[1], bb_check.p[2] );
702 bb_check.p[1] ^= abb_mask[to].p[1];
703 bb_check.p[2] ^= abb_mask[to].p[2];
705 if ( ! is_white_attacked( ptree, to ) ) { continue; }
707 bb_attacks = abb_b_silver_attacks[to];
708 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
709 if ( IsDiscoverWK( from, to ) );
710 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
711 if ( IsDiscoverBK( from, to ) ) { continue; }
713 XorFile( from, OCCUPIED_FILE );
714 XorDiag2( from, OCCUPIED_DIAG2 );
715 XorDiag1( from, OCCUPIED_DIAG1 );
716 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
717 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
718 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
719 BB_BSILVER.p[2] ^= abb_mask[from].p[2];
720 return ( To2Move(to) | From2Move(from)
721 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
722 } while ( bb_check.p[1] | bb_check.p[2] );
724 XorFile( from, OCCUPIED_FILE );
725 XorDiag2( from, OCCUPIED_DIAG2 );
726 XorDiag1( from, OCCUPIED_DIAG1 );
727 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
728 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
729 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
730 BB_BSILVER.p[2] ^= abb_mask[from].p[2];
733 BBAnd( bb, BB_BKNIGHT, b_chk_tbl[SQ_WKING].knight );
734 while ( BBToU(bb) ) {
735 from = FirstOne( bb );
738 bb_check.p[0] = bb_move.p[0] & abb_b_knight_attacks[from].p[0]
739 & abb_w_gold_attacks[SQ_WKING].p[0];
741 if ( bb_check.p[0] ) {
742 BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
743 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
744 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
745 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
746 XorFile( from, OCCUPIED_FILE );
747 XorDiag2( from, OCCUPIED_DIAG2 );
748 XorDiag1( from, OCCUPIED_DIAG1 );
751 to = last_one0( bb_check.p[0] );
752 bb_check.p[0] ^= abb_mask[to].p[0];
754 if ( ! is_white_attacked( ptree, to ) ) { continue; }
756 bb_attacks = abb_b_gold_attacks[to];
757 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
758 if ( IsDiscoverWK( from, to ) );
759 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
760 if ( IsDiscoverBK( from, to ) ) { continue; }
762 XorFile( from, OCCUPIED_FILE );
763 XorDiag2( from, OCCUPIED_DIAG2 );
764 XorDiag1( from, OCCUPIED_DIAG1 );
765 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
766 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
767 BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
768 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
769 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
770 | Cap2Move(-BOARD[to]) | Piece2Move(knight) );
771 } while ( bb_check.p[0] );
773 XorFile( from, OCCUPIED_FILE );
774 XorDiag2( from, OCCUPIED_DIAG2 );
775 XorDiag1( from, OCCUPIED_DIAG1 );
776 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
777 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
778 BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
779 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
782 BBAnd( bb_check, bb_move, abb_b_knight_attacks[from] );
783 BBAnd( bb_check, bb_check, abb_w_knight_attacks[SQ_WKING] );
785 if ( BBToU(bb_check) ) {
786 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
787 BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
788 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
789 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
790 XorFile( from, OCCUPIED_FILE );
791 XorDiag2( from, OCCUPIED_DIAG2 );
792 XorDiag1( from, OCCUPIED_DIAG1 );
795 to = FirstOne( bb_check );
799 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
800 if ( IsDiscoverWK( from, to ) );
801 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
802 if ( IsDiscoverBK( from, to ) ) { continue; }
804 XorFile( from, OCCUPIED_FILE );
805 XorDiag2( from, OCCUPIED_DIAG2 );
806 XorDiag1( from, OCCUPIED_DIAG1 );
807 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
808 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
809 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
810 BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
811 return ( To2Move(to) | From2Move(from)
812 | Cap2Move(-BOARD[to]) | Piece2Move(knight) );
813 } while ( BBToU(bb_check) );
815 XorFile( from, OCCUPIED_FILE );
816 XorDiag2( from, OCCUPIED_DIAG2 );
817 XorDiag1( from, OCCUPIED_DIAG1 );
818 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
819 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
820 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
821 BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
826 BBAnd( bb, BB_BLANCE, b_chk_tbl[SQ_WKING].lance );
827 while ( BBToU(bb) ) {
828 from = FirstOne( bb );
831 bb_attacks = AttackFile(from);
832 BBAnd( bb_attacks, bb_attacks, abb_minus_rays[from] );
833 BBAnd( bb_attacks, bb_attacks, bb_move );
835 BBAnd( bb_check, bb_attacks, abb_mask[SQ_WKING+nfile] );
836 bb_check_pro.p[0] = bb_attacks.p[0] & abb_w_gold_attacks[SQ_WKING].p[0];
838 if ( ! ( bb_check_pro.p[0] | bb_check.p[0]
839 | bb_check.p[1] | bb_check.p[2] ) ) { continue; }
841 Xor( from, BB_BLANCE );
842 Xor( from, BB_BOCCUPY );
843 XorFile( from, OCCUPIED_FILE );
844 XorDiag2( from, OCCUPIED_DIAG2 );
845 XorDiag1( from, OCCUPIED_DIAG1 );
847 bb_check.p[0] &= 0x1ffU;
848 if ( BBToU(bb_check) ) {
851 if ( ! is_white_attacked( ptree, to ) ) {
852 bb_check.p[0] &= ~abb_mask[to].p[0];
855 bb_temp = abb_file_attacks[to][0];
856 if ( can_w_king_escape( ptree, to, bb_temp ) ) { goto b_lance_next; }
857 if ( IsDiscoverWK( from, to ) );
858 else if ( can_w_piece_capture( ptree, to ) ) { goto b_lance_next; }
859 if ( IsDiscoverBK( from, to ) ) { goto b_lance_next; }
861 XorFile( from, OCCUPIED_FILE );
862 XorDiag2( from, OCCUPIED_DIAG2 );
863 XorDiag1( from, OCCUPIED_DIAG1 );
864 Xor( from, BB_BOCCUPY );
865 Xor( from, BB_BLANCE );
866 return ( To2Move(to) | From2Move(from)
867 | Cap2Move(-BOARD[to]) | Piece2Move(lance) );
871 while ( bb_check_pro.p[0] )
873 to = last_one0( bb_check_pro.p[0] );
874 bb_check_pro.p[0] ^= abb_mask[to].p[0];
876 if ( ! is_white_attacked( ptree, to ) ) { continue; }
878 bb_attacks = abb_b_gold_attacks[to];
879 if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
880 if ( IsDiscoverWK( from, to ) );
881 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
882 if ( IsDiscoverBK( from, to ) ) { continue; }
884 XorFile( from, OCCUPIED_FILE );
885 XorDiag2( from, OCCUPIED_DIAG2 );
886 XorDiag1( from, OCCUPIED_DIAG1 );
887 Xor( from, BB_BOCCUPY );
888 Xor( from, BB_BLANCE );
889 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
890 | Cap2Move(-BOARD[to]) | Piece2Move(lance) );
893 XorFile( from, OCCUPIED_FILE );
894 XorDiag2( from, OCCUPIED_DIAG2 );
895 XorDiag1( from, OCCUPIED_DIAG1 );
896 Xor( from, BB_BOCCUPY );
897 Xor( from, BB_BLANCE );
900 bb_check.p[0] = bb_move.p[0] & BB_BPAWN_ATK.p[0]
901 & abb_w_gold_attacks[SQ_WKING].p[0];
902 while ( bb_check.p[0] ) {
903 to = last_one0( bb_check.p[0] );
905 bb_check.p[0] ^= abb_mask[to].p[0];
907 BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
908 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
909 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
910 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
911 XorFile( from, OCCUPIED_FILE );
912 XorDiag2( from, OCCUPIED_DIAG2 );
913 XorDiag1( from, OCCUPIED_DIAG1 );
915 if ( ! is_white_attacked( ptree, to ) ) { goto b_pawn_pro_next; }
916 bb_attacks = abb_b_gold_attacks[to];
917 if ( can_w_king_escape( ptree,to,bb_attacks ) ) { goto b_pawn_pro_next; }
918 if ( IsDiscoverWK( from, to ) );
919 else if ( can_w_piece_capture( ptree, to ) ) { goto b_pawn_pro_next; }
920 if ( IsDiscoverBK( from, to ) ) { goto b_pawn_pro_next; }
922 XorFile( from, OCCUPIED_FILE );
923 XorDiag2( from, OCCUPIED_DIAG2 );
924 XorDiag1( from, OCCUPIED_DIAG1 );
925 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
926 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
927 BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
928 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
929 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
930 | Cap2Move(-BOARD[to]) | Piece2Move(pawn) );
933 XorFile( from, OCCUPIED_FILE );
934 XorDiag2( from, OCCUPIED_DIAG2 );
935 XorDiag1( from, OCCUPIED_DIAG1 );
936 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
937 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
938 BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
939 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
942 if ( SQ_WKING >= A7 && SQ_WKING <= I3 ) {
943 to = SQ_WKING + nfile;
945 if ( BOARD[from] == pawn && BOARD[to] <= 0 ) {
947 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
948 BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
949 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
950 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
951 XorFile( from, OCCUPIED_FILE );
952 XorDiag2( from, OCCUPIED_DIAG2 );
953 XorDiag1( from, OCCUPIED_DIAG1 );
955 if ( ! is_white_attacked( ptree, to ) ) { goto b_pawn_end; }
957 if ( can_w_king_escape( ptree,to,bb_attacks ) ) { goto b_pawn_end; }
958 if ( can_w_piece_capture( ptree, to ) ) { goto b_pawn_end; }
959 if ( IsDiscoverBK( from, to ) ) { goto b_pawn_end; }
961 XorFile( from, OCCUPIED_FILE );
962 XorDiag2( from, OCCUPIED_DIAG2 );
963 XorDiag1( from, OCCUPIED_DIAG1 );
964 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
965 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
966 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
967 BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
968 return ( To2Move(to) | From2Move(from)
969 | Cap2Move(-BOARD[to]) | Piece2Move(pawn) );
972 XorFile( from, OCCUPIED_FILE );
973 XorDiag2( from, OCCUPIED_DIAG2 );
974 XorDiag1( from, OCCUPIED_DIAG1 );
975 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
976 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
977 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
978 BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
987 is_w_mate_in_1ply( tree_t * restrict ptree )
989 bitboard_t bb, bb_temp, bb_check, bb_check_pro, bb_attacks, bb_drop, bb_move;
991 int to, from, idirec;
993 assert( ! is_white_attacked( ptree, SQ_WKING ) );
996 BBOr( bb_drop, BB_BOCCUPY, BB_WOCCUPY );
997 BBNot( bb_drop, bb_drop );
999 if ( IsHandRook(HAND_W) ) {
1001 BBAnd( bb, abb_w_gold_attacks[SQ_BKING],
1002 abb_b_gold_attacks[SQ_BKING] );
1003 BBAnd( bb, bb, bb_drop );
1009 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1011 bb_attacks = abb_file_attacks[to][0];
1012 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1013 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1014 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1015 return To2Move(to) | Drop2Move(rook);
1018 } else if ( IsHandLance(HAND_W) && SQ_BKING >= A8 ) {
1020 to = SQ_BKING-nfile;
1021 if ( ( ! BOARD[to] ) && is_black_attacked( ptree, to ) )
1023 bb_attacks = abb_file_attacks[to][0];
1024 if ( ( ! can_b_king_escape( ptree, to, bb_attacks ) )
1025 && ( ! can_b_piece_capture( ptree, to ) ) )
1027 return To2Move(to) | Drop2Move(lance);
1032 if ( IsHandBishop(HAND_W) ) {
1034 BBAnd( bb, abb_w_silver_attacks[SQ_BKING],
1035 abb_b_silver_attacks[SQ_BKING] );
1036 BBAnd( bb, bb, bb_drop );
1042 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1044 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1045 abb_bishop_attacks_rl45[to][0] );
1046 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1047 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1048 return To2Move(to) | Drop2Move(bishop);
1052 if ( IsHandGold(HAND_W) ) {
1054 if ( IsHandRook(HAND_W) )
1056 BBAnd( bb, abb_w_gold_attacks[SQ_BKING],
1057 abb_w_silver_attacks[SQ_BKING] );
1059 BBAnd( bb, bb, bb_drop );
1060 BBAnd( bb, bb, abb_b_gold_attacks[SQ_BKING] );
1062 else { BBAnd( bb, bb_drop, abb_b_gold_attacks[SQ_BKING] ); }
1069 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1071 bb_attacks = abb_w_gold_attacks[to];
1072 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1073 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1074 return To2Move(to) | Drop2Move(gold);
1078 if ( IsHandSilver(HAND_W) ) {
1080 if ( IsHandGold(HAND_W) )
1082 if ( IsHandBishop(HAND_W) ) { goto w_silver_drop_end; }
1083 BBNot( bb, abb_b_gold_attacks[SQ_BKING] );
1084 BBAnd( bb, bb, abb_b_silver_attacks[SQ_BKING] );
1085 BBAnd( bb, bb, bb_drop );
1088 BBAnd( bb, bb_drop, abb_b_silver_attacks[SQ_BKING] );
1089 if ( IsHandBishop(HAND_W) )
1091 BBAnd( bb, bb, abb_b_gold_attacks[SQ_BKING] );
1100 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1102 bb_attacks = abb_w_silver_attacks[to];
1103 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1104 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1105 return To2Move(to) | Drop2Move(silver);
1110 if ( IsHandKnight(HAND_W) ) {
1112 BBAnd( bb, bb_drop, abb_b_knight_attacks[SQ_BKING] );
1118 BBIni( bb_attacks );
1119 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1120 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1121 return To2Move(to) | Drop2Move(knight);
1126 BBNot( bb_move, BB_WOCCUPY );
1129 while ( BBToU(bb) ) {
1130 from = LastOne( bb );
1133 AttackDragon( bb_attacks, from );
1134 BBAnd( bb_check, bb_move, bb_attacks );
1135 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1136 if ( ! BBToU(bb_check) ) { continue; }
1138 Xor( from, BB_W_HDK );
1139 Xor( from, BB_W_RD );
1140 Xor( from, BB_WOCCUPY );
1141 XorFile( from, OCCUPIED_FILE );
1142 XorDiag2( from, OCCUPIED_DIAG2 );
1143 XorDiag1( from, OCCUPIED_DIAG1 );
1146 to = LastOne( bb_check );
1147 Xor( to, bb_check );
1149 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1151 if ( (int)adirec[SQ_BKING][to] & flag_cross )
1153 bb_attacks = abb_file_attacks[to][0];
1154 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1155 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1157 else { AttackDragon( bb_attacks, to ); }
1159 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1160 if ( IsDiscoverBK( from, to ) );
1161 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1162 if ( IsDiscoverWK( from, to ) ) { continue; }
1164 XorFile( from, OCCUPIED_FILE );
1165 XorDiag2( from, OCCUPIED_DIAG2 );
1166 XorDiag1( from, OCCUPIED_DIAG1 );
1167 Xor( from, BB_WOCCUPY );
1168 Xor( from, BB_W_RD );
1169 Xor( from, BB_W_HDK );
1170 return ( To2Move(to) | From2Move(from)
1171 | Cap2Move(BOARD[to]) | Piece2Move(dragon) );
1172 } while ( BBToU(bb_check) );
1174 XorFile( from, OCCUPIED_FILE );
1175 XorDiag2( from, OCCUPIED_DIAG2 );
1176 XorDiag1( from, OCCUPIED_DIAG1 );
1177 Xor( from, BB_WOCCUPY );
1178 Xor( from, BB_W_RD );
1179 Xor( from, BB_W_HDK );
1182 bb.p[2] = BB_WROOK.p[2];
1184 from = first_one2( bb.p[2] );
1185 bb.p[2] ^= abb_mask[from].p[2];
1187 AttackRook( bb_attacks, from );
1188 BBAnd( bb_check, bb_move, bb_attacks );
1189 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1190 if ( ! BBToU(bb_check) ) { continue; }
1192 BB_W_RD.p[2] ^= abb_mask[from].p[2];
1193 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1194 XorFile( from, OCCUPIED_FILE );
1195 XorDiag2( from, OCCUPIED_DIAG2 );
1196 XorDiag1( from, OCCUPIED_DIAG1 );
1199 to = LastOne( bb_check );
1200 Xor( to, bb_check );
1202 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1204 if ( (int)adirec[SQ_BKING][to] & flag_cross )
1206 bb_attacks = abb_file_attacks[to][0];
1207 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1208 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1210 else { AttackDragon( bb_attacks, to ); }
1212 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1213 if ( IsDiscoverBK( from, to ) );
1214 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1215 if ( IsDiscoverWK( from, to ) ) { continue; }
1217 XorFile( from, OCCUPIED_FILE );
1218 XorDiag2( from, OCCUPIED_DIAG2 );
1219 XorDiag1( from, OCCUPIED_DIAG1 );
1220 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1221 BB_W_RD.p[2] ^= abb_mask[from].p[2];
1222 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1223 | Cap2Move(BOARD[to]) | Piece2Move(rook) );
1224 } while ( BBToU(bb_check) );
1226 XorFile( from, OCCUPIED_FILE );
1227 XorDiag2( from, OCCUPIED_DIAG2 );
1228 XorDiag1( from, OCCUPIED_DIAG1 );
1229 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1230 BB_W_RD.p[2] ^= abb_mask[from].p[2];
1233 bb.p[0] = BB_WROOK.p[0];
1234 bb.p[1] = BB_WROOK.p[1];
1235 while ( bb.p[0] | bb.p[1] ) {
1236 from = last_one01( bb.p[0], bb.p[1] );
1237 bb.p[0] ^= abb_mask[from].p[0];
1238 bb.p[1] ^= abb_mask[from].p[1];
1240 AttackRook( bb_attacks, from );
1241 BBAnd( bb_check, bb_move, bb_attacks );
1242 bb_check.p[0] &= abb_b_gold_attacks[SQ_BKING].p[0];
1243 bb_check.p[1] &= abb_b_gold_attacks[SQ_BKING].p[1];
1244 bb_check.p[0] &= abb_w_gold_attacks[SQ_BKING].p[0];
1245 bb_check.p[1] &= abb_w_gold_attacks[SQ_BKING].p[1];
1246 bb_check.p[2] &= abb_king_attacks[SQ_BKING].p[2];
1247 if ( ! BBToU(bb_check) ) { continue; }
1249 BB_W_RD.p[0] ^= abb_mask[from].p[0];
1250 BB_W_RD.p[1] ^= abb_mask[from].p[1];
1251 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1252 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1253 XorFile( from, OCCUPIED_FILE );
1254 XorDiag2( from, OCCUPIED_DIAG2 );
1255 XorDiag1( from, OCCUPIED_DIAG1 );
1258 to = LastOne( bb_check );
1259 Xor( to, bb_check );
1261 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1264 if ( (int)adirec[SQ_BKING][to] & flag_cross )
1266 bb_attacks = abb_file_attacks[to][0];
1267 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1268 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
1269 bb_attacks.p[2] |= abb_king_attacks[to].p[2];
1271 else { AttackDragon( bb_attacks, to ); }
1273 bb_attacks = abb_file_attacks[to][0];
1274 bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1276 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1277 if ( IsDiscoverBK( from, to ) );
1278 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1279 if ( IsDiscoverWK( from, to ) ) { continue; }
1281 XorFile( from, OCCUPIED_FILE );
1282 XorDiag2( from, OCCUPIED_DIAG2 );
1283 XorDiag1( from, OCCUPIED_DIAG1 );
1284 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1285 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1286 BB_W_RD.p[0] ^= abb_mask[from].p[0];
1287 BB_W_RD.p[1] ^= abb_mask[from].p[1];
1288 return ( To2Move(to) | From2Move(from)
1289 | ( (to > I4) ? FLAG_PROMO : 0 )
1290 | Cap2Move(BOARD[to]) | Piece2Move(rook) );
1291 } while ( BBToU(bb_check) );
1293 XorFile( from, OCCUPIED_FILE );
1294 XorDiag2( from, OCCUPIED_DIAG2 );
1295 XorDiag1( from, OCCUPIED_DIAG1 );
1296 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1297 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1298 BB_W_RD.p[0] ^= abb_mask[from].p[0];
1299 BB_W_RD.p[1] ^= abb_mask[from].p[1];
1303 while ( BBToU(bb) ) {
1304 from = LastOne( bb );
1307 AttackHorse( bb_attacks, from );
1308 BBAnd( bb_check, bb_move, bb_attacks );
1309 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1310 if ( ! BBToU(bb_check) ) { continue; }
1312 Xor( from, BB_W_HDK );
1313 Xor( from, BB_W_BH );
1314 Xor( from, BB_WOCCUPY );
1315 XorFile( from, OCCUPIED_FILE );
1316 XorDiag2( from, OCCUPIED_DIAG2 );
1317 XorDiag1( from, OCCUPIED_DIAG1 );
1320 to = LastOne( bb_check );
1321 Xor( to, bb_check );
1323 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1325 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1326 abb_bishop_attacks_rl45[to][0] );
1327 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1328 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1329 if ( IsDiscoverBK( from, to ) );
1330 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1331 if ( IsDiscoverWK( from, to ) ) { continue; }
1333 XorFile( from, OCCUPIED_FILE );
1334 XorDiag2( from, OCCUPIED_DIAG2 );
1335 XorDiag1( from, OCCUPIED_DIAG1 );
1336 Xor( from, BB_WOCCUPY );
1337 Xor( from, BB_W_BH );
1338 Xor( from, BB_W_HDK );
1339 return ( To2Move(to) | From2Move(from)
1340 | Cap2Move(BOARD[to]) | Piece2Move(horse) );
1341 } while ( BBToU(bb_check) );
1343 XorFile( from, OCCUPIED_FILE );
1344 XorDiag2( from, OCCUPIED_DIAG2 );
1345 XorDiag1( from, OCCUPIED_DIAG1 );
1346 Xor( from, BB_WOCCUPY );
1347 Xor( from, BB_W_BH );
1348 Xor( from, BB_W_HDK );
1351 bb.p[2] = BB_WBISHOP.p[2];
1353 from = first_one2( bb.p[2] );
1354 bb.p[2] ^= abb_mask[from].p[2];
1356 AttackBishop( bb_attacks, from );
1357 BBAnd( bb_check, bb_move, bb_attacks );
1358 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1359 if ( ! BBToU(bb_check) ) { continue; }
1361 BB_W_BH.p[2] ^= abb_mask[from].p[2];
1362 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1363 XorFile( from, OCCUPIED_FILE );
1364 XorDiag2( from, OCCUPIED_DIAG2 );
1365 XorDiag1( from, OCCUPIED_DIAG1 );
1368 to = LastOne( bb_check );
1369 Xor( to, bb_check );
1371 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1373 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1374 abb_bishop_attacks_rl45[to][0] );
1375 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1376 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1377 if ( IsDiscoverBK( from, to ) );
1378 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1379 if ( IsDiscoverWK( from, to ) ) { continue; }
1381 XorFile( from, OCCUPIED_FILE );
1382 XorDiag2( from, OCCUPIED_DIAG2 );
1383 XorDiag1( from, OCCUPIED_DIAG1 );
1384 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1385 BB_W_BH.p[2] ^= abb_mask[from].p[2];
1386 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1387 | Cap2Move(BOARD[to]) | Piece2Move(bishop) );
1388 } while ( BBToU(bb_check) );
1390 XorFile( from, OCCUPIED_FILE );
1391 XorDiag2( from, OCCUPIED_DIAG2 );
1392 XorDiag1( from, OCCUPIED_DIAG1 );
1393 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1394 BB_W_BH.p[2] ^= abb_mask[from].p[2];
1397 bb.p[0] = BB_WBISHOP.p[0];
1398 bb.p[1] = BB_WBISHOP.p[1];
1399 while ( bb.p[0] | bb.p[1] ) {
1400 from = last_one01( bb.p[0], bb.p[1] );
1401 bb.p[0] ^= abb_mask[from].p[0];
1402 bb.p[1] ^= abb_mask[from].p[1];
1404 AttackBishop( bb_attacks, from );
1405 BBAnd( bb_check, bb_move, bb_attacks );
1406 bb_check.p[0] &= abb_b_silver_attacks[SQ_BKING].p[0];
1407 bb_check.p[1] &= abb_b_silver_attacks[SQ_BKING].p[1];
1408 bb_check.p[0] &= abb_w_silver_attacks[SQ_BKING].p[0];
1409 bb_check.p[1] &= abb_w_silver_attacks[SQ_BKING].p[1];
1410 bb_check.p[2] &= abb_king_attacks[SQ_BKING].p[2];
1411 if ( ! BBToU(bb_check) ) { continue; }
1413 BB_W_BH.p[0] ^= abb_mask[from].p[0];
1414 BB_W_BH.p[1] ^= abb_mask[from].p[1];
1415 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1416 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1417 XorFile( from, OCCUPIED_FILE );
1418 XorDiag2( from, OCCUPIED_DIAG2 );
1419 XorDiag1( from, OCCUPIED_DIAG1 );
1422 to = LastOne( bb_check );
1423 Xor( to, bb_check );
1425 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1427 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1428 abb_bishop_attacks_rl45[to][0] );
1430 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
1431 bb_attacks.p[2] |= abb_king_attacks[to].p[2];
1433 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1434 if ( IsDiscoverBK( from, to ) );
1435 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1436 if ( IsDiscoverWK( from, to ) ) { continue; }
1438 XorFile( from, OCCUPIED_FILE );
1439 XorDiag2( from, OCCUPIED_DIAG2 );
1440 XorDiag1( from, OCCUPIED_DIAG1 );
1441 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1442 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1443 BB_W_BH.p[0] ^= abb_mask[from].p[0];
1444 BB_W_BH.p[1] ^= abb_mask[from].p[1];
1445 return ( To2Move(to) | From2Move(from)
1446 | ( (to > I4) ? FLAG_PROMO : 0 )
1447 | Cap2Move(BOARD[to]) | Piece2Move(bishop) );
1448 } while ( BBToU(bb_check) );
1450 XorFile( from, OCCUPIED_FILE );
1451 XorDiag2( from, OCCUPIED_DIAG2 );
1452 XorDiag1( from, OCCUPIED_DIAG1 );
1453 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1454 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1455 BB_W_BH.p[0] ^= abb_mask[from].p[0];
1456 BB_W_BH.p[1] ^= abb_mask[from].p[1];
1459 BBAnd( bb, BB_WTGOLD, w_chk_tbl[SQ_BKING].gold );
1460 while ( BBToU(bb) ) {
1461 from = LastOne( bb );
1464 BBAnd( bb_check, bb_move, abb_w_gold_attacks[from] );
1465 BBAnd( bb_check, bb_check, abb_b_gold_attacks[SQ_BKING] );
1466 if ( ! BBToU(bb_check) ) { continue; }
1468 Xor( from, BB_WTGOLD );
1469 Xor( from, BB_WOCCUPY );
1470 XorFile( from, OCCUPIED_FILE );
1471 XorDiag2( from, OCCUPIED_DIAG2 );
1472 XorDiag1( from, OCCUPIED_DIAG1 );
1475 to = LastOne( bb_check );
1476 Xor( to, bb_check );
1478 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1480 bb_attacks = abb_w_gold_attacks[to];
1481 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1482 if ( IsDiscoverBK( from, to ) );
1483 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1484 if ( IsDiscoverWK( from, to ) ) { continue; }
1486 XorFile( from, OCCUPIED_FILE );
1487 XorDiag2( from, OCCUPIED_DIAG2 );
1488 XorDiag1( from, OCCUPIED_DIAG1 );
1489 Xor( from, BB_WOCCUPY );
1490 Xor( from, BB_WTGOLD );
1491 return ( To2Move(to) | From2Move(from)
1492 | Cap2Move(BOARD[to]) | Piece2Move(-BOARD[from]) );
1493 } while ( BBToU(bb_check) );
1495 XorFile( from, OCCUPIED_FILE );
1496 XorDiag2( from, OCCUPIED_DIAG2 );
1497 XorDiag1( from, OCCUPIED_DIAG1 );
1498 Xor( from, BB_WOCCUPY );
1499 Xor( from, BB_WTGOLD );
1502 BBAnd( bb, BB_WSILVER, w_chk_tbl[SQ_BKING].silver );
1504 from = first_one2( bb.p[2] );
1505 bb.p[2] ^= abb_mask[from].p[2];
1507 bb_check_pro.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1508 & abb_b_gold_attacks[SQ_BKING].p[1];
1509 bb_check_pro.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1510 & abb_b_gold_attacks[SQ_BKING].p[2];
1512 bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1513 & abb_b_silver_attacks[SQ_BKING].p[1]
1514 & ~abb_b_gold_attacks[SQ_BKING].p[1];
1515 bb_check.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1516 & abb_b_silver_attacks[SQ_BKING].p[2]
1517 & ~abb_b_gold_attacks[SQ_BKING].p[2];
1519 if ( ! ( bb_check_pro.p[1] | bb_check_pro.p[2]
1520 | bb_check.p[1]| bb_check.p[2] ) ) { continue; }
1522 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1523 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1524 XorFile( from, OCCUPIED_FILE );
1525 XorDiag2( from, OCCUPIED_DIAG2 );
1526 XorDiag1( from, OCCUPIED_DIAG1 );
1528 while ( bb_check_pro.p[1] | bb_check_pro.p[2] ) {
1529 to = last_one12( bb_check_pro.p[1], bb_check_pro.p[2] );
1530 bb_check_pro.p[1] ^= abb_mask[to].p[1];
1531 bb_check_pro.p[2] ^= abb_mask[to].p[2];
1533 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1535 bb_attacks = abb_w_gold_attacks[to];
1536 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1537 if ( IsDiscoverBK( from, to ) );
1538 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1539 if ( IsDiscoverWK( from, to ) ) { continue; }
1541 XorFile( from, OCCUPIED_FILE );
1542 XorDiag2( from, OCCUPIED_DIAG2 );
1543 XorDiag1( from, OCCUPIED_DIAG1 );
1544 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1545 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1546 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1547 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1550 while ( bb_check.p[1] | bb_check.p[2] ) {
1551 to = last_one12( bb_check.p[1], bb_check.p[2] );
1552 bb_check.p[1] ^= abb_mask[to].p[1];
1553 bb_check.p[2] ^= abb_mask[to].p[2];
1555 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1557 bb_attacks = abb_w_silver_attacks[to];
1558 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1559 if ( IsDiscoverBK( from, to ) );
1560 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1561 if ( IsDiscoverWK( from, to ) ) { continue; }
1563 XorFile( from, OCCUPIED_FILE );
1564 XorDiag2( from, OCCUPIED_DIAG2 );
1565 XorDiag1( from, OCCUPIED_DIAG1 );
1566 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1567 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1568 return ( To2Move(to) | From2Move(from)
1569 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1572 XorFile( from, OCCUPIED_FILE );
1573 XorDiag2( from, OCCUPIED_DIAG2 );
1574 XorDiag1( from, OCCUPIED_DIAG1 );
1575 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1576 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1579 ubb = bb.p[1] & 0x1ffU;
1581 from = first_one1( ubb );
1582 ubb ^= abb_mask[from].p[1];
1584 bb_check_pro.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1585 & abb_b_gold_attacks[SQ_BKING].p[2];
1587 bb_check.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1588 & abb_b_silver_attacks[SQ_BKING].p[2]
1589 & ~abb_b_gold_attacks[SQ_BKING].p[2];
1590 bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1591 & abb_b_silver_attacks[SQ_BKING].p[1];
1593 if ( ! (bb_check_pro.p[2]|bb_check.p[2]|bb_check.p[1]) ) { continue; }
1595 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1596 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1597 XorFile( from, OCCUPIED_FILE );
1598 XorDiag2( from, OCCUPIED_DIAG2 );
1599 XorDiag1( from, OCCUPIED_DIAG1 );
1601 while ( bb_check_pro.p[2] ) {
1602 to = first_one2( bb_check_pro.p[2] );
1603 bb_check_pro.p[2] ^= abb_mask[to].p[2];
1605 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1607 bb_attacks = abb_w_gold_attacks[to];
1608 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1609 if ( IsDiscoverBK( from, to ) );
1610 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1611 if ( IsDiscoverWK( from, to ) ) { continue; }
1613 XorFile( from, OCCUPIED_FILE );
1614 XorDiag2( from, OCCUPIED_DIAG2 );
1615 XorDiag1( from, OCCUPIED_DIAG1 );
1616 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1617 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1618 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1619 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1622 while ( bb_check.p[1] | bb_check.p[2] ) {
1623 to = last_one12( bb_check.p[1], bb_check.p[2] );
1624 bb_check.p[1] ^= abb_mask[to].p[1];
1625 bb_check.p[2] ^= abb_mask[to].p[2];
1627 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1629 bb_attacks = abb_w_silver_attacks[to];
1630 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1631 if ( IsDiscoverBK( from, to ) );
1632 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1633 if ( IsDiscoverWK( from, to ) ) { continue; }
1635 XorFile( from, OCCUPIED_FILE );
1636 XorDiag2( from, OCCUPIED_DIAG2 );
1637 XorDiag1( from, OCCUPIED_DIAG1 );
1638 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1639 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1640 return ( To2Move(to) | From2Move(from)
1641 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1644 XorFile( from, OCCUPIED_FILE );
1645 XorDiag2( from, OCCUPIED_DIAG2 );
1646 XorDiag1( from, OCCUPIED_DIAG1 );
1647 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1648 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1652 bb.p[1] = bb.p[1] & 0x7fffe00U;
1653 while ( bb.p[0] | bb.p[1] ) {
1654 from = last_one01( bb.p[0], bb.p[1] );
1655 bb.p[0] ^= abb_mask[from].p[0];
1656 bb.p[1] ^= abb_mask[from].p[1];
1658 bb_check.p[0] = bb_move.p[0] & abb_w_silver_attacks[from].p[0]
1659 & abb_b_silver_attacks[SQ_BKING].p[0];
1660 bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1661 & abb_b_silver_attacks[SQ_BKING].p[1];
1662 if ( ! ( bb_check.p[0] | bb_check.p[1] ) ) { continue; }
1664 BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1665 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1666 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1667 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1668 XorFile( from, OCCUPIED_FILE );
1669 XorDiag2( from, OCCUPIED_DIAG2 );
1670 XorDiag1( from, OCCUPIED_DIAG1 );
1673 to = last_one01( bb_check.p[0], bb_check.p[1] );
1674 bb_check.p[0] ^= abb_mask[to].p[0];
1675 bb_check.p[1] ^= abb_mask[to].p[1];
1677 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1679 bb_attacks = abb_w_silver_attacks[to];
1680 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1681 if ( IsDiscoverBK( from, to ) );
1682 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1683 if ( IsDiscoverWK( from, to ) ) { continue; }
1685 XorFile( from, OCCUPIED_FILE );
1686 XorDiag2( from, OCCUPIED_DIAG2 );
1687 XorDiag1( from, OCCUPIED_DIAG1 );
1688 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1689 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1690 BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1691 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1692 return ( To2Move(to) | From2Move(from)
1693 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1694 } while ( bb_check.p[0] | bb_check.p[1] );
1696 XorFile( from, OCCUPIED_FILE );
1697 XorDiag2( from, OCCUPIED_DIAG2 );
1698 XorDiag1( from, OCCUPIED_DIAG1 );
1699 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1700 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1701 BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1702 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1705 BBAnd( bb, BB_WKNIGHT, w_chk_tbl[SQ_BKING].knight );
1706 while ( BBToU(bb) ) {
1707 from = LastOne( bb );
1710 bb_check.p[2] = bb_move.p[2] & abb_w_knight_attacks[from].p[2]
1711 & abb_b_gold_attacks[SQ_BKING].p[2];
1713 if ( bb_check.p[2] ) {
1714 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1715 BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1716 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1717 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1718 XorFile( from, OCCUPIED_FILE );
1719 XorDiag2( from, OCCUPIED_DIAG2 );
1720 XorDiag1( from, OCCUPIED_DIAG1 );
1723 to = first_one2( bb_check.p[2] );
1724 bb_check.p[2] ^= abb_mask[to].p[2];
1726 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1728 bb_attacks = abb_w_gold_attacks[to];
1729 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1730 if ( IsDiscoverBK( from, to ) );
1731 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1732 if ( IsDiscoverWK( from, to ) ) { continue; }
1734 XorFile( from, OCCUPIED_FILE );
1735 XorDiag2( from, OCCUPIED_DIAG2 );
1736 XorDiag1( from, OCCUPIED_DIAG1 );
1737 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1738 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1739 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1740 BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1741 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1742 | Cap2Move(BOARD[to]) | Piece2Move(knight) );
1743 } while ( bb_check.p[2] );
1745 XorFile( from, OCCUPIED_FILE );
1746 XorDiag2( from, OCCUPIED_DIAG2 );
1747 XorDiag1( from, OCCUPIED_DIAG1 );
1748 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1749 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1750 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1751 BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1754 BBAnd( bb_check, bb_move, abb_w_knight_attacks[from] );
1755 BBAnd( bb_check, bb_check, abb_b_knight_attacks[SQ_BKING] );
1757 if ( BBToU(bb_check) ) {
1758 BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1759 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1760 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1761 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1762 XorFile( from, OCCUPIED_FILE );
1763 XorDiag2( from, OCCUPIED_DIAG2 );
1764 XorDiag1( from, OCCUPIED_DIAG1 );
1767 to = LastOne( bb_check );
1768 Xor( to, bb_check );
1770 BBIni( bb_attacks );
1771 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1772 if ( IsDiscoverBK( from, to ) );
1773 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1774 if ( IsDiscoverWK( from, to ) ) { continue; }
1776 XorFile( from, OCCUPIED_FILE );
1777 XorDiag2( from, OCCUPIED_DIAG2 );
1778 XorDiag1( from, OCCUPIED_DIAG1 );
1779 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1780 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1781 BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1782 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1783 return ( To2Move(to) | From2Move(from)
1784 | Cap2Move(BOARD[to]) | Piece2Move(knight) );
1785 } while ( BBToU(bb_check) );
1787 XorFile( from, OCCUPIED_FILE );
1788 XorDiag2( from, OCCUPIED_DIAG2 );
1789 XorDiag1( from, OCCUPIED_DIAG1 );
1790 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1791 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1792 BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1793 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1798 BBAnd( bb, BB_WLANCE, w_chk_tbl[SQ_BKING].lance );
1799 while ( BBToU(bb) ) {
1800 from = LastOne( bb );
1803 bb_attacks = AttackFile(from);
1804 BBAnd( bb_attacks, bb_attacks, abb_plus_rays[from] );
1805 BBAnd( bb_attacks, bb_attacks, bb_move );
1807 BBAnd( bb_check, bb_attacks, abb_mask[SQ_BKING-nfile] );
1808 bb_check_pro.p[2] = bb_attacks.p[2] & abb_b_gold_attacks[SQ_BKING].p[2];
1810 if ( ! ( bb_check_pro.p[2] | bb_check.p[0]
1811 | bb_check.p[1] | bb_check.p[2] ) ) { continue; }
1813 Xor( from, BB_WLANCE );
1814 Xor( from, BB_WOCCUPY );
1815 XorFile( from, OCCUPIED_FILE );
1816 XorDiag2( from, OCCUPIED_DIAG2 );
1817 XorDiag1( from, OCCUPIED_DIAG1 );
1819 bb_check.p[2] &= 0x7fc0000U;
1820 if ( BBToU(bb_check) ) {
1822 to = SQ_BKING-nfile;
1823 if ( ! is_black_attacked( ptree, to ) ) {
1824 bb_check.p[2] &= ~abb_mask[to].p[2];
1827 bb_temp = abb_file_attacks[to][0];
1828 if ( can_b_king_escape( ptree, to, bb_temp ) ) { goto w_lance_next; }
1829 if ( IsDiscoverBK( from, to ) );
1830 else if ( can_b_piece_capture( ptree, to ) ) { goto w_lance_next; }
1831 if ( IsDiscoverWK( from, to ) ) { goto w_lance_next; }
1833 XorFile( from, OCCUPIED_FILE );
1834 XorDiag2( from, OCCUPIED_DIAG2 );
1835 XorDiag1( from, OCCUPIED_DIAG1 );
1836 Xor( from, BB_WOCCUPY );
1837 Xor( from, BB_WLANCE );
1838 return ( To2Move(to) | From2Move(from)
1839 | Cap2Move(BOARD[to]) | Piece2Move(lance) );
1843 while ( bb_check_pro.p[2] )
1845 to = first_one2( bb_check_pro.p[2] );
1846 bb_check_pro.p[2] ^= abb_mask[to].p[2];
1848 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1850 bb_attacks = abb_w_gold_attacks[to];
1851 if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1852 if ( IsDiscoverBK( from, to ) );
1853 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1854 if ( IsDiscoverWK( from, to ) ) { continue; }
1856 XorFile( from, OCCUPIED_FILE );
1857 XorDiag2( from, OCCUPIED_DIAG2 );
1858 XorDiag1( from, OCCUPIED_DIAG1 );
1859 Xor( from, BB_WOCCUPY );
1860 Xor( from, BB_WLANCE );
1861 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1862 | Cap2Move(BOARD[to]) | Piece2Move(lance) );
1865 XorFile( from, OCCUPIED_FILE );
1866 XorDiag2( from, OCCUPIED_DIAG2 );
1867 XorDiag1( from, OCCUPIED_DIAG1 );
1868 Xor( from, BB_WOCCUPY );
1869 Xor( from, BB_WLANCE );
1872 bb_check.p[2] = bb_move.p[2] & BB_WPAWN_ATK.p[2]
1873 & abb_b_gold_attacks[SQ_BKING].p[2];
1874 while ( bb_check.p[2] ) {
1875 to = first_one2( bb_check.p[2] );
1877 bb_check.p[2] ^= abb_mask[to].p[2];
1879 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1880 BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1881 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1882 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1883 XorFile( from, OCCUPIED_FILE );
1884 XorDiag2( from, OCCUPIED_DIAG2 );
1885 XorDiag1( from, OCCUPIED_DIAG1 );
1887 if ( ! is_black_attacked( ptree, to ) ) { goto w_pawn_pro_next; }
1888 bb_attacks = abb_w_gold_attacks[to];
1889 if ( can_b_king_escape( ptree,to,bb_attacks ) ) { goto w_pawn_pro_next; }
1890 if ( IsDiscoverBK( from, to ) );
1891 else if ( can_b_piece_capture( ptree, to ) ) { goto w_pawn_pro_next; }
1892 if ( IsDiscoverWK( from, to ) ) { goto w_pawn_pro_next; }
1894 XorFile( from, OCCUPIED_FILE );
1895 XorDiag2( from, OCCUPIED_DIAG2 );
1896 XorDiag1( from, OCCUPIED_DIAG1 );
1897 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1898 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1899 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1900 BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1901 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1902 | Cap2Move(BOARD[to]) | Piece2Move(pawn) );
1905 XorFile( from, OCCUPIED_FILE );
1906 XorDiag2( from, OCCUPIED_DIAG2 );
1907 XorDiag1( from, OCCUPIED_DIAG1 );
1908 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1909 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1910 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1911 BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1914 if ( SQ_BKING <= I3 && SQ_BKING >= A7 ) {
1915 to = SQ_BKING - nfile;
1917 if ( BOARD[from] == -pawn && BOARD[to] >= 0 ) {
1919 BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1920 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1921 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1922 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1923 XorFile( from, OCCUPIED_FILE );
1924 XorDiag2( from, OCCUPIED_DIAG2 );
1925 XorDiag1( from, OCCUPIED_DIAG1 );
1927 if ( ! is_black_attacked( ptree, to ) ) { goto w_pawn_end; }
1928 BBIni( bb_attacks );
1929 if ( can_b_king_escape( ptree,to,bb_attacks ) ) { goto w_pawn_end; }
1930 if ( can_b_piece_capture( ptree, to ) ) { goto w_pawn_end; }
1931 if ( IsDiscoverWK( from, to ) ) { goto w_pawn_end; }
1933 XorFile( from, OCCUPIED_FILE );
1934 XorDiag2( from, OCCUPIED_DIAG2 );
1935 XorDiag1( from, OCCUPIED_DIAG1 );
1936 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1937 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1938 BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1939 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1940 return ( To2Move(to) | From2Move(from)
1941 | Cap2Move(BOARD[to]) | Piece2Move(pawn) );
1944 XorFile( from, OCCUPIED_FILE );
1945 XorDiag2( from, OCCUPIED_DIAG2 );
1946 XorDiag1( from, OCCUPIED_DIAG1 );
1947 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1948 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1949 BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1950 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1959 can_w_piece_capture( const tree_t * restrict ptree, int to )
1961 bitboard_t bb_sum, bb, bb_attacks;
1965 if ( to >= A8 && BOARD[from] == -pawn )
1967 if ( IsDiscoverWK(from,to) );
1971 BBAnd( bb_sum, BB_WKNIGHT, abb_b_knight_attacks[to] );
1973 BBAnd( bb, BB_WSILVER, abb_b_silver_attacks[to] );
1974 BBOr( bb_sum, bb, bb_sum );
1976 BBAnd( bb, BB_WTGOLD, abb_b_gold_attacks[to] );
1977 BBOr( bb_sum, bb, bb_sum );
1979 BBOr( bb, BB_WHORSE, BB_WDRAGON );
1980 BBAnd( bb, bb, abb_king_attacks[to] );
1981 BBOr( bb_sum, bb, bb_sum );
1983 AttackBishop( bb, to );
1984 BBAnd( bb, BB_W_BH, bb );
1985 BBOr( bb_sum, bb, bb_sum );
1987 bb_sum.p[aslide[to].ir0] |= BB_W_RD.p[aslide[to].ir0] & AttackRank(to);
1989 BBAnd( bb, BB_WLANCE, abb_minus_rays[to] );
1990 BBOr( bb, bb, BB_W_RD );
1991 bb_attacks = AttackFile( to );
1992 BBAnd( bb, bb, bb_attacks );
1993 BBOr( bb_sum, bb_sum, bb );
1995 while ( BBToU( bb_sum ) )
1997 from = FirstOne( bb_sum );
1998 Xor( from, bb_sum );
2000 if ( IsDiscoverWK(from,to) ) { continue; }
2009 can_b_piece_capture( const tree_t * restrict ptree, int to )
2011 bitboard_t bb_sum, bb, bb_attacks;
2015 if ( to <= I2 && BOARD[from] == pawn )
2017 if ( IsDiscoverBK(from,to) );
2021 BBAnd( bb_sum, BB_BKNIGHT, abb_w_knight_attacks[to] );
2023 BBAnd( bb, BB_BSILVER, abb_w_silver_attacks[to] );
2024 BBOr( bb_sum, bb_sum, bb );
2026 BBAnd( bb, BB_BTGOLD, abb_w_gold_attacks[to] );
2027 BBOr( bb_sum, bb_sum, bb );
2029 BBOr( bb, BB_BHORSE, BB_BDRAGON );
2030 BBAnd( bb, bb, abb_king_attacks[to] );
2031 BBOr( bb_sum, bb_sum, bb );
2033 AttackBishop( bb, to );
2034 BBAnd( bb, bb, BB_B_BH );
2035 BBOr( bb_sum, bb_sum, bb );
2037 bb_sum.p[aslide[to].ir0] |= BB_B_RD.p[aslide[to].ir0] & AttackRank(to);
2039 BBAnd( bb, BB_BLANCE, abb_plus_rays[to] );
2040 BBOr( bb, bb, BB_B_RD );
2041 bb_attacks = AttackFile( to );
2042 BBAnd( bb, bb, bb_attacks );
2043 BBOr( bb_sum, bb_sum, bb );
2045 while ( BBToU( bb_sum ) )
2047 from = LastOne( bb_sum );
2048 Xor( from, bb_sum );
2050 if ( IsDiscoverBK( from, to ) ) { continue; }
2059 can_w_king_escape( tree_t * restrict ptree, int to, bitboard_t bb )
2061 int iret = 0, iescape;
2065 Xor( to, BB_BOCCUPY );
2066 XorFile( to, OCCUPIED_FILE );
2067 XorDiag2( to, OCCUPIED_DIAG2 );
2068 XorDiag1( to, OCCUPIED_DIAG1 );
2070 Xor( SQ_WKING, BB_WOCCUPY );
2071 XorFile( SQ_WKING, OCCUPIED_FILE );
2072 XorDiag2( SQ_WKING, OCCUPIED_DIAG2 );
2073 XorDiag1( SQ_WKING, OCCUPIED_DIAG1 );
2075 BBOr( bb, bb, abb_mask[to] );
2076 BBOr( bb, bb, BB_WOCCUPY );
2078 BBAnd( bb, bb, abb_king_attacks[SQ_WKING] );
2082 iescape = FirstOne( bb );
2083 if ( ! is_white_attacked( ptree, iescape ) )
2091 XorFile( SQ_WKING, OCCUPIED_FILE );
2092 XorDiag2( SQ_WKING, OCCUPIED_DIAG2 );
2093 XorDiag1( SQ_WKING, OCCUPIED_DIAG1 );
2094 Xor( SQ_WKING, BB_WOCCUPY );
2097 Xor( to, BB_BOCCUPY );
2098 XorFile( to, OCCUPIED_FILE );
2099 XorDiag2( to, OCCUPIED_DIAG2 );
2100 XorDiag1( to, OCCUPIED_DIAG1 );
2108 can_b_king_escape( tree_t * restrict ptree, int to, bitboard_t bb )
2110 int iret = 0, iescape;
2114 Xor( to, BB_WOCCUPY );
2115 XorFile( to, OCCUPIED_FILE );
2116 XorDiag2( to, OCCUPIED_DIAG2 );
2117 XorDiag1( to, OCCUPIED_DIAG1 );
2120 Xor( SQ_BKING, BB_BOCCUPY );
2121 XorFile( SQ_BKING, OCCUPIED_FILE );
2122 XorDiag2( SQ_BKING, OCCUPIED_DIAG2 );
2123 XorDiag1( SQ_BKING, OCCUPIED_DIAG1 );
2125 BBOr( bb, bb, abb_mask[to] );
2126 BBOr( bb, bb, BB_BOCCUPY );
2128 BBAnd( bb, bb, abb_king_attacks[SQ_BKING] );
2132 iescape = LastOne( bb );
2133 if ( ! is_black_attacked( ptree, iescape ) )
2141 XorFile( SQ_BKING, OCCUPIED_FILE );
2142 XorDiag2( SQ_BKING, OCCUPIED_DIAG2 );
2143 XorDiag1( SQ_BKING, OCCUPIED_DIAG1 );
2144 Xor( SQ_BKING, BB_BOCCUPY );
2148 XorFile( to, OCCUPIED_FILE );
2149 XorDiag2( to, OCCUPIED_DIAG2 );
2150 XorDiag1( to, OCCUPIED_DIAG1 );
2151 Xor( to, BB_WOCCUPY );