5 static void CONV add_behind_attacks( bitboard_t * restrict pbb, int idirec,
9 b_gen_checks( tree_t * restrict __ptree__, unsigned int * restrict pmove )
11 bitboard_t bb_piece, bb_rook_chk, bb_bishop_chk, bb_chk, bb_move_to;
12 bitboard_t bb_diag1_chk, bb_diag2_chk, bb_file_chk, bb_drop_to, bb_desti;
13 bitboard_t bb_rank_chk;
14 const tree_t * restrict ptree = __ptree__;
15 unsigned int u0, u1, u2;
16 int from, to, sq_wk, idirec;
19 bb_file_chk = AttackFile( sq_wk );
20 bb_rank_chk = AttackRank( sq_wk );
21 BBOr( bb_rook_chk, bb_file_chk, bb_rank_chk );
23 bb_diag1_chk = AttackDiag1( sq_wk );
24 bb_diag2_chk = AttackDiag2( sq_wk );
25 BBOr( bb_bishop_chk, bb_diag1_chk, bb_diag2_chk );
26 BBNot( bb_move_to, BB_BOCCUPY );
27 BBOr( bb_drop_to, BB_BOCCUPY, BB_WOCCUPY );
28 BBNot( bb_drop_to, bb_drop_to );
31 idirec = (int)adirec[sq_wk][from];
32 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
35 add_behind_attacks( &bb_chk, idirec, sq_wk );
36 BBAnd( bb_chk, bb_chk, abb_king_attacks[from] );
37 BBAnd( bb_chk, bb_chk, bb_move_to );
39 while( BBTest( bb_chk ) )
41 to = LastOne( bb_chk );
43 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(king)
44 | Cap2Move(-BOARD[to]);
49 bb_piece = BB_BDRAGON;
50 while( BBTest( bb_piece ) )
52 from = LastOne( bb_piece );
53 Xor( from, bb_piece );
55 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_wk] );
56 idirec = (int)adirec[sq_wk][from];
57 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
59 add_behind_attacks( &bb_chk, idirec, sq_wk );
62 AttackDragon( bb_desti, from );
63 BBAnd( bb_chk, bb_chk, bb_desti );
64 BBAnd( bb_chk, bb_chk, bb_move_to );
66 while( BBTest( bb_chk ) )
68 to = LastOne( bb_chk );
70 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(dragon)
71 | Cap2Move(-BOARD[to]);
76 while( BBTest( bb_piece ) )
78 from = LastOne( bb_piece );
79 Xor( from, bb_piece );
81 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_wk] );
82 idirec = (int)adirec[sq_wk][from];
83 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
85 add_behind_attacks( &bb_chk, idirec, sq_wk );
88 AttackHorse( bb_desti, from );
89 BBAnd( bb_chk, bb_chk, bb_desti );
90 BBAnd( bb_chk, bb_chk, bb_move_to );
92 while( BBTest( bb_chk ) )
94 to = LastOne( bb_chk );
96 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(horse)
97 | Cap2Move(-BOARD[to]);
105 from = last_one12( u1, u2 );
106 u1 ^= abb_mask[from].p[1];
107 u2 ^= abb_mask[from].p[2];
109 AttackRook( bb_desti, from );
111 idirec = (int)adirec[sq_wk][from];
112 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
114 BBAnd( bb_chk, bb_desti, bb_move_to );
117 bb_chk = bb_rook_chk;
118 bb_chk.p[0] |= abb_king_attacks[sq_wk].p[0];
119 BBAnd( bb_chk, bb_chk, bb_desti );
120 BBAnd( bb_chk, bb_chk, bb_move_to );
123 while ( bb_chk.p[0] )
125 to = last_one0( bb_chk.p[0] );
126 bb_chk.p[0] ^= abb_mask[to].p[0];
127 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(rook)
128 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
131 while( bb_chk.p[1] | bb_chk.p[2] )
133 to = last_one12( bb_chk.p[1], bb_chk.p[2] );
134 bb_chk.p[1] ^= abb_mask[to].p[1];
135 bb_chk.p[2] ^= abb_mask[to].p[2];
136 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(rook)
137 | Cap2Move(-BOARD[to]);
144 from = last_one0( u0 );
145 u0 ^= abb_mask[from].p[0];
147 AttackRook( bb_desti, from );
149 idirec = (int)adirec[sq_wk][from];
150 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
152 BBAnd( bb_chk, bb_desti, bb_move_to );
155 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_wk] );
156 BBAnd( bb_chk, bb_chk, bb_desti );
157 BBAnd( bb_chk, bb_chk, bb_move_to );
160 while( BBTest( bb_chk ) )
162 to = LastOne( bb_chk );
164 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(rook)
165 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
169 u1 = BB_BBISHOP.p[1];
170 u2 = BB_BBISHOP.p[2];
173 from = last_one12( u1, u2 );
174 u1 ^= abb_mask[from].p[1];
175 u2 ^= abb_mask[from].p[2];
177 AttackBishop( bb_desti, from );
179 idirec = (int)adirec[sq_wk][from];
180 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
182 BBAnd( bb_chk, bb_desti, bb_move_to );
185 bb_chk = bb_bishop_chk;
186 bb_chk.p[0] |= abb_king_attacks[sq_wk].p[0];
187 BBAnd( bb_chk, bb_chk, bb_desti );
188 BBAnd( bb_chk, bb_chk, bb_move_to );
191 while ( bb_chk.p[0] )
193 to = last_one0( bb_chk.p[0] );
194 bb_chk.p[0] ^= abb_mask[to].p[0];
195 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(bishop)
196 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
199 while( bb_chk.p[1] | bb_chk.p[2] )
201 to = last_one12( bb_chk.p[1], bb_chk.p[2] );
202 bb_chk.p[1] ^= abb_mask[to].p[1];
203 bb_chk.p[2] ^= abb_mask[to].p[2];
204 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(bishop)
205 | Cap2Move(-BOARD[to]);
209 u0 = BB_BBISHOP.p[0];
212 from = last_one0( u0 );
213 u0 ^= abb_mask[from].p[0];
215 AttackBishop( bb_desti, from );
217 idirec = (int)adirec[sq_wk][from];
218 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
220 BBAnd( bb_chk, bb_desti, bb_move_to );
223 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_wk] );
224 BBAnd( bb_chk, bb_chk, bb_desti );
225 BBAnd( bb_chk, bb_chk, bb_move_to );
228 while( BBTest( bb_chk ) )
230 to = LastOne( bb_chk );
232 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(bishop)
233 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
238 bb_piece = BB_BTGOLD;
239 while( BBTest( bb_piece ) )
241 from = LastOne( bb_piece );
242 Xor( from, bb_piece );
244 bb_chk = abb_w_gold_attacks[sq_wk];
246 idirec = (int)adirec[sq_wk][from];
247 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
249 add_behind_attacks( &bb_chk, idirec, sq_wk );
252 BBAnd( bb_chk, bb_chk, abb_b_gold_attacks[from] );
253 BBAnd( bb_chk, bb_chk, bb_move_to );
255 while( BBTest( bb_chk ) )
257 to = LastOne( bb_chk );
259 *pmove++ = ( To2Move(to) | From2Move(from)
260 | Piece2Move(BOARD[from])
261 | Cap2Move(-BOARD[to]) );
266 u0 = BB_BSILVER.p[0];
269 from = last_one0( u0 );
270 u0 ^= abb_mask[from].p[0];
272 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
273 bb_chk.p[1] = abb_w_gold_attacks[sq_wk].p[1];
276 idirec = (int)adirec[sq_wk][from];
277 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
279 add_behind_attacks( &bb_chk, idirec, sq_wk );
282 bb_chk.p[0] &= bb_move_to.p[0] & abb_b_silver_attacks[from].p[0];
283 bb_chk.p[1] &= bb_move_to.p[1] & abb_b_silver_attacks[from].p[1];
285 while( bb_chk.p[0] | bb_chk.p[1] )
287 to = last_one01( bb_chk.p[0], bb_chk.p[1] );
288 bb_chk.p[0] ^= abb_mask[to].p[0];
289 bb_chk.p[1] ^= abb_mask[to].p[1];
290 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(silver)
291 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
296 u1 = BB_BSILVER.p[1] & 0x7fc0000U;
299 from = last_one1( u1 );
300 u1 ^= abb_mask[from].p[1];
302 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
303 bb_chk.p[1] = bb_chk.p[2] = 0;
305 idirec = (int)adirec[sq_wk][from];
306 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
308 add_behind_attacks( &bb_chk, idirec, sq_wk );
311 bb_chk.p[0] &= bb_move_to.p[0] & abb_b_silver_attacks[from].p[0];
312 while ( bb_chk.p[0] )
314 to = last_one0( bb_chk.p[0] );
315 bb_chk.p[0] ^= abb_mask[to].p[0];
316 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(silver)
317 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
322 bb_piece = BB_BSILVER;
323 while( BBTest( bb_piece ) )
325 from = LastOne( bb_piece );
326 Xor( from, bb_piece );
328 bb_chk = abb_w_silver_attacks[sq_wk];
330 idirec = (int)adirec[sq_wk][from];
331 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
333 add_behind_attacks( &bb_chk, idirec, sq_wk );
336 BBAnd( bb_chk, bb_chk, abb_b_silver_attacks[from] );
337 BBAnd( bb_chk, bb_chk, bb_move_to );
339 while( BBTest( bb_chk ) )
341 to = LastOne( bb_chk );
343 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(silver)
344 | Cap2Move(-BOARD[to]);
349 u0 = BB_BKNIGHT.p[0];
350 u1 = BB_BKNIGHT.p[1] & 0x7fffe00U;
353 from = last_one01( u0, u1 );
354 u0 ^= abb_mask[from].p[0];
355 u1 ^= abb_mask[from].p[1];
357 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
358 bb_chk.p[1] = bb_chk.p[2] = 0;
360 idirec = (int)adirec[sq_wk][from];
361 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
363 add_behind_attacks( &bb_chk, idirec, sq_wk );
366 bb_chk.p[0] &= abb_b_knight_attacks[from].p[0] & bb_move_to.p[0];
370 to = last_one0( bb_chk.p[0] );
371 bb_chk.p[0] ^= abb_mask[to].p[0];
372 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(knight)
373 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
378 u2 = BB_BKNIGHT.p[2];
379 u1 = BB_BKNIGHT.p[1] & 0x3ffffU;
382 from = last_one12( u1, u2 );
383 u2 ^= abb_mask[from].p[2];
384 u1 ^= abb_mask[from].p[1];
386 bb_chk = abb_w_knight_attacks[sq_wk];
388 idirec = (int)adirec[sq_wk][from];
389 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
391 add_behind_attacks( &bb_chk, idirec, sq_wk );
394 BBAnd( bb_chk, bb_chk, abb_b_knight_attacks[from] );
395 BBAnd( bb_chk, bb_chk, bb_move_to );
397 while( BBTest( bb_chk ) )
399 to = LastOne( bb_chk );
401 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(knight)
402 | Cap2Move(-BOARD[to]);
407 bb_piece = BB_BLANCE;
408 while( BBTest( bb_piece ) )
410 from = LastOne( bb_piece );
411 Xor( from, bb_piece );
413 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
414 bb_chk.p[1] = bb_chk.p[2] = 0;
416 idirec = (int)adirec[sq_wk][from];
417 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
419 add_behind_attacks( &bb_chk, idirec, sq_wk );
422 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
423 BBAnd( bb_chk, bb_chk, abb_minus_rays[from] );
424 BBAnd( bb_chk, bb_chk, bb_move_to );
426 while( BBTest( bb_chk ) )
428 to = LastOne( bb_chk );
430 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(lance)
431 | Cap2Move(-BOARD[to]) | FLAG_PROMO;
440 from = last_one12( u1, u2 );
441 u1 ^= abb_mask[from].p[1];
442 u2 ^= abb_mask[from].p[2];
444 bb_chk = bb_file_chk;
445 idirec = (int)adirec[sq_wk][from];
446 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
448 add_behind_attacks( &bb_chk, idirec, sq_wk );
449 BBAnd( bb_chk, bb_chk, abb_minus_rays[from] );
451 else { BBAnd( bb_chk, bb_file_chk, abb_plus_rays[sq_wk] );}
453 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
454 BBAnd( bb_chk, bb_chk, bb_move_to );
455 bb_chk.p[0] = bb_chk.p[0] & 0x1ffU;
457 while( BBTest( bb_chk ) )
459 to = LastOne( bb_chk );
461 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(lance)
462 | Cap2Move(-BOARD[to]);
467 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
468 if ( sq_wk < A2 ) { BBOr( bb_chk, bb_chk, abb_mask[sq_wk+nfile] ); }
469 BBAnd( bb_chk, bb_chk, bb_move_to );
470 BBAnd( bb_chk, bb_chk, BB_BPAWN_ATK );
472 BBAnd( bb_piece, bb_diag1_chk, BB_BPAWN );
473 while ( BBTest(bb_piece) )
475 from = LastOne( bb_piece );
476 Xor( from, bb_piece );
479 if ( BOARD[to] > 0 ) { continue; }
481 bb_desti = AttackDiag1( from );
482 if ( BBContract( bb_desti, BB_B_BH ) )
484 BBNotAnd( bb_chk, bb_chk, abb_mask[to] );
486 *pmove = To2Move(to) | From2Move(from)
487 | Piece2Move(pawn) | Cap2Move(-BOARD[to]);
488 if ( from < A5 ) { *pmove |= FLAG_PROMO; }
493 BBAnd( bb_piece, bb_diag2_chk, BB_BPAWN );
494 while ( BBTest(bb_piece) )
496 from = LastOne( bb_piece );
497 Xor( from, bb_piece );
500 if ( BOARD[to] > 0 ) { continue; }
502 bb_desti = AttackDiag2( from );
503 if ( BBContract( bb_desti, BB_B_BH ) )
505 BBNotAnd( bb_chk, bb_chk, abb_mask[to] );
507 *pmove = To2Move(to) | From2Move(from)
508 | Piece2Move(pawn) | Cap2Move(-BOARD[to]);
509 if ( from < A5 ) { *pmove |= FLAG_PROMO; }
514 BBAnd( bb_piece, bb_rank_chk, BB_BPAWN );
515 while ( BBTest(bb_piece) )
517 from = LastOne( bb_piece );
518 Xor( from, bb_piece );
521 if ( BOARD[to] > 0 ) { continue; }
523 bb_desti = AttackRank( from );
524 if ( BBContract( bb_desti, BB_B_RD ) )
526 BBNotAnd( bb_chk, bb_chk, abb_mask[to] );
528 *pmove = To2Move(to) | From2Move(from)
529 | Piece2Move(pawn) | Cap2Move(-BOARD[to]);
530 if ( from < A5 ) { *pmove |= FLAG_PROMO; }
535 while ( BBTest(bb_chk) )
537 to = LastOne( bb_chk );
541 *pmove = To2Move(to) | From2Move(from)
542 | Piece2Move(pawn) | Cap2Move(-BOARD[to]);
543 if ( from < A5 ) { *pmove |= FLAG_PROMO; }
548 if ( IsHandGold(HAND_B) )
550 BBAnd( bb_chk, bb_drop_to, abb_w_gold_attacks[sq_wk] );
551 while( BBTest( bb_chk ) )
553 to = LastOne( bb_chk );
555 *pmove++ = To2Move(to) | Drop2Move(gold);
560 if ( IsHandSilver(HAND_B) )
562 BBAnd( bb_chk, bb_drop_to, abb_w_silver_attacks[sq_wk] );
563 while( BBTest( bb_chk ) )
565 to = LastOne( bb_chk );
567 *pmove++ = To2Move(to) | Drop2Move(silver);
572 if ( IsHandKnight(HAND_B) && sq_wk < A2 )
574 to = sq_wk + 2*nfile - 1;
575 if ( aifile[sq_wk] != file1 && BOARD[to] == empty )
577 *pmove++ = To2Move(to) | Drop2Move(knight);
580 to = sq_wk + 2*nfile + 1;
581 if ( aifile[sq_wk] != file9 && BOARD[to] == empty )
583 *pmove++ = To2Move(to) | Drop2Move(knight);
588 if ( IsHandPawn(HAND_B)
590 && ! ( BBToU(BB_BPAWN) & ( mask_file1 >> aifile[sq_wk] ) ) )
593 if ( BOARD[to] == empty && ! is_mate_b_pawn_drop( __ptree__, to ) )
595 *pmove++ = To2Move(to) | Drop2Move(pawn);
600 if ( IsHandLance(HAND_B) )
605 if ( (int)aifile[sq_wk] == file1
606 || (int)aifile[sq_wk] == file9 ) { min_dist = 2; }
607 else { min_dist = 3; }
609 for ( to = sq_wk+nfile, dist = 1; to < nsquare && BOARD[to] == empty;
610 to += nfile, dist += 1 )
612 move = To2Move(to) | Drop2Move(lance);
613 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
614 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
620 if ( IsHandRook(HAND_B) )
623 int file, dist, min_dist;
625 if ( (int)aifile[sq_wk] == file1
626 || (int)aifile[sq_wk] == file9 ) { min_dist = 2; }
627 else { min_dist = 3; }
629 for ( to = sq_wk+nfile, dist = 1; to < nsquare && BOARD[to] == empty;
630 to += nfile, dist += 1 )
632 move = To2Move(to) | Drop2Move(rook);
633 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
634 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
638 for ( file = (int)aifile[sq_wk]-1, to = sq_wk-1, dist = 1;
639 file >= file1 && BOARD[to] == empty;
640 file -= 1, to -= 1, dist += 1 )
642 move = To2Move(to) | Drop2Move(rook);
643 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
644 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
648 if ( sq_wk < A8 || I2 < sq_wk ) { min_dist = 2; }
649 else { min_dist = 3; }
651 for ( file = (int)aifile[sq_wk]+1, to = sq_wk+1, dist = 1;
652 file <= file9 && BOARD[to] == empty;
653 file += 1, to += 1, dist += 1 )
655 move = To2Move(to) | Drop2Move(rook);
656 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
657 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
661 for ( to = sq_wk-nfile, dist = 1; to >= 0 && BOARD[to] == empty;
662 to -= nfile, dist += 1 )
664 move = To2Move(to) | Drop2Move(rook);
665 if ( (int)airank[to] == rank3 ) { move |= MOVE_CHK_CLEAR; }
666 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
667 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
673 if ( IsHandBishop(HAND_B) )
676 int file, rank, dist;
679 file = (int)aifile[sq_wk];
680 rank = (int)airank[sq_wk];
681 for ( to -= 10, file -= 1, rank -= 1, dist = 1;
682 file >= 0 && rank >= 0 && BOARD[to] == empty;
683 to -= 10, file -= 1, rank -= 1, dist += 1 )
685 move = To2Move(to) | Drop2Move(bishop);
686 if ( rank == rank3 ) { move |= MOVE_CHK_CLEAR; }
687 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
688 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
693 file = (int)aifile[sq_wk];
694 rank = (int)airank[sq_wk];
695 for ( to -= 8, file += 1, rank -= 1, dist = 1;
696 file <= file9 && rank >= 0 && BOARD[to] == empty;
697 to -= 8, file += 1, rank -= 1, dist += 1 )
699 move = To2Move(to) | Drop2Move(bishop);
700 if ( rank == rank3 ) { move |= MOVE_CHK_CLEAR; }
701 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
702 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
707 file = (int)aifile[sq_wk];
708 rank = (int)airank[sq_wk];
709 for ( to += 8, file -= 1, rank += 1, dist = 1;
710 file >= 0 && rank <= rank9 && BOARD[to] == empty;
711 to += 8, file -= 1, rank += 1, dist += 1 )
713 move = To2Move(to) | Drop2Move(bishop);
714 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
715 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
720 file = (int)aifile[sq_wk];
721 rank = (int)airank[sq_wk];
722 for ( to += 10, file += 1, rank += 1, dist = 1;
723 file <= file9 && rank <= rank9 && BOARD[to] == empty;
724 to += 10, file += 1, rank += 1, dist += 1 )
726 move = To2Move(to) | Drop2Move(bishop);
727 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
728 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
739 w_gen_checks( tree_t * restrict __ptree__, unsigned int * restrict pmove )
741 bitboard_t bb_piece, bb_rook_chk, bb_bishop_chk, bb_chk, bb_move_to;
742 bitboard_t bb_diag1_chk, bb_diag2_chk, bb_file_chk, bb_drop_to, bb_desti;
743 bitboard_t bb_rank_chk;
744 const tree_t * restrict ptree = __ptree__;
745 unsigned int u0, u1, u2;
746 int from, to, sq_bk, idirec;
749 bb_file_chk = AttackFile( sq_bk );
750 bb_rank_chk = AttackRank( sq_bk );
751 BBOr( bb_rook_chk, bb_file_chk, bb_rank_chk );
753 bb_diag1_chk = AttackDiag1( sq_bk );
754 bb_diag2_chk = AttackDiag2( sq_bk );
755 BBOr( bb_bishop_chk, bb_diag1_chk, bb_diag2_chk );
756 BBNot( bb_move_to, BB_WOCCUPY );
757 BBOr( bb_drop_to, BB_BOCCUPY, BB_WOCCUPY );
758 BBNot( bb_drop_to, bb_drop_to );
762 idirec = (int)adirec[sq_bk][from];
763 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
766 add_behind_attacks( &bb_chk, idirec, sq_bk );
767 BBAnd( bb_chk, bb_chk, abb_king_attacks[from] );
768 BBAnd( bb_chk, bb_chk, bb_move_to );
770 while( BBTest( bb_chk ) )
772 to = FirstOne( bb_chk );
774 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(king)
775 | Cap2Move(BOARD[to]);
780 bb_piece = BB_WDRAGON;
781 while( BBTest( bb_piece ) )
783 from = FirstOne( bb_piece );
784 Xor( from, bb_piece );
786 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_bk] );
787 idirec = (int)adirec[sq_bk][from];
788 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
790 add_behind_attacks( &bb_chk, idirec, sq_bk );
793 AttackDragon( bb_desti, from );
794 BBAnd( bb_chk, bb_chk, bb_desti );
795 BBAnd( bb_chk, bb_chk, bb_move_to );
797 while( BBTest( bb_chk ) )
799 to = LastOne( bb_chk );
801 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(dragon)
802 | Cap2Move(BOARD[to]);
807 bb_piece = BB_WHORSE;
808 while( BBTest( bb_piece ) )
810 from = FirstOne( bb_piece );
811 Xor( from, bb_piece );
813 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_bk] );
814 idirec = (int)adirec[sq_bk][from];
815 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
817 add_behind_attacks( &bb_chk, idirec, sq_bk );
820 AttackHorse( bb_desti, from );
821 BBAnd( bb_chk, bb_chk, bb_desti );
822 BBAnd( bb_chk, bb_chk, bb_move_to );
824 while( BBTest( bb_chk ) )
826 to = FirstOne( bb_chk );
828 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(horse)
829 | Cap2Move(BOARD[to]);
837 from = first_one01( u0, u1 );
838 u0 ^= abb_mask[from].p[0];
839 u1 ^= abb_mask[from].p[1];
841 AttackRook( bb_desti, from );
843 idirec = (int)adirec[sq_bk][from];
844 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
846 BBAnd( bb_chk, bb_desti, bb_move_to );
849 bb_chk = bb_rook_chk;
850 bb_chk.p[2] |= abb_king_attacks[sq_bk].p[2];
851 BBAnd( bb_chk, bb_chk, bb_desti );
852 BBAnd( bb_chk, bb_chk, bb_move_to );
855 while ( bb_chk.p[2] )
857 to = first_one2( bb_chk.p[2] );
858 bb_chk.p[2] ^= abb_mask[to].p[2];
859 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(rook)
860 | Cap2Move(BOARD[to]) | FLAG_PROMO;
863 while( bb_chk.p[0] | bb_chk.p[1] )
865 to = first_one01( bb_chk.p[0], bb_chk.p[1] );
866 bb_chk.p[0] ^= abb_mask[to].p[0];
867 bb_chk.p[1] ^= abb_mask[to].p[1];
868 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(rook)
869 | Cap2Move(BOARD[to]);
876 from = first_one2( u2 );
877 u2 ^= abb_mask[from].p[2];
879 AttackRook( bb_desti, from );
881 idirec = (int)adirec[sq_bk][from];
882 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
884 BBAnd( bb_chk, bb_desti, bb_move_to );
887 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_bk] );
888 BBAnd( bb_chk, bb_chk, bb_desti );
889 BBAnd( bb_chk, bb_chk, bb_move_to );
892 while( BBTest( bb_chk ) )
894 to = FirstOne( bb_chk );
896 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(rook)
897 | Cap2Move(BOARD[to]) | FLAG_PROMO;
901 u0 = BB_WBISHOP.p[0];
902 u1 = BB_WBISHOP.p[1];
905 from = first_one01( u0, u1 );
906 u0 ^= abb_mask[from].p[0];
907 u1 ^= abb_mask[from].p[1];
909 AttackBishop( bb_desti, from );
911 idirec = (int)adirec[sq_bk][from];
912 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
914 BBAnd( bb_chk, bb_desti, bb_move_to );
917 bb_chk = bb_bishop_chk;
918 bb_chk.p[2] |= abb_king_attacks[sq_bk].p[2];
919 BBAnd( bb_chk, bb_chk, bb_desti );
920 BBAnd( bb_chk, bb_chk, bb_move_to );
923 while ( bb_chk.p[2] )
925 to = first_one2( bb_chk.p[2] );
926 bb_chk.p[2] ^= abb_mask[to].p[2];
927 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(bishop)
928 | Cap2Move(BOARD[to]) | FLAG_PROMO;
931 while( bb_chk.p[0] | bb_chk.p[1] )
933 to = first_one01( bb_chk.p[0], bb_chk.p[1] );
934 bb_chk.p[0] ^= abb_mask[to].p[0];
935 bb_chk.p[1] ^= abb_mask[to].p[1];
936 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(bishop)
937 | Cap2Move(BOARD[to]);
941 u2 = BB_WBISHOP.p[2];
944 from = first_one2( u2 );
945 u2 ^= abb_mask[from].p[2];
947 AttackBishop( bb_desti, from );
949 idirec = (int)adirec[sq_bk][from];
950 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
952 BBAnd( bb_chk, bb_desti, bb_move_to );
955 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_bk] );
956 BBAnd( bb_chk, bb_chk, bb_desti );
957 BBAnd( bb_chk, bb_chk, bb_move_to );
960 while( BBTest( bb_chk ) )
962 to = FirstOne( bb_chk );
964 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(bishop)
965 | Cap2Move(BOARD[to]) | FLAG_PROMO;
970 bb_piece = BB_WTGOLD;
971 while( BBTest( bb_piece ) )
973 from = FirstOne( bb_piece );
974 Xor( from, bb_piece );
976 bb_chk = abb_b_gold_attacks[sq_bk];
978 idirec = (int)adirec[sq_bk][from];
979 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
981 add_behind_attacks( &bb_chk, idirec, sq_bk );
984 BBAnd( bb_chk, bb_chk, abb_w_gold_attacks[from] );
985 BBAnd( bb_chk, bb_chk, bb_move_to );
987 while( BBTest( bb_chk ) )
989 to = FirstOne( bb_chk );
991 *pmove++ = ( To2Move(to) | From2Move(from)
992 | Piece2Move(-BOARD[from])
993 | Cap2Move(BOARD[to]) );
998 u2 = BB_WSILVER.p[2];
1001 from = first_one2( u2 );
1002 u2 ^= abb_mask[from].p[2];
1004 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
1005 bb_chk.p[1] = abb_b_gold_attacks[sq_bk].p[1];
1008 idirec = (int)adirec[sq_bk][from];
1009 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1011 add_behind_attacks( &bb_chk, idirec, sq_bk );
1014 bb_chk.p[2] &= bb_move_to.p[2] & abb_w_silver_attacks[from].p[2];
1015 bb_chk.p[1] &= bb_move_to.p[1] & abb_w_silver_attacks[from].p[1];
1017 while( bb_chk.p[2] | bb_chk.p[1] )
1019 to = first_one12( bb_chk.p[1], bb_chk.p[2] );
1020 bb_chk.p[1] ^= abb_mask[to].p[1];
1021 bb_chk.p[2] ^= abb_mask[to].p[2];
1022 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(silver)
1023 | Cap2Move(BOARD[to]) | FLAG_PROMO;
1028 u1 = BB_WSILVER.p[1] & 0x1ffU;
1031 from = first_one1( u1 );
1032 u1 ^= abb_mask[from].p[1];
1034 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
1035 bb_chk.p[1] = bb_chk.p[0] = 0;
1037 idirec = (int)adirec[sq_bk][from];
1038 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1040 add_behind_attacks( &bb_chk, idirec, sq_bk );
1043 bb_chk.p[2] &= bb_move_to.p[2] & abb_w_silver_attacks[from].p[2];
1044 while ( bb_chk.p[2] )
1046 to = first_one2( bb_chk.p[2] );
1047 bb_chk.p[2] ^= abb_mask[to].p[2];
1048 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(silver)
1049 | Cap2Move(BOARD[to]) | FLAG_PROMO;
1054 bb_piece = BB_WSILVER;
1055 while( BBTest( bb_piece ) )
1057 from = FirstOne( bb_piece );
1058 Xor( from, bb_piece );
1060 bb_chk = abb_b_silver_attacks[sq_bk];
1062 idirec = (int)adirec[sq_bk][from];
1063 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1065 add_behind_attacks( &bb_chk, idirec, sq_bk );
1068 BBAnd( bb_chk, bb_chk, abb_w_silver_attacks[from] );
1069 BBAnd( bb_chk, bb_chk, bb_move_to );
1071 while( BBTest( bb_chk ) )
1073 to = FirstOne( bb_chk );
1075 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(silver)
1076 | Cap2Move(BOARD[to]);
1081 u2 = BB_WKNIGHT.p[2];
1082 u1 = BB_WKNIGHT.p[1] & 0x3ffffU;
1085 from = first_one12( u1, u2 );
1086 u2 ^= abb_mask[from].p[2];
1087 u1 ^= abb_mask[from].p[1];
1089 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
1090 bb_chk.p[1] = bb_chk.p[0] = 0;
1092 idirec = (int)adirec[sq_bk][from];
1093 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1095 add_behind_attacks( &bb_chk, idirec, sq_bk );
1098 bb_chk.p[2] &= abb_w_knight_attacks[from].p[2] & bb_move_to.p[2];
1100 while( bb_chk.p[2] )
1102 to = first_one2( bb_chk.p[2] );
1103 bb_chk.p[2] ^= abb_mask[to].p[2];
1104 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(knight)
1105 | Cap2Move(BOARD[to]) | FLAG_PROMO;
1110 u0 = BB_WKNIGHT.p[0];
1111 u1 = BB_WKNIGHT.p[1] & 0x7fffe00U;
1114 from = first_one01( u0, u1 );
1115 u0 ^= abb_mask[from].p[0];
1116 u1 ^= abb_mask[from].p[1];
1118 bb_chk = abb_b_knight_attacks[sq_bk];
1120 idirec = (int)adirec[sq_bk][from];
1121 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1123 add_behind_attacks( &bb_chk, idirec, sq_bk );
1126 BBAnd( bb_chk, bb_chk, abb_w_knight_attacks[from] );
1127 BBAnd( bb_chk, bb_chk, bb_move_to );
1129 while( BBTest( bb_chk ) )
1131 to = FirstOne( bb_chk );
1133 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(knight)
1134 | Cap2Move(BOARD[to]);
1139 bb_piece = BB_WLANCE;
1140 while( BBTest( bb_piece ) )
1142 from = FirstOne( bb_piece );
1143 Xor( from, bb_piece );
1145 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
1146 bb_chk.p[1] = bb_chk.p[0] = 0;
1148 idirec = (int)adirec[sq_bk][from];
1149 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1151 add_behind_attacks( &bb_chk, idirec, sq_bk );
1154 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
1155 BBAnd( bb_chk, bb_chk, abb_plus_rays[from] );
1156 BBAnd( bb_chk, bb_chk, bb_move_to );
1158 while( BBTest( bb_chk ) )
1160 to = FirstOne( bb_chk );
1162 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(lance)
1163 | Cap2Move(BOARD[to]) | FLAG_PROMO;
1168 u0 = BB_WLANCE.p[0];
1169 u1 = BB_WLANCE.p[1];
1172 from = first_one01( u0, u1 );
1173 u0 ^= abb_mask[from].p[0];
1174 u1 ^= abb_mask[from].p[1];
1176 bb_chk = bb_file_chk;
1177 idirec = (int)adirec[sq_bk][from];
1178 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
1180 add_behind_attacks( &bb_chk, idirec, sq_bk );
1181 BBAnd( bb_chk, bb_chk, abb_plus_rays[from] );
1183 else { BBAnd( bb_chk, bb_file_chk, abb_minus_rays[sq_bk] ); }
1185 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
1186 BBAnd( bb_chk, bb_chk, bb_move_to );
1187 bb_chk.p[2] = bb_chk.p[2] & 0x7fc0000U;
1189 while( BBTest( bb_chk ) )
1191 to = FirstOne( bb_chk );
1193 *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(lance)
1194 | Cap2Move(BOARD[to]);
1199 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
1200 if ( sq_bk > I8 ) { BBOr( bb_chk, bb_chk, abb_mask[sq_bk-nfile] ); }
1201 BBAnd( bb_chk, bb_chk, bb_move_to );
1202 BBAnd( bb_chk, bb_chk, BB_WPAWN_ATK );
1204 BBAnd( bb_piece, bb_diag1_chk, BB_WPAWN );
1205 while ( BBTest(bb_piece) )
1207 from = FirstOne( bb_piece );
1208 Xor( from, bb_piece );
1211 if ( BOARD[to] < 0 ) { continue; }
1213 bb_desti = AttackDiag1( from );
1214 if ( BBContract( bb_desti, BB_W_BH ) )
1216 BBNotAnd( bb_chk, bb_chk, abb_mask[to] );
1218 *pmove = To2Move(to) | From2Move(from)
1219 | Piece2Move(pawn) | Cap2Move(BOARD[to]);
1220 if ( from > I5 ) { *pmove |= FLAG_PROMO; }
1225 BBAnd( bb_piece, bb_diag2_chk, BB_WPAWN );
1226 while ( BBTest(bb_piece) )
1228 from = FirstOne( bb_piece );
1229 Xor( from, bb_piece );
1232 if ( BOARD[to] < 0 ) { continue; }
1234 bb_desti = AttackDiag2( from );
1235 if ( BBContract( bb_desti, BB_W_BH ) )
1237 BBNotAnd( bb_chk, bb_chk, abb_mask[to] );
1239 *pmove = To2Move(to) | From2Move(from)
1240 | Piece2Move(pawn) | Cap2Move(BOARD[to]);
1241 if ( from > I5 ) { *pmove |= FLAG_PROMO; }
1246 BBAnd( bb_piece, bb_rank_chk, BB_WPAWN );
1247 while ( BBTest(bb_piece) )
1249 from = FirstOne( bb_piece );
1250 Xor( from, bb_piece );
1253 if ( BOARD[to] < 0 ) { continue; }
1255 bb_desti = AttackRank( from );
1256 if ( BBContract( bb_desti, BB_W_RD ) )
1258 BBNotAnd( bb_chk, bb_chk, abb_mask[to] );
1260 *pmove = To2Move(to) | From2Move(from)
1261 | Piece2Move(pawn) | Cap2Move(BOARD[to]);
1262 if ( from > I5 ) { *pmove |= FLAG_PROMO; }
1267 while ( BBTest(bb_chk) )
1269 to = FirstOne( bb_chk );
1273 *pmove = To2Move(to) | From2Move(from) | Piece2Move(pawn)
1274 | Cap2Move(BOARD[to]);
1275 if ( from > I5 ) { *pmove |= FLAG_PROMO; }
1280 if ( IsHandGold(HAND_W) )
1282 BBAnd( bb_chk, bb_drop_to, abb_b_gold_attacks[sq_bk] );
1283 while( BBTest( bb_chk ) )
1285 to = FirstOne( bb_chk );
1287 *pmove++ = To2Move(to) | Drop2Move(gold);
1292 if ( IsHandSilver(HAND_W) )
1294 BBAnd( bb_chk, bb_drop_to, abb_b_silver_attacks[sq_bk] );
1295 while( BBTest( bb_chk ) )
1297 to = FirstOne( bb_chk );
1299 *pmove++ = To2Move(to) | Drop2Move(silver);
1304 if ( IsHandKnight(HAND_W) && sq_bk > I8 )
1306 to = sq_bk - 2*nfile - 1;
1307 if ( aifile[sq_bk] != file1 && BOARD[to] == empty )
1309 *pmove++ = To2Move(to) | Drop2Move(knight);
1312 to = sq_bk - 2*nfile + 1;
1313 if ( aifile[sq_bk] != file9 && BOARD[to] == empty )
1315 *pmove++ = To2Move(to) | Drop2Move(knight);
1320 if ( IsHandPawn(HAND_W)
1322 && ! ( BBToU(BB_WPAWN) & ( mask_file1 >> aifile[sq_bk] ) ) )
1325 if ( BOARD[to] == empty && ! is_mate_w_pawn_drop( __ptree__, to ) )
1327 *pmove++ = To2Move(to) | Drop2Move(pawn);
1332 if ( IsHandLance(HAND_W) )
1337 if ( (int)aifile[sq_bk] == file1
1338 || (int)aifile[sq_bk] == file9 ) { min_dist = 2; }
1339 else { min_dist = 3; }
1341 for ( to = sq_bk-nfile, dist = 1; to >= 0 && BOARD[to] == empty;
1342 to -= nfile, dist += 1 )
1344 move = To2Move(to) | Drop2Move(lance);
1345 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1346 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
1352 if ( IsHandRook(HAND_W) )
1355 int file, dist, min_dist;
1357 if ( (int)aifile[sq_bk] == file1
1358 || (int)aifile[sq_bk] == file9 ) { min_dist = 2; }
1359 else { min_dist = 3; }
1361 for ( to = sq_bk-nfile, dist = 1; to >= 0 && BOARD[to] == empty;
1362 to -= nfile, dist += 1 )
1364 move = To2Move(to) | Drop2Move(rook);
1365 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1366 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
1370 for ( to = sq_bk+nfile, dist = 1; to < nsquare && BOARD[to] == empty;
1371 to += nfile, dist += 1 )
1373 move = To2Move(to) | Drop2Move(rook);
1374 if ( (int)airank[to] == rank7 ) { move |= MOVE_CHK_CLEAR; }
1375 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1376 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
1381 if ( sq_bk < A8 || I2 < sq_bk ) { min_dist = 2; }
1382 else { min_dist = 3; }
1384 for ( file = (int)aifile[sq_bk]+1, to = sq_bk+1, dist = 1;
1385 file <= file9 && BOARD[to] == empty;
1386 file += 1, to += 1, dist += 1 )
1388 move = To2Move(to) | Drop2Move(rook);
1389 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1390 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
1394 for ( file = (int)aifile[sq_bk]-1, to = sq_bk-1, dist = 1;
1395 file >= file1 && BOARD[to] == empty;
1396 file -= 1, to -= 1, dist += 1 )
1398 move = To2Move(to) | Drop2Move(rook);
1399 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1400 else if ( dist > min_dist ) { move |= MOVE_CHK_SET; }
1406 if ( IsHandBishop(HAND_W) )
1409 int file, rank, dist;
1412 file = (int)aifile[sq_bk];
1413 rank = (int)airank[sq_bk];
1414 for ( to += 10, file += 1, rank += 1, dist = 1;
1415 file <= file9 && rank <= rank9 && BOARD[to] == empty;
1416 to += 10, file += 1, rank += 1, dist += 1 )
1418 move = To2Move(to) | Drop2Move(bishop);
1419 if ( rank == rank7 ) { move |= MOVE_CHK_CLEAR; }
1420 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1421 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
1426 file = (int)aifile[sq_bk];
1427 rank = (int)airank[sq_bk];
1428 for ( to += 8, file -= 1, rank += 1, dist = 1;
1429 file >= 0 && rank <= rank9 && BOARD[to] == empty;
1430 to += 8, file -= 1, rank += 1, dist += 1 )
1432 move = To2Move(to) | Drop2Move(bishop);
1433 if ( rank == rank7 ) { move |= MOVE_CHK_CLEAR; }
1434 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1435 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
1440 file = (int)aifile[sq_bk];
1441 rank = (int)airank[sq_bk];
1442 for ( to -= 8, file += 1, rank -= 1, dist = 1;
1443 file <= file9 && rank >= 0 && BOARD[to] == empty;
1444 to -= 8, file += 1, rank -= 1, dist += 1 )
1446 move = To2Move(to) | Drop2Move(bishop);
1447 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1448 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
1453 file = (int)aifile[sq_bk];
1454 rank = (int)airank[sq_bk];
1455 for ( to -= 10, file -= 1, rank -= 1, dist = 1;
1456 file >= 0 && rank >= 0 && BOARD[to] == empty;
1457 to -= 10, file -= 1, rank -= 1, dist += 1 )
1459 move = To2Move(to) | Drop2Move(bishop);
1460 if ( dist == 1 ) { move |= MOVE_CHK_CLEAR; }
1461 else if ( dist > 2 ) { move |= MOVE_CHK_SET; }
1471 int CONV b_have_checks( tree_t * restrict __ptree__ )
1473 bitboard_t bb_piece, bb_rook_chk, bb_bishop_chk, bb_chk, bb_move_to;
1474 bitboard_t bb_diag1_chk, bb_diag2_chk, bb_file_chk, bb_drop_to, bb_desti;
1475 bitboard_t bb_rank_chk;
1476 const tree_t * restrict ptree = __ptree__;
1477 unsigned int u0, u1, u2;
1478 int from, to, sq_wk, idirec;
1481 BBOr( bb_drop_to, BB_BOCCUPY, BB_WOCCUPY );
1482 BBNot( bb_drop_to, bb_drop_to );
1484 if ( IsHandGold(HAND_B) )
1486 BBAnd( bb_chk, bb_drop_to, abb_w_gold_attacks[sq_wk] );
1487 if ( BBTest( bb_chk ) ) { return 1; }
1490 if ( IsHandSilver(HAND_B) )
1492 BBAnd( bb_chk, bb_drop_to, abb_w_silver_attacks[sq_wk] );
1493 if ( BBTest( bb_chk ) ) { return 1; }
1496 if ( IsHandKnight(HAND_B) && sq_wk < A2 )
1498 if ( aifile[sq_wk] != file1
1499 && BOARD[sq_wk + 2*nfile - 1] == empty ) { return 1; }
1501 if ( aifile[sq_wk] != file9
1502 && BOARD[sq_wk + 2*nfile + 1] == empty ) { return 1; }
1505 if ( IsHandLance(HAND_B)
1506 && sq_wk + nfile < nsquare
1507 && BOARD[sq_wk + nfile] == empty ) { return 1; }
1509 if ( IsHandRook(HAND_B) )
1511 if ( sq_wk + nfile < nsquare
1512 && BOARD[sq_wk + nfile] == empty ) { return 1; }
1514 if ( file1 < (int)aifile[sq_wk]
1515 && BOARD[sq_wk - 1] == empty ) { return 1; }
1517 if ( (int)aifile[sq_wk] < file9
1518 && BOARD[sq_wk + 1] == empty ) { return 1; }
1520 if ( 0 <= sq_wk - nfile
1521 && BOARD[sq_wk - nfile] == empty ) { return 1; }
1524 if ( IsHandBishop(HAND_B) )
1526 if ( 0 < (int)aifile[sq_wk]
1527 && 0 < (int)airank[sq_wk]
1528 && BOARD[sq_wk - 10] == empty ) { return 1; }
1530 if ( (int)aifile[sq_wk] < file9
1531 && 0 < (int)airank[sq_wk]
1532 && BOARD[sq_wk - 8] == empty ) { return 1; }
1534 if ( 0 < (int)aifile[sq_wk]
1535 && (int)airank[sq_wk] < rank9
1536 && BOARD[sq_wk + 8] == empty ) { return 1; }
1538 if ( (int)aifile[sq_wk] < file9
1539 && (int)airank[sq_wk] < rank9
1540 && BOARD[sq_wk + 10] == empty ) { return 1; }
1543 if ( IsHandPawn(HAND_B)
1545 && BOARD[sq_wk+nfile] == empty
1546 && ! ( BBToU(BB_BPAWN) & ( mask_file1 >> aifile[sq_wk] ) )
1547 && ! is_mate_b_pawn_drop( __ptree__, sq_wk+nfile ) )
1553 bb_file_chk = AttackFile( sq_wk );
1554 bb_rank_chk = AttackRank( sq_wk );
1555 BBOr( bb_rook_chk, bb_file_chk, bb_rank_chk );
1557 bb_diag1_chk = AttackDiag1( sq_wk );
1558 bb_diag2_chk = AttackDiag2( sq_wk );
1559 BBOr( bb_bishop_chk, bb_diag1_chk, bb_diag2_chk );
1560 BBNot( bb_move_to, BB_BOCCUPY );
1563 idirec = (int)adirec[sq_wk][from];
1564 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1567 add_behind_attacks( &bb_chk, idirec, sq_wk );
1568 BBAnd( bb_chk, bb_chk, abb_king_attacks[from] );
1569 BBAnd( bb_chk, bb_chk, bb_move_to );
1571 if ( BBTest( bb_chk ) ) { return 1; }
1575 bb_piece = BB_BDRAGON;
1576 while( BBTest( bb_piece ) )
1578 from = LastOne( bb_piece );
1579 Xor( from, bb_piece );
1581 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_wk] );
1582 idirec = (int)adirec[sq_wk][from];
1583 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1585 add_behind_attacks( &bb_chk, idirec, sq_wk );
1588 AttackDragon( bb_desti, from );
1589 BBAnd( bb_chk, bb_chk, bb_desti );
1590 BBAnd( bb_chk, bb_chk, bb_move_to );
1592 if ( BBTest( bb_chk ) ) { return 1; }
1595 bb_piece = BB_BHORSE;
1596 while( BBTest( bb_piece ) )
1598 from = LastOne( bb_piece );
1599 Xor( from, bb_piece );
1601 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_wk] );
1602 idirec = (int)adirec[sq_wk][from];
1603 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1605 add_behind_attacks( &bb_chk, idirec, sq_wk );
1608 AttackHorse( bb_desti, from );
1609 BBAnd( bb_chk, bb_chk, bb_desti );
1610 BBAnd( bb_chk, bb_chk, bb_move_to );
1612 if ( BBTest( bb_chk ) ) { return 1; }
1619 from = last_one12( u1, u2 );
1620 u1 ^= abb_mask[from].p[1];
1621 u2 ^= abb_mask[from].p[2];
1623 AttackRook( bb_desti, from );
1625 idirec = (int)adirec[sq_wk][from];
1626 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1628 BBAnd( bb_chk, bb_desti, bb_move_to );
1631 bb_chk = bb_rook_chk;
1632 bb_chk.p[0] |= abb_king_attacks[sq_wk].p[0];
1633 BBAnd( bb_chk, bb_chk, bb_desti );
1634 BBAnd( bb_chk, bb_chk, bb_move_to );
1637 if ( BBTest( bb_chk ) ) { return 1; }
1643 from = last_one0( u0 );
1644 u0 ^= abb_mask[from].p[0];
1646 AttackRook( bb_desti, from );
1648 idirec = (int)adirec[sq_wk][from];
1649 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1651 BBAnd( bb_chk, bb_desti, bb_move_to );
1654 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_wk] );
1655 BBAnd( bb_chk, bb_chk, bb_desti );
1656 BBAnd( bb_chk, bb_chk, bb_move_to );
1659 if ( BBTest( bb_chk ) ) { return 1; }
1662 u1 = BB_BBISHOP.p[1];
1663 u2 = BB_BBISHOP.p[2];
1666 from = last_one12( u1, u2 );
1667 u1 ^= abb_mask[from].p[1];
1668 u2 ^= abb_mask[from].p[2];
1670 AttackBishop( bb_desti, from );
1672 idirec = (int)adirec[sq_wk][from];
1673 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1675 BBAnd( bb_chk, bb_desti, bb_move_to );
1678 bb_chk = bb_bishop_chk;
1679 bb_chk.p[0] |= abb_king_attacks[sq_wk].p[0];
1680 BBAnd( bb_chk, bb_chk, bb_desti );
1681 BBAnd( bb_chk, bb_chk, bb_move_to );
1684 if ( BBTest( bb_chk ) ) { return 1; }
1687 u0 = BB_BBISHOP.p[0];
1690 from = last_one0( u0 );
1691 u0 ^= abb_mask[from].p[0];
1693 AttackBishop( bb_desti, from );
1695 idirec = (int)adirec[sq_wk][from];
1696 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1698 BBAnd( bb_chk, bb_desti, bb_move_to );
1701 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_wk] );
1702 BBAnd( bb_chk, bb_chk, bb_desti );
1703 BBAnd( bb_chk, bb_chk, bb_move_to );
1706 if ( BBTest( bb_chk ) ) { return 1; }
1710 bb_piece = BB_BTGOLD;
1711 while( BBTest( bb_piece ) )
1713 from = LastOne( bb_piece );
1714 Xor( from, bb_piece );
1716 bb_chk = abb_w_gold_attacks[sq_wk];
1718 idirec = (int)adirec[sq_wk][from];
1719 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1721 add_behind_attacks( &bb_chk, idirec, sq_wk );
1724 BBAnd( bb_chk, bb_chk, abb_b_gold_attacks[from] );
1725 BBAnd( bb_chk, bb_chk, bb_move_to );
1727 if ( BBTest( bb_chk ) ) { return 1; }
1731 u0 = BB_BSILVER.p[0];
1734 from = last_one0( u0 );
1735 u0 ^= abb_mask[from].p[0];
1737 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
1738 bb_chk.p[1] = abb_w_gold_attacks[sq_wk].p[1];
1741 idirec = (int)adirec[sq_wk][from];
1742 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1744 add_behind_attacks( &bb_chk, idirec, sq_wk );
1747 bb_chk.p[0] &= bb_move_to.p[0] & abb_b_silver_attacks[from].p[0];
1748 bb_chk.p[1] &= bb_move_to.p[1] & abb_b_silver_attacks[from].p[1];
1750 if ( bb_chk.p[0] | bb_chk.p[1] ) { return 1; }
1754 u1 = BB_BSILVER.p[1] & 0x7fc0000U;
1757 from = last_one1( u1 );
1758 u1 ^= abb_mask[from].p[1];
1760 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
1761 bb_chk.p[1] = bb_chk.p[2] = 0;
1763 idirec = (int)adirec[sq_wk][from];
1764 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1766 add_behind_attacks( &bb_chk, idirec, sq_wk );
1769 bb_chk.p[0] &= bb_move_to.p[0] & abb_b_silver_attacks[from].p[0];
1771 if ( bb_chk.p[0] ) { return 1; }
1775 bb_piece = BB_BSILVER;
1776 while( BBTest( bb_piece ) )
1778 from = LastOne( bb_piece );
1779 Xor( from, bb_piece );
1781 bb_chk = abb_w_silver_attacks[sq_wk];
1783 idirec = (int)adirec[sq_wk][from];
1784 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1786 add_behind_attacks( &bb_chk, idirec, sq_wk );
1789 BBAnd( bb_chk, bb_chk, abb_b_silver_attacks[from] );
1790 BBAnd( bb_chk, bb_chk, bb_move_to );
1792 if ( BBTest( bb_chk ) ) { return 1; }
1796 u0 = BB_BKNIGHT.p[0];
1797 u1 = BB_BKNIGHT.p[1] & 0x7fffe00U;
1800 from = last_one01( u0, u1 );
1801 u0 ^= abb_mask[from].p[0];
1802 u1 ^= abb_mask[from].p[1];
1804 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
1805 bb_chk.p[1] = bb_chk.p[2] = 0;
1807 idirec = (int)adirec[sq_wk][from];
1808 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1810 add_behind_attacks( &bb_chk, idirec, sq_wk );
1813 bb_chk.p[0] &= abb_b_knight_attacks[from].p[0] & bb_move_to.p[0];
1815 if ( bb_chk.p[0] ) { return 1; }
1819 u2 = BB_BKNIGHT.p[2];
1820 u1 = BB_BKNIGHT.p[1] & 0x3ffffU;
1823 from = last_one12( u1, u2 );
1824 u2 ^= abb_mask[from].p[2];
1825 u1 ^= abb_mask[from].p[1];
1827 bb_chk = abb_w_knight_attacks[sq_wk];
1829 idirec = (int)adirec[sq_wk][from];
1830 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1832 add_behind_attacks( &bb_chk, idirec, sq_wk );
1835 BBAnd( bb_chk, bb_chk, abb_b_knight_attacks[from] );
1836 BBAnd( bb_chk, bb_chk, bb_move_to );
1838 if ( BBTest( bb_chk ) ) { return 1; }
1842 bb_piece = BB_BLANCE;
1843 while( BBTest( bb_piece ) )
1845 from = LastOne( bb_piece );
1846 Xor( from, bb_piece );
1848 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
1849 bb_chk.p[1] = bb_chk.p[2] = 0;
1851 idirec = (int)adirec[sq_wk][from];
1852 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1854 add_behind_attacks( &bb_chk, idirec, sq_wk );
1857 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
1858 BBAnd( bb_chk, bb_chk, abb_minus_rays[from] );
1859 BBAnd( bb_chk, bb_chk, bb_move_to );
1861 if ( BBTest( bb_chk ) ) { return 1; }
1865 u1 = BB_BLANCE.p[1];
1866 u2 = BB_BLANCE.p[2];
1869 from = last_one12( u1, u2 );
1870 u1 ^= abb_mask[from].p[1];
1871 u2 ^= abb_mask[from].p[2];
1873 bb_chk = bb_file_chk;
1874 idirec = (int)adirec[sq_wk][from];
1875 if ( idirec && is_pinned_on_white_king( ptree, from, idirec ) )
1877 add_behind_attacks( &bb_chk, idirec, sq_wk );
1878 BBAnd( bb_chk, bb_chk, abb_minus_rays[from] );
1880 else { BBAnd( bb_chk, bb_file_chk, abb_plus_rays[sq_wk] );}
1882 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
1883 BBAnd( bb_chk, bb_chk, bb_move_to );
1884 bb_chk.p[0] = bb_chk.p[0] & 0x1ffU;
1886 if ( BBTest( bb_chk ) ) { return 1; }
1890 bb_chk.p[0] = abb_w_gold_attacks[sq_wk].p[0];
1891 if ( sq_wk < A2 ) { BBOr( bb_chk, bb_chk, abb_mask[sq_wk+nfile] ); };
1892 BBAnd( bb_chk, bb_chk, bb_move_to );
1893 BBAnd( bb_chk, bb_chk, BB_BPAWN_ATK );
1894 if ( BBTest(bb_chk) ) { return 1; }
1896 BBAnd( bb_piece, bb_diag1_chk, BB_BPAWN );
1897 while ( BBTest(bb_piece) )
1899 from = LastOne( bb_piece );
1900 Xor( from, bb_piece );
1903 if ( BOARD[to] > 0 ) { continue; }
1905 bb_desti = AttackDiag1( from );
1907 if ( BBContract( bb_desti, BB_B_BH ) ) { return 1; }
1910 BBAnd( bb_piece, bb_diag2_chk, BB_BPAWN );
1911 while ( BBTest(bb_piece) )
1913 from = LastOne( bb_piece );
1914 Xor( from, bb_piece );
1917 if ( BOARD[to] > 0 ) { continue; }
1919 bb_desti = AttackDiag2( from );
1921 if ( BBContract( bb_desti, BB_B_BH ) ) { return 1; }
1924 BBAnd( bb_piece, bb_rank_chk, BB_BPAWN );
1925 while ( BBTest(bb_piece) )
1927 from = LastOne( bb_piece );
1928 Xor( from, bb_piece );
1931 if ( BOARD[to] > 0 ) { continue; }
1933 bb_desti = AttackRank( from );
1934 if ( BBContract( bb_desti, BB_B_RD ) ) { return 1; }
1941 int CONV w_have_checks( tree_t * restrict __ptree__ )
1943 bitboard_t bb_piece, bb_rook_chk, bb_bishop_chk, bb_chk, bb_move_to;
1944 bitboard_t bb_diag1_chk, bb_diag2_chk, bb_file_chk, bb_drop_to, bb_desti;
1945 bitboard_t bb_rank_chk;
1946 const tree_t * restrict ptree = __ptree__;
1947 unsigned int u0, u1, u2;
1948 int from, to, sq_bk, idirec;
1951 BBOr( bb_drop_to, BB_BOCCUPY, BB_WOCCUPY );
1952 BBNot( bb_drop_to, bb_drop_to );
1954 if ( IsHandGold(HAND_W) )
1956 BBAnd( bb_chk, bb_drop_to, abb_b_gold_attacks[sq_bk] );
1957 if ( BBTest( bb_chk ) ) { return 1; }
1960 if ( IsHandSilver(HAND_W) )
1962 BBAnd( bb_chk, bb_drop_to, abb_b_silver_attacks[sq_bk] );
1963 if ( BBTest( bb_chk ) ) { return 1; }
1966 if ( IsHandKnight(HAND_W) && sq_bk > I8 )
1968 if ( aifile[sq_bk] != file1
1969 && BOARD[sq_bk - 2*nfile - 1] == empty ) { return 1; }
1971 if ( aifile[sq_bk] != file9
1972 && BOARD[sq_bk - 2*nfile + 1] == empty ) { return 1; }
1975 if ( IsHandLance(HAND_W)
1976 && 0 <= sq_bk - nfile
1977 && BOARD[sq_bk - nfile] == empty ) { return 1; }
1979 if ( IsHandRook(HAND_W) )
1981 if ( sq_bk + nfile < nsquare
1982 && BOARD[sq_bk + nfile] == empty ) { return 1; }
1984 if ( file1 < (int)aifile[sq_bk]
1985 && BOARD[sq_bk - 1] == empty ) { return 1; }
1987 if ( (int)aifile[sq_bk] < file9
1988 && BOARD[sq_bk + 1] == empty ) { return 1; }
1990 if ( 0 <= sq_bk - nfile
1991 && BOARD[sq_bk - nfile] == empty ) { return 1; }
1994 if ( IsHandBishop(HAND_W) )
1996 if ( 0 < (int)aifile[sq_bk]
1997 && 0 < (int)airank[sq_bk]
1998 && BOARD[sq_bk - 10] == empty ) { return 1; }
2000 if ( (int)aifile[sq_bk] < file9
2001 && 0 < (int)airank[sq_bk]
2002 && BOARD[sq_bk - 8] == empty ) { return 1; }
2004 if ( 0 < (int)aifile[sq_bk]
2005 && (int)airank[sq_bk] < rank9
2006 && BOARD[sq_bk + 8] == empty ) { return 1; }
2008 if ( (int)aifile[sq_bk] < file9
2009 && (int)airank[sq_bk] < rank9
2010 && BOARD[sq_bk + 10] == empty ) { return 1; }
2013 if ( IsHandPawn(HAND_W)
2015 && BOARD[sq_bk - nfile] == empty
2016 && ! ( BBToU(BB_WPAWN) & ( mask_file1 >> aifile[sq_bk] ) )
2017 && ! is_mate_w_pawn_drop( __ptree__, sq_bk - nfile ) )
2023 bb_file_chk = AttackFile( sq_bk );
2024 bb_rank_chk = AttackRank( sq_bk );
2025 BBOr( bb_rook_chk, bb_file_chk, bb_rank_chk );
2027 bb_diag1_chk = AttackDiag1( sq_bk );
2028 bb_diag2_chk = AttackDiag2( sq_bk );
2029 BBOr( bb_bishop_chk, bb_diag1_chk, bb_diag2_chk );
2030 BBNot( bb_move_to, BB_WOCCUPY );
2034 idirec = (int)adirec[sq_bk][from];
2035 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2038 add_behind_attacks( &bb_chk, idirec, sq_bk );
2039 BBAnd( bb_chk, bb_chk, abb_king_attacks[from] );
2040 BBAnd( bb_chk, bb_chk, bb_move_to );
2042 if ( BBTest( bb_chk ) ) { return 1; }
2046 bb_piece = BB_WDRAGON;
2047 while( BBTest( bb_piece ) )
2049 from = FirstOne( bb_piece );
2050 Xor( from, bb_piece );
2052 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_bk] );
2053 idirec = (int)adirec[sq_bk][from];
2054 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2056 add_behind_attacks( &bb_chk, idirec, sq_bk );
2059 AttackDragon( bb_desti, from );
2060 BBAnd( bb_chk, bb_chk, bb_desti );
2061 BBAnd( bb_chk, bb_chk, bb_move_to );
2063 if ( BBTest( bb_chk ) ) { return 1; }
2067 bb_piece = BB_WHORSE;
2068 while( BBTest( bb_piece ) )
2070 from = FirstOne( bb_piece );
2071 Xor( from, bb_piece );
2073 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_bk] );
2074 idirec = (int)adirec[sq_bk][from];
2075 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2077 add_behind_attacks( &bb_chk, idirec, sq_bk );
2080 AttackHorse( bb_desti, from );
2081 BBAnd( bb_chk, bb_chk, bb_desti );
2082 BBAnd( bb_chk, bb_chk, bb_move_to );
2084 if ( BBTest( bb_chk ) ) { return 1; }
2091 from = first_one01( u0, u1 );
2092 u0 ^= abb_mask[from].p[0];
2093 u1 ^= abb_mask[from].p[1];
2095 AttackRook( bb_desti, from );
2097 idirec = (int)adirec[sq_bk][from];
2098 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2100 BBAnd( bb_chk, bb_desti, bb_move_to );
2103 bb_chk = bb_rook_chk;
2104 bb_chk.p[2] |= abb_king_attacks[sq_bk].p[2];
2105 BBAnd( bb_chk, bb_chk, bb_desti );
2106 BBAnd( bb_chk, bb_chk, bb_move_to );
2109 if ( BBTest( bb_chk ) ) { return 1; }
2115 from = first_one2( u2 );
2116 u2 ^= abb_mask[from].p[2];
2118 AttackRook( bb_desti, from );
2120 idirec = (int)adirec[sq_bk][from];
2121 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2123 BBAnd( bb_chk, bb_desti, bb_move_to );
2126 BBOr( bb_chk, bb_rook_chk, abb_king_attacks[sq_bk] );
2127 BBAnd( bb_chk, bb_chk, bb_desti );
2128 BBAnd( bb_chk, bb_chk, bb_move_to );
2131 if ( BBTest( bb_chk ) ) { return 1; }
2134 u0 = BB_WBISHOP.p[0];
2135 u1 = BB_WBISHOP.p[1];
2138 from = first_one01( u0, u1 );
2139 u0 ^= abb_mask[from].p[0];
2140 u1 ^= abb_mask[from].p[1];
2142 AttackBishop( bb_desti, from );
2144 idirec = (int)adirec[sq_bk][from];
2145 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2147 BBAnd( bb_chk, bb_desti, bb_move_to );
2150 bb_chk = bb_bishop_chk;
2151 bb_chk.p[2] |= abb_king_attacks[sq_bk].p[2];
2152 BBAnd( bb_chk, bb_chk, bb_desti );
2153 BBAnd( bb_chk, bb_chk, bb_move_to );
2156 if ( BBTest( bb_chk ) ) { return 1; }
2159 u2 = BB_WBISHOP.p[2];
2162 from = first_one2( u2 );
2163 u2 ^= abb_mask[from].p[2];
2165 AttackBishop( bb_desti, from );
2167 idirec = (int)adirec[sq_bk][from];
2168 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2170 BBAnd( bb_chk, bb_desti, bb_move_to );
2173 BBOr( bb_chk, bb_bishop_chk, abb_king_attacks[sq_bk] );
2174 BBAnd( bb_chk, bb_chk, bb_desti );
2175 BBAnd( bb_chk, bb_chk, bb_move_to );
2178 if ( BBTest( bb_chk ) ) { return 1; }
2182 bb_piece = BB_WTGOLD;
2183 while( BBTest( bb_piece ) )
2185 from = FirstOne( bb_piece );
2186 Xor( from, bb_piece );
2188 bb_chk = abb_b_gold_attacks[sq_bk];
2190 idirec = (int)adirec[sq_bk][from];
2191 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2193 add_behind_attacks( &bb_chk, idirec, sq_bk );
2196 BBAnd( bb_chk, bb_chk, abb_w_gold_attacks[from] );
2197 BBAnd( bb_chk, bb_chk, bb_move_to );
2199 if ( BBTest( bb_chk ) ) { return 1; }
2203 u2 = BB_WSILVER.p[2];
2206 from = first_one2( u2 );
2207 u2 ^= abb_mask[from].p[2];
2209 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
2210 bb_chk.p[1] = abb_b_gold_attacks[sq_bk].p[1];
2213 idirec = (int)adirec[sq_bk][from];
2214 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2216 add_behind_attacks( &bb_chk, idirec, sq_bk );
2219 bb_chk.p[2] &= bb_move_to.p[2] & abb_w_silver_attacks[from].p[2];
2220 bb_chk.p[1] &= bb_move_to.p[1] & abb_w_silver_attacks[from].p[1];
2222 if ( bb_chk.p[2] | bb_chk.p[1] ) { return 1; }
2226 u1 = BB_WSILVER.p[1] & 0x1ffU;
2229 from = first_one1( u1 );
2230 u1 ^= abb_mask[from].p[1];
2232 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
2233 bb_chk.p[1] = bb_chk.p[0] = 0;
2235 idirec = (int)adirec[sq_bk][from];
2236 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2238 add_behind_attacks( &bb_chk, idirec, sq_bk );
2241 bb_chk.p[2] &= bb_move_to.p[2] & abb_w_silver_attacks[from].p[2];
2243 if ( bb_chk.p[2] ) { return 1; }
2247 bb_piece = BB_WSILVER;
2248 while( BBTest( bb_piece ) )
2250 from = FirstOne( bb_piece );
2251 Xor( from, bb_piece );
2253 bb_chk = abb_b_silver_attacks[sq_bk];
2255 idirec = (int)adirec[sq_bk][from];
2256 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2258 add_behind_attacks( &bb_chk, idirec, sq_bk );
2261 BBAnd( bb_chk, bb_chk, abb_w_silver_attacks[from] );
2262 BBAnd( bb_chk, bb_chk, bb_move_to );
2264 if ( BBTest( bb_chk ) ) { return 1; }
2268 u2 = BB_WKNIGHT.p[2];
2269 u1 = BB_WKNIGHT.p[1] & 0x3ffffU;
2272 from = first_one12( u1, u2 );
2273 u2 ^= abb_mask[from].p[2];
2274 u1 ^= abb_mask[from].p[1];
2276 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
2277 bb_chk.p[1] = bb_chk.p[0] = 0;
2279 idirec = (int)adirec[sq_bk][from];
2280 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2282 add_behind_attacks( &bb_chk, idirec, sq_bk );
2285 bb_chk.p[2] &= abb_w_knight_attacks[from].p[2] & bb_move_to.p[2];
2287 if ( bb_chk.p[2] ) { return 1; }
2291 u0 = BB_WKNIGHT.p[0];
2292 u1 = BB_WKNIGHT.p[1] & 0x7fffe00U;
2295 from = first_one01( u0, u1 );
2296 u0 ^= abb_mask[from].p[0];
2297 u1 ^= abb_mask[from].p[1];
2299 bb_chk = abb_b_knight_attacks[sq_bk];
2301 idirec = (int)adirec[sq_bk][from];
2302 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2304 add_behind_attacks( &bb_chk, idirec, sq_bk );
2307 BBAnd( bb_chk, bb_chk, abb_w_knight_attacks[from] );
2308 BBAnd( bb_chk, bb_chk, bb_move_to );
2310 if ( BBTest( bb_chk ) ) { return 1; }
2314 bb_piece = BB_WLANCE;
2315 while( BBTest( bb_piece ) )
2317 from = FirstOne( bb_piece );
2318 Xor( from, bb_piece );
2320 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
2321 bb_chk.p[1] = bb_chk.p[0] = 0;
2323 idirec = (int)adirec[sq_bk][from];
2324 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2326 add_behind_attacks( &bb_chk, idirec, sq_bk );
2329 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
2330 BBAnd( bb_chk, bb_chk, abb_plus_rays[from] );
2331 BBAnd( bb_chk, bb_chk, bb_move_to );
2333 if ( BBTest( bb_chk ) ) { return 1; }
2337 u0 = BB_WLANCE.p[0];
2338 u1 = BB_WLANCE.p[1];
2341 from = first_one01( u0, u1 );
2342 u0 ^= abb_mask[from].p[0];
2343 u1 ^= abb_mask[from].p[1];
2345 bb_chk = bb_file_chk;
2346 idirec = (int)adirec[sq_bk][from];
2347 if ( idirec && is_pinned_on_black_king( ptree, from, idirec ) )
2349 add_behind_attacks( &bb_chk, idirec, sq_bk );
2350 BBAnd( bb_chk, bb_chk, abb_plus_rays[from] );
2352 else { BBAnd( bb_chk, bb_file_chk, abb_minus_rays[sq_bk] ); }
2354 BBAnd( bb_chk, bb_chk, AttackFile( from ) );
2355 BBAnd( bb_chk, bb_chk, bb_move_to );
2356 bb_chk.p[2] = bb_chk.p[2] & 0x7fc0000U;
2358 if ( BBTest( bb_chk ) ) { return 1; }
2362 bb_chk.p[2] = abb_b_gold_attacks[sq_bk].p[2];
2363 if ( sq_bk > I8 ) { BBOr( bb_chk, bb_chk, abb_mask[sq_bk-nfile] ); };
2364 BBAnd( bb_chk, bb_chk, bb_move_to );
2365 BBAnd( bb_chk, bb_chk, BB_WPAWN_ATK );
2366 if ( BBTest( bb_chk ) ) { return 1; }
2368 BBAnd( bb_piece, bb_diag1_chk, BB_WPAWN );
2369 while ( BBTest(bb_piece) )
2371 from = FirstOne( bb_piece );
2372 Xor( from, bb_piece );
2375 if ( BOARD[to] < 0 ) { continue; }
2377 bb_desti = AttackDiag1( from );
2379 if ( BBContract( bb_desti, BB_W_BH ) ) { return 1; }
2382 BBAnd( bb_piece, bb_diag2_chk, BB_WPAWN );
2383 while ( BBTest(bb_piece) )
2385 from = FirstOne( bb_piece );
2386 Xor( from, bb_piece );
2389 if ( BOARD[to] < 0 ) { continue; }
2391 bb_desti = AttackDiag2( from );
2393 if ( BBContract( bb_desti, BB_W_BH ) ) { return 1; }
2396 BBAnd( bb_piece, bb_rank_chk, BB_WPAWN );
2397 while ( BBTest(bb_piece) )
2399 from = FirstOne( bb_piece );
2400 Xor( from, bb_piece );
2403 if ( BOARD[to] < 0 ) { continue; }
2405 bb_desti = AttackRank( from );
2406 if ( BBContract( bb_desti, BB_W_RD ) ) { return 1; }
2414 add_behind_attacks( bitboard_t * restrict pbb, int idirec, int ik )
2418 if ( idirec == direc_diag1 )
2420 bb_tmp = abb_bishop_attacks_rr45[ik][0];
2422 else if ( idirec == direc_diag2 )
2424 bb_tmp = abb_bishop_attacks_rl45[ik][0];
2426 else if ( idirec == direc_file )
2428 bb_tmp = abb_file_attacks[ik][0];
2431 assert( idirec == direc_rank );
2432 bb_tmp = abb_rank_attacks[ik][0];
2434 BBNot( bb_tmp, bb_tmp );
2435 BBOr( *pbb, *pbb, bb_tmp );