5 #define DebugOut { static int count = 0; \
6 if ( count++ < 16 ) { out_CSA_posi( ptree, stdout, 0 ); } }
8 static int CONV can_w_king_escape( tree_t * restrict ptree, int to,
9 const bitboard_t * restrict pbb );
10 static int CONV can_b_king_escape( tree_t * restrict ptree, int to,
11 const bitboard_t * restrict pbb );
12 static int CONV can_w_piece_capture( const tree_t * restrict ptree, int to );
13 static int CONV can_b_piece_capture( const tree_t * restrict ptree, int to );
17 is_b_mate_in_1ply( tree_t * restrict ptree )
19 bitboard_t bb, bb_temp, bb_check, bb_check_pro, bb_attacks, bb_drop, bb_move;
23 assert( ! is_black_attacked( ptree, SQ_BKING ) );
26 BBOr( bb_drop, BB_BOCCUPY, BB_WOCCUPY );
27 BBNot( bb_drop, bb_drop );
29 if ( IsHandRook(HAND_B) ) {
31 BBAnd( bb, abb_w_gold_attacks[SQ_WKING], abb_b_gold_attacks[SQ_WKING] );
32 BBAnd( bb, bb, bb_drop );
38 if ( ! is_white_attacked( ptree, to ) ) { continue; }
40 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[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] );
86 BBNotAnd( bb, bb_drop, bb );
87 BBAnd( bb, bb, abb_w_gold_attacks[SQ_WKING] );
89 else { BBAnd( bb, bb_drop, abb_w_gold_attacks[SQ_WKING] ); }
96 if ( ! is_white_attacked( ptree, to ) ) { continue; }
98 bb_attacks = abb_b_gold_attacks[to];
99 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
100 if ( can_w_piece_capture( ptree, to ) ) { continue; }
101 return To2Move(to) | Drop2Move(gold);
105 if ( IsHandSilver(HAND_B) ) {
107 if ( IsHandGold(HAND_B) )
109 if ( IsHandBishop(HAND_B) ) { goto b_silver_drop_end; }
111 abb_w_silver_attacks[SQ_WKING],
112 abb_w_gold_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 ( BBTest(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 ( ! BBTest(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 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0] );
182 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
184 else { AttackDragon( bb_attacks, to ); }
186 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
187 if ( IsDiscoverWK( from, to ) );
188 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
189 if ( IsDiscoverBK( from, to ) ) { continue; }
191 XorFile( from, OCCUPIED_FILE );
192 XorDiag2( from, OCCUPIED_DIAG2 );
193 XorDiag1( from, OCCUPIED_DIAG1 );
194 Xor( from, BB_BOCCUPY );
195 Xor( from, BB_B_RD );
196 Xor( from, BB_B_HDK );
197 return ( To2Move(to) | From2Move(from)
198 | Cap2Move(-BOARD[to]) | Piece2Move(dragon) );
199 } while ( BBTest(bb_check) );
201 XorFile( from, OCCUPIED_FILE );
202 XorDiag2( from, OCCUPIED_DIAG2 );
203 XorDiag1( from, OCCUPIED_DIAG1 );
204 Xor( from, BB_BOCCUPY );
205 Xor( from, BB_B_RD );
206 Xor( from, BB_B_HDK );
209 bb.p[0] = BB_BROOK.p[0];
211 from = last_one0( bb.p[0] );
212 bb.p[0] ^= abb_mask[from].p[0];
214 AttackRook( bb_attacks, from );
215 BBAnd( bb_check, bb_move, bb_attacks );
216 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
217 if ( ! BBTest(bb_check) ) { continue; }
219 BB_B_RD.p[0] ^= abb_mask[from].p[0];
220 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
221 XorFile( from, OCCUPIED_FILE );
222 XorDiag2( from, OCCUPIED_DIAG2 );
223 XorDiag1( from, OCCUPIED_DIAG1 );
226 to = FirstOne( bb_check );
229 if ( ! is_white_attacked( ptree, to ) ) { continue; }
231 if ( (int)adirec[SQ_WKING][to] & flag_cross )
233 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0] );
234 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
236 else { AttackDragon( bb_attacks, to ); }
238 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
239 if ( IsDiscoverWK( from, to ) );
240 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
241 if ( IsDiscoverBK( from, to ) ) { continue; }
243 XorFile( from, OCCUPIED_FILE );
244 XorDiag2( from, OCCUPIED_DIAG2 );
245 XorDiag1( from, OCCUPIED_DIAG1 );
246 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
247 BB_B_RD.p[0] ^= abb_mask[from].p[0];
248 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
249 | Cap2Move(-BOARD[to]) | Piece2Move(rook) );
250 } while ( BBTest(bb_check) );
252 XorFile( from, OCCUPIED_FILE );
253 XorDiag2( from, OCCUPIED_DIAG2 );
254 XorDiag1( from, OCCUPIED_DIAG1 );
255 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
256 BB_B_RD.p[0] ^= abb_mask[from].p[0];
259 bb.p[1] = BB_BROOK.p[1];
260 bb.p[2] = BB_BROOK.p[2];
261 while ( bb.p[1] | bb.p[2] ) {
262 from = first_one12( bb.p[1], bb.p[2] );
263 bb.p[1] ^= abb_mask[from].p[1];
264 bb.p[2] ^= abb_mask[from].p[2];
266 AttackRook( bb_attacks, from );
267 BBAnd( bb_check, bb_move, bb_attacks );
268 bb_check.p[0] &= abb_king_attacks[SQ_WKING].p[0];
269 bb_check.p[1] &= abb_b_gold_attacks[SQ_WKING].p[1];
270 bb_check.p[2] &= abb_b_gold_attacks[SQ_WKING].p[2];
271 bb_check.p[1] &= abb_w_gold_attacks[SQ_WKING].p[1];
272 bb_check.p[2] &= abb_w_gold_attacks[SQ_WKING].p[2];
273 if ( ! BBTest(bb_check) ) { continue; }
275 BB_B_RD.p[1] ^= abb_mask[from].p[1];
276 BB_B_RD.p[2] ^= abb_mask[from].p[2];
277 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
278 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
279 XorFile( from, OCCUPIED_FILE );
280 XorDiag2( from, OCCUPIED_DIAG2 );
281 XorDiag1( from, OCCUPIED_DIAG1 );
284 to = FirstOne( bb_check );
287 if ( ! is_white_attacked( ptree, to ) ) { continue; }
290 if ( (int)adirec[SQ_WKING][to] & flag_cross )
292 BBOr(bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0]);
293 bb_attacks.p[0] |= abb_king_attacks[to].p[0];
294 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
296 else { AttackDragon( bb_attacks, to ); }
299 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0] );
301 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
302 if ( IsDiscoverWK( from, to ) );
303 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
304 if ( IsDiscoverBK( from, to ) ) { continue; }
306 XorFile( from, OCCUPIED_FILE );
307 XorDiag2( from, OCCUPIED_DIAG2 );
308 XorDiag1( from, OCCUPIED_DIAG1 );
309 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
310 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
311 BB_B_RD.p[1] ^= abb_mask[from].p[1];
312 BB_B_RD.p[2] ^= abb_mask[from].p[2];
313 return ( To2Move(to) | From2Move(from)
314 | ( (to < A6) ? FLAG_PROMO : 0 )
315 | Cap2Move(-BOARD[to]) | Piece2Move(rook) );
316 } while ( BBTest(bb_check) );
318 XorFile( from, OCCUPIED_FILE );
319 XorDiag2( from, OCCUPIED_DIAG2 );
320 XorDiag1( from, OCCUPIED_DIAG1 );
321 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
322 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
323 BB_B_RD.p[1] ^= abb_mask[from].p[1];
324 BB_B_RD.p[2] ^= abb_mask[from].p[2];
328 while ( BBTest(bb) ) {
329 from = FirstOne( bb );
332 AttackHorse( bb_attacks, from );
333 BBAnd( bb_check, bb_move, bb_attacks );
334 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
335 if ( ! BBTest(bb_check) ) { continue; }
337 Xor( from, BB_B_HDK );
338 Xor( from, BB_B_BH );
339 Xor( from, BB_BOCCUPY );
340 XorFile( from, OCCUPIED_FILE );
341 XorDiag2( from, OCCUPIED_DIAG2 );
342 XorDiag1( from, OCCUPIED_DIAG1 );
345 to = FirstOne( bb_check );
348 if ( ! is_white_attacked( ptree, to ) ) { continue; }
350 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
351 abb_bishop_attacks_rl45[to][0] );
352 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
353 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
354 if ( IsDiscoverWK( from, to ) );
355 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
356 if ( IsDiscoverBK( from, to ) ) { continue; }
358 XorFile( from, OCCUPIED_FILE );
359 XorDiag2( from, OCCUPIED_DIAG2 );
360 XorDiag1( from, OCCUPIED_DIAG1 );
361 Xor( from, BB_BOCCUPY );
362 Xor( from, BB_B_BH );
363 Xor( from, BB_B_HDK );
364 return ( To2Move(to) | From2Move(from)
365 | Cap2Move(-BOARD[to]) | Piece2Move(horse) );
366 } while ( BBTest(bb_check) );
368 XorFile( from, OCCUPIED_FILE );
369 XorDiag2( from, OCCUPIED_DIAG2 );
370 XorDiag1( from, OCCUPIED_DIAG1 );
371 Xor( from, BB_BOCCUPY );
372 Xor( from, BB_B_BH );
373 Xor( from, BB_B_HDK );
376 bb.p[0] = BB_BBISHOP.p[0];
378 from = last_one0( bb.p[0] );
379 bb.p[0] ^= abb_mask[from].p[0];
381 AttackBishop( bb_attacks, from );
382 BBAnd( bb_check, bb_move, bb_attacks );
383 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
384 if ( ! BBTest(bb_check) ) { continue; }
386 BB_B_BH.p[0] ^= abb_mask[from].p[0];
387 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
388 XorFile( from, OCCUPIED_FILE );
389 XorDiag2( from, OCCUPIED_DIAG2 );
390 XorDiag1( from, OCCUPIED_DIAG1 );
393 to = FirstOne( bb_check );
396 if ( ! is_white_attacked( ptree, to ) ) { continue; }
398 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
399 abb_bishop_attacks_rl45[to][0] );
400 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
401 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
402 if ( IsDiscoverWK( from, to ) );
403 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
404 if ( IsDiscoverBK( from, to ) ) { continue; }
406 XorFile( from, OCCUPIED_FILE );
407 XorDiag2( from, OCCUPIED_DIAG2 );
408 XorDiag1( from, OCCUPIED_DIAG1 );
409 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
410 BB_B_BH.p[0] ^= abb_mask[from].p[0];
411 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
412 | Cap2Move(-BOARD[to]) | Piece2Move(bishop) );
413 } while ( BBTest(bb_check) );
415 XorFile( from, OCCUPIED_FILE );
416 XorDiag2( from, OCCUPIED_DIAG2 );
417 XorDiag1( from, OCCUPIED_DIAG1 );
418 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
419 BB_B_BH.p[0] ^= abb_mask[from].p[0];
422 bb.p[1] = BB_BBISHOP.p[1];
423 bb.p[2] = BB_BBISHOP.p[2];
424 while ( bb.p[1] | bb.p[2] ) {
425 from = first_one12( bb.p[1], bb.p[2] );
426 bb.p[1] ^= abb_mask[from].p[1];
427 bb.p[2] ^= abb_mask[from].p[2];
429 AttackBishop( bb_attacks, from );
430 BBAnd( bb_check, bb_move, bb_attacks );
431 bb_check.p[0] &= abb_king_attacks[SQ_WKING].p[0];
432 bb_check.p[1] &= abb_b_silver_attacks[SQ_WKING].p[1];
433 bb_check.p[2] &= abb_b_silver_attacks[SQ_WKING].p[2];
434 bb_check.p[1] &= abb_w_silver_attacks[SQ_WKING].p[1];
435 bb_check.p[2] &= abb_w_silver_attacks[SQ_WKING].p[2];
436 if ( ! BBTest(bb_check) ) { continue; }
438 BB_B_BH.p[1] ^= abb_mask[from].p[1];
439 BB_B_BH.p[2] ^= abb_mask[from].p[2];
440 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
441 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
442 XorFile( from, OCCUPIED_FILE );
443 XorDiag2( from, OCCUPIED_DIAG2 );
444 XorDiag1( from, OCCUPIED_DIAG1 );
447 to = FirstOne( bb_check );
450 if ( ! is_white_attacked( ptree, to ) ) { continue; }
452 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
453 abb_bishop_attacks_rl45[to][0] );
455 bb_attacks.p[0] |= abb_king_attacks[to].p[0];
456 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
458 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
459 if ( IsDiscoverWK( from, to ) );
460 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
461 if ( IsDiscoverBK( from, to ) ) { continue; }
463 XorFile( from, OCCUPIED_FILE );
464 XorDiag2( from, OCCUPIED_DIAG2 );
465 XorDiag1( from, OCCUPIED_DIAG1 );
466 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
467 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
468 BB_B_BH.p[1] ^= abb_mask[from].p[1];
469 BB_B_BH.p[2] ^= abb_mask[from].p[2];
470 return ( To2Move(to) | From2Move(from)
471 | ( (to < A6) ? FLAG_PROMO : 0 )
472 | Cap2Move(-BOARD[to]) | Piece2Move(bishop) );
473 } while ( BBTest(bb_check) );
475 XorFile( from, OCCUPIED_FILE );
476 XorDiag2( from, OCCUPIED_DIAG2 );
477 XorDiag1( from, OCCUPIED_DIAG1 );
478 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
479 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
480 BB_B_BH.p[1] ^= abb_mask[from].p[1];
481 BB_B_BH.p[2] ^= abb_mask[from].p[2];
484 BBAnd( bb, BB_BTGOLD, b_chk_tbl[SQ_WKING].gold );
485 while ( BBTest(bb) ) {
486 from = FirstOne( bb );
489 BBAnd( bb_check, bb_move, abb_b_gold_attacks[from] );
490 BBAnd( bb_check, bb_check, abb_w_gold_attacks[SQ_WKING] );
491 if ( ! BBTest(bb_check) ) { continue; }
493 Xor( from, BB_BTGOLD );
494 Xor( from, BB_BOCCUPY );
495 XorFile( from, OCCUPIED_FILE );
496 XorDiag2( from, OCCUPIED_DIAG2 );
497 XorDiag1( from, OCCUPIED_DIAG1 );
500 to = FirstOne( bb_check );
503 if ( ! is_white_attacked( ptree, to ) ) { continue; }
505 bb_attacks = abb_b_gold_attacks[to];
506 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
507 if ( IsDiscoverWK( from, to ) );
508 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
509 if ( IsDiscoverBK( from, to ) ) { continue; }
511 XorFile( from, OCCUPIED_FILE );
512 XorDiag2( from, OCCUPIED_DIAG2 );
513 XorDiag1( from, OCCUPIED_DIAG1 );
514 Xor( from, BB_BOCCUPY );
515 Xor( from, BB_BTGOLD );
516 return ( To2Move(to) | From2Move(from)
517 | Cap2Move(-BOARD[to]) | Piece2Move(BOARD[from]) );
518 } while ( BBTest(bb_check) );
520 XorFile( from, OCCUPIED_FILE );
521 XorDiag2( from, OCCUPIED_DIAG2 );
522 XorDiag1( from, OCCUPIED_DIAG1 );
523 Xor( from, BB_BOCCUPY );
524 Xor( from, BB_BTGOLD );
527 BBAnd( bb, BB_BSILVER, b_chk_tbl[SQ_WKING].silver );
529 from = last_one0( bb.p[0] );
530 bb.p[0] ^= abb_mask[from].p[0];
532 bb_check_pro.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
533 & abb_w_gold_attacks[SQ_WKING].p[0];
534 bb_check_pro.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
535 & abb_w_gold_attacks[SQ_WKING].p[1];
537 bb_check.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
538 & abb_w_silver_attacks[SQ_WKING].p[0]
539 & ~abb_w_gold_attacks[SQ_WKING].p[0];
540 bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
541 & abb_w_silver_attacks[SQ_WKING].p[1]
542 & ~abb_w_gold_attacks[SQ_WKING].p[1];
544 if ( ! ( bb_check_pro.p[0] | bb_check_pro.p[1]
545 | bb_check.p[0]| bb_check.p[1] ) ) { continue; }
547 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
548 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
549 XorFile( from, OCCUPIED_FILE );
550 XorDiag2( from, OCCUPIED_DIAG2 );
551 XorDiag1( from, OCCUPIED_DIAG1 );
553 while ( bb_check_pro.p[0] | bb_check_pro.p[1] ) {
554 to = first_one01( bb_check_pro.p[0], bb_check_pro.p[1] );
555 bb_check_pro.p[0] ^= abb_mask[to].p[0];
556 bb_check_pro.p[1] ^= abb_mask[to].p[1];
558 if ( ! is_white_attacked( ptree, to ) ) { continue; }
560 bb_attacks = abb_b_gold_attacks[to];
561 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
562 if ( IsDiscoverWK( from, to ) );
563 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
564 if ( IsDiscoverBK( from, to ) ) { continue; }
566 XorFile( from, OCCUPIED_FILE );
567 XorDiag2( from, OCCUPIED_DIAG2 );
568 XorDiag1( from, OCCUPIED_DIAG1 );
569 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
570 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
571 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
572 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
575 while ( bb_check.p[0] | bb_check.p[1] ) {
576 to = first_one01( bb_check.p[0], bb_check.p[1] );
577 bb_check.p[0] ^= abb_mask[to].p[0];
578 bb_check.p[1] ^= abb_mask[to].p[1];
580 if ( ! is_white_attacked( ptree, to ) ) { continue; }
582 bb_attacks = abb_b_silver_attacks[to];
583 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
584 if ( IsDiscoverWK( from, to ) );
585 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
586 if ( IsDiscoverBK( from, to ) ) { continue; }
588 XorFile( from, OCCUPIED_FILE );
589 XorDiag2( from, OCCUPIED_DIAG2 );
590 XorDiag1( from, OCCUPIED_DIAG1 );
591 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
592 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
593 return ( To2Move(to) | From2Move(from)
594 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
597 XorFile( from, OCCUPIED_FILE );
598 XorDiag2( from, OCCUPIED_DIAG2 );
599 XorDiag1( from, OCCUPIED_DIAG1 );
600 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
601 BB_BSILVER.p[0] ^= abb_mask[from].p[0];
604 ubb = bb.p[1] & 0x7fc0000U;
606 from = last_one1( ubb );
607 ubb ^= abb_mask[from].p[1];
609 bb_check_pro.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
610 & abb_w_gold_attacks[SQ_WKING].p[0];
612 bb_check.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
613 & abb_w_silver_attacks[SQ_WKING].p[0]
614 & ~abb_w_gold_attacks[SQ_WKING].p[0];
615 bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
616 & abb_w_silver_attacks[SQ_WKING].p[1];
618 if ( ! (bb_check_pro.p[0]|bb_check.p[0]|bb_check.p[1]) ) { continue; }
620 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
621 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
622 XorFile( from, OCCUPIED_FILE );
623 XorDiag2( from, OCCUPIED_DIAG2 );
624 XorDiag1( from, OCCUPIED_DIAG1 );
626 while ( bb_check_pro.p[0] ) {
627 to = last_one0( bb_check_pro.p[0] );
628 bb_check_pro.p[0] ^= abb_mask[to].p[0];
630 if ( ! is_white_attacked( ptree, to ) ) { continue; }
632 bb_attacks = abb_b_gold_attacks[to];
633 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
634 if ( IsDiscoverWK( from, to ) );
635 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
636 if ( IsDiscoverBK( from, to ) ) { continue; }
638 XorFile( from, OCCUPIED_FILE );
639 XorDiag2( from, OCCUPIED_DIAG2 );
640 XorDiag1( from, OCCUPIED_DIAG1 );
641 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
642 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
643 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
644 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
647 while ( bb_check.p[0] | bb_check.p[1] ) {
648 to = first_one01( bb_check.p[0], bb_check.p[1] );
649 bb_check.p[0] ^= abb_mask[to].p[0];
650 bb_check.p[1] ^= abb_mask[to].p[1];
652 if ( ! is_white_attacked( ptree, to ) ) { continue; }
654 bb_attacks = abb_b_silver_attacks[to];
655 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
656 if ( IsDiscoverWK( from, to ) );
657 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
658 if ( IsDiscoverBK( from, to ) ) { continue; }
660 XorFile( from, OCCUPIED_FILE );
661 XorDiag2( from, OCCUPIED_DIAG2 );
662 XorDiag1( from, OCCUPIED_DIAG1 );
663 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
664 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
665 return ( To2Move(to) | From2Move(from)
666 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
669 XorFile( from, OCCUPIED_FILE );
670 XorDiag2( from, OCCUPIED_DIAG2 );
671 XorDiag1( from, OCCUPIED_DIAG1 );
672 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
673 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
676 bb.p[1] &= 0x003ffffU;
677 while ( bb.p[1] | bb.p[2] ) {
678 from = first_one12( bb.p[1], bb.p[2] );
679 bb.p[1] ^= abb_mask[from].p[1];
680 bb.p[2] ^= abb_mask[from].p[2];
682 bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
683 & abb_w_silver_attacks[SQ_WKING].p[1];
684 bb_check.p[2] = bb_move.p[2] & abb_b_silver_attacks[from].p[2]
685 & abb_w_silver_attacks[SQ_WKING].p[2];
686 if ( ! ( bb_check.p[1] | bb_check.p[2] ) ) { continue; }
688 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
689 BB_BSILVER.p[2] ^= abb_mask[from].p[2];
690 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
691 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
692 XorFile( from, OCCUPIED_FILE );
693 XorDiag2( from, OCCUPIED_DIAG2 );
694 XorDiag1( from, OCCUPIED_DIAG1 );
697 to = first_one12( bb_check.p[1], bb_check.p[2] );
698 bb_check.p[1] ^= abb_mask[to].p[1];
699 bb_check.p[2] ^= abb_mask[to].p[2];
701 if ( ! is_white_attacked( ptree, to ) ) { continue; }
703 bb_attacks = abb_b_silver_attacks[to];
704 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
705 if ( IsDiscoverWK( from, to ) );
706 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
707 if ( IsDiscoverBK( from, to ) ) { continue; }
709 XorFile( from, OCCUPIED_FILE );
710 XorDiag2( from, OCCUPIED_DIAG2 );
711 XorDiag1( from, OCCUPIED_DIAG1 );
712 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
713 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
714 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
715 BB_BSILVER.p[2] ^= abb_mask[from].p[2];
716 return ( To2Move(to) | From2Move(from)
717 | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
718 } while ( bb_check.p[1] | bb_check.p[2] );
720 XorFile( from, OCCUPIED_FILE );
721 XorDiag2( from, OCCUPIED_DIAG2 );
722 XorDiag1( from, OCCUPIED_DIAG1 );
723 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
724 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
725 BB_BSILVER.p[1] ^= abb_mask[from].p[1];
726 BB_BSILVER.p[2] ^= abb_mask[from].p[2];
729 BBAnd( bb, BB_BKNIGHT, b_chk_tbl[SQ_WKING].knight );
730 while ( BBTest(bb) ) {
731 from = FirstOne( bb );
734 bb_check.p[0] = bb_move.p[0] & abb_b_knight_attacks[from].p[0]
735 & abb_w_gold_attacks[SQ_WKING].p[0];
737 if ( bb_check.p[0] ) {
738 BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
739 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
740 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
741 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
742 XorFile( from, OCCUPIED_FILE );
743 XorDiag2( from, OCCUPIED_DIAG2 );
744 XorDiag1( from, OCCUPIED_DIAG1 );
747 to = last_one0( bb_check.p[0] );
748 bb_check.p[0] ^= abb_mask[to].p[0];
750 if ( ! is_white_attacked( ptree, to ) ) { continue; }
752 bb_attacks = abb_b_gold_attacks[to];
753 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
754 if ( IsDiscoverWK( from, to ) );
755 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
756 if ( IsDiscoverBK( from, to ) ) { continue; }
758 XorFile( from, OCCUPIED_FILE );
759 XorDiag2( from, OCCUPIED_DIAG2 );
760 XorDiag1( from, OCCUPIED_DIAG1 );
761 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
762 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
763 BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
764 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
765 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
766 | Cap2Move(-BOARD[to]) | Piece2Move(knight) );
767 } while ( bb_check.p[0] );
769 XorFile( from, OCCUPIED_FILE );
770 XorDiag2( from, OCCUPIED_DIAG2 );
771 XorDiag1( from, OCCUPIED_DIAG1 );
772 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
773 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
774 BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
775 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
778 BBAnd( bb_check, bb_move, abb_b_knight_attacks[from] );
779 BBAnd( bb_check, bb_check, abb_w_knight_attacks[SQ_WKING] );
781 if ( BBTest(bb_check) ) {
782 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
783 BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
784 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
785 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
786 XorFile( from, OCCUPIED_FILE );
787 XorDiag2( from, OCCUPIED_DIAG2 );
788 XorDiag1( from, OCCUPIED_DIAG1 );
791 to = FirstOne( bb_check );
795 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
796 if ( IsDiscoverWK( from, to ) );
797 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
798 if ( IsDiscoverBK( from, to ) ) { continue; }
800 XorFile( from, OCCUPIED_FILE );
801 XorDiag2( from, OCCUPIED_DIAG2 );
802 XorDiag1( from, OCCUPIED_DIAG1 );
803 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
804 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
805 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
806 BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
807 return ( To2Move(to) | From2Move(from)
808 | Cap2Move(-BOARD[to]) | Piece2Move(knight) );
809 } while ( BBTest(bb_check) );
811 XorFile( from, OCCUPIED_FILE );
812 XorDiag2( from, OCCUPIED_DIAG2 );
813 XorDiag1( from, OCCUPIED_DIAG1 );
814 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
815 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
816 BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
817 BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
822 BBAnd( bb, BB_BLANCE, b_chk_tbl[SQ_WKING].lance );
823 while ( BBTest(bb) ) {
824 from = FirstOne( bb );
827 bb_attacks = AttackFile(from);
828 BBAnd( bb_attacks, bb_attacks, abb_minus_rays[from] );
829 BBAnd( bb_attacks, bb_attacks, bb_move );
831 BBAnd( bb_check, bb_attacks, abb_mask[SQ_WKING+nfile] );
832 bb_check_pro.p[0] = bb_attacks.p[0] & abb_w_gold_attacks[SQ_WKING].p[0];
834 if ( ! ( bb_check_pro.p[0] | bb_check.p[0]
835 | bb_check.p[1] | bb_check.p[2] ) ) { continue; }
837 Xor( from, BB_BLANCE );
838 Xor( from, BB_BOCCUPY );
839 XorFile( from, OCCUPIED_FILE );
840 XorDiag2( from, OCCUPIED_DIAG2 );
841 XorDiag1( from, OCCUPIED_DIAG1 );
843 bb_check.p[0] &= 0x1ffU;
844 if ( BBTest(bb_check) ) {
847 if ( ! is_white_attacked( ptree, to ) ) {
848 bb_check.p[0] &= ~abb_mask[to].p[0];
851 bb_temp = abb_file_attacks[to][0];
852 if ( can_w_king_escape( ptree, to, &bb_temp ) ) { goto b_lance_next; }
853 if ( IsDiscoverWK( from, to ) );
854 else if ( can_w_piece_capture( ptree, to ) ) { goto b_lance_next; }
855 if ( IsDiscoverBK( from, to ) ) { goto b_lance_next; }
857 XorFile( from, OCCUPIED_FILE );
858 XorDiag2( from, OCCUPIED_DIAG2 );
859 XorDiag1( from, OCCUPIED_DIAG1 );
860 Xor( from, BB_BOCCUPY );
861 Xor( from, BB_BLANCE );
862 return ( To2Move(to) | From2Move(from)
863 | Cap2Move(-BOARD[to]) | Piece2Move(lance) );
867 while ( bb_check_pro.p[0] )
869 to = last_one0( bb_check_pro.p[0] );
870 bb_check_pro.p[0] ^= abb_mask[to].p[0];
872 if ( ! is_white_attacked( ptree, to ) ) { continue; }
874 bb_attacks = abb_b_gold_attacks[to];
875 if ( can_w_king_escape( ptree, to, &bb_attacks ) ) { continue; }
876 if ( IsDiscoverWK( from, to ) );
877 else if ( can_w_piece_capture( ptree, to ) ) { continue; }
878 if ( IsDiscoverBK( from, to ) ) { continue; }
880 XorFile( from, OCCUPIED_FILE );
881 XorDiag2( from, OCCUPIED_DIAG2 );
882 XorDiag1( from, OCCUPIED_DIAG1 );
883 Xor( from, BB_BOCCUPY );
884 Xor( from, BB_BLANCE );
885 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
886 | Cap2Move(-BOARD[to]) | Piece2Move(lance) );
889 XorFile( from, OCCUPIED_FILE );
890 XorDiag2( from, OCCUPIED_DIAG2 );
891 XorDiag1( from, OCCUPIED_DIAG1 );
892 Xor( from, BB_BOCCUPY );
893 Xor( from, BB_BLANCE );
896 bb_check.p[0] = bb_move.p[0] & BB_BPAWN_ATK.p[0]
897 & abb_w_gold_attacks[SQ_WKING].p[0];
898 while ( bb_check.p[0] ) {
899 to = last_one0( bb_check.p[0] );
901 bb_check.p[0] ^= abb_mask[to].p[0];
903 BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
904 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
905 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
906 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
907 XorFile( from, OCCUPIED_FILE );
908 XorDiag2( from, OCCUPIED_DIAG2 );
909 XorDiag1( from, OCCUPIED_DIAG1 );
911 if ( ! is_white_attacked( ptree, to ) ) { goto b_pawn_pro_next; }
912 bb_attacks = abb_b_gold_attacks[to];
913 if ( can_w_king_escape( ptree,to,&bb_attacks ) ) { goto b_pawn_pro_next; }
914 if ( IsDiscoverWK( from, to ) );
915 else if ( can_w_piece_capture( ptree, to ) ) { goto b_pawn_pro_next; }
916 if ( IsDiscoverBK( from, to ) ) { goto b_pawn_pro_next; }
918 XorFile( from, OCCUPIED_FILE );
919 XorDiag2( from, OCCUPIED_DIAG2 );
920 XorDiag1( from, OCCUPIED_DIAG1 );
921 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
922 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
923 BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
924 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
925 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
926 | Cap2Move(-BOARD[to]) | Piece2Move(pawn) );
929 XorFile( from, OCCUPIED_FILE );
930 XorDiag2( from, OCCUPIED_DIAG2 );
931 XorDiag1( from, OCCUPIED_DIAG1 );
932 BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
933 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
934 BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
935 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
938 if ( SQ_WKING >= A7 && SQ_WKING <= I3 ) {
939 to = SQ_WKING + nfile;
941 if ( BOARD[from] == pawn && BOARD[to] <= 0 ) {
943 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
944 BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
945 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
946 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
947 XorFile( from, OCCUPIED_FILE );
948 XorDiag2( from, OCCUPIED_DIAG2 );
949 XorDiag1( from, OCCUPIED_DIAG1 );
951 if ( ! is_white_attacked( ptree, to ) ) { goto b_pawn_end; }
953 if ( can_w_king_escape( ptree,to,&bb_attacks ) ) { goto b_pawn_end; }
954 if ( can_w_piece_capture( ptree, to ) ) { goto b_pawn_end; }
955 if ( IsDiscoverBK( from, to ) ) { goto b_pawn_end; }
957 XorFile( from, OCCUPIED_FILE );
958 XorDiag2( from, OCCUPIED_DIAG2 );
959 XorDiag1( from, OCCUPIED_DIAG1 );
960 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
961 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
962 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
963 BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
964 return ( To2Move(to) | From2Move(from)
965 | Cap2Move(-BOARD[to]) | Piece2Move(pawn) );
968 XorFile( from, OCCUPIED_FILE );
969 XorDiag2( from, OCCUPIED_DIAG2 );
970 XorDiag1( from, OCCUPIED_DIAG1 );
971 BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
972 BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
973 BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
974 BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
983 is_w_mate_in_1ply( tree_t * restrict ptree )
985 bitboard_t bb, bb_temp, bb_check, bb_check_pro, bb_attacks, bb_drop, bb_move;
987 int to, from, idirec;
989 assert( ! is_white_attacked( ptree, SQ_WKING ) );
992 BBOr( bb_drop, BB_BOCCUPY, BB_WOCCUPY );
993 BBNot( bb_drop, bb_drop );
995 if ( IsHandRook(HAND_W) ) {
997 BBAnd( bb, abb_w_gold_attacks[SQ_BKING],
998 abb_b_gold_attacks[SQ_BKING] );
999 BBAnd( bb, bb, bb_drop );
1005 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1007 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0] );
1008 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1009 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1010 return To2Move(to) | Drop2Move(rook);
1013 } else if ( IsHandLance(HAND_W) && SQ_BKING >= A8 ) {
1015 to = SQ_BKING-nfile;
1016 if ( ( ! BOARD[to] ) && is_black_attacked( ptree, to ) )
1018 bb_attacks = abb_file_attacks[to][0];
1019 if ( ( ! can_b_king_escape( ptree, to, &bb_attacks ) )
1020 && ( ! can_b_piece_capture( ptree, to ) ) )
1022 return To2Move(to) | Drop2Move(lance);
1027 if ( IsHandBishop(HAND_W) ) {
1029 BBAnd( bb, abb_w_silver_attacks[SQ_BKING],
1030 abb_b_silver_attacks[SQ_BKING] );
1031 BBAnd( bb, bb, bb_drop );
1037 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1039 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1040 abb_bishop_attacks_rl45[to][0] );
1041 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1042 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1043 return To2Move(to) | Drop2Move(bishop);
1047 if ( IsHandGold(HAND_W) ) {
1049 if ( IsHandRook(HAND_W) )
1051 BBAnd( bb, abb_w_gold_attacks[SQ_BKING],
1052 abb_w_silver_attacks[SQ_BKING] );
1053 BBNotAnd( bb, bb_drop, bb );
1054 BBAnd( bb, bb, abb_b_gold_attacks[SQ_BKING] );
1056 else { BBAnd( bb, bb_drop, abb_b_gold_attacks[SQ_BKING] ); }
1058 while ( BBTest(bb) )
1063 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1065 bb_attacks = abb_w_gold_attacks[to];
1066 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1067 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1068 return To2Move(to) | Drop2Move(gold);
1072 if ( IsHandSilver(HAND_W) ) {
1074 if ( IsHandGold(HAND_W) )
1076 if ( IsHandBishop(HAND_W) ) { goto w_silver_drop_end; }
1078 abb_b_silver_attacks[SQ_BKING],
1079 abb_b_gold_attacks[SQ_BKING] );
1080 BBAnd( bb, bb, bb_drop );
1083 BBAnd( bb, bb_drop, abb_b_silver_attacks[SQ_BKING] );
1084 if ( IsHandBishop(HAND_W) )
1086 BBAnd( bb, bb, abb_b_gold_attacks[SQ_BKING] );
1090 while ( BBTest(bb) )
1095 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1097 bb_attacks = abb_w_silver_attacks[to];
1098 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1099 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1100 return To2Move(to) | Drop2Move(silver);
1105 if ( IsHandKnight(HAND_W) ) {
1107 BBAnd( bb, bb_drop, abb_b_knight_attacks[SQ_BKING] );
1108 while ( BBTest(bb) )
1113 BBIni( bb_attacks );
1114 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1115 if ( can_b_piece_capture( ptree, to ) ) { continue; }
1116 return To2Move(to) | Drop2Move(knight);
1121 BBNot( bb_move, BB_WOCCUPY );
1124 while ( BBTest(bb) ) {
1125 from = LastOne( bb );
1128 AttackDragon( bb_attacks, from );
1129 BBAnd( bb_check, bb_move, bb_attacks );
1130 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1131 if ( ! BBTest(bb_check) ) { continue; }
1133 Xor( from, BB_W_HDK );
1134 Xor( from, BB_W_RD );
1135 Xor( from, BB_WOCCUPY );
1136 XorFile( from, OCCUPIED_FILE );
1137 XorDiag2( from, OCCUPIED_DIAG2 );
1138 XorDiag1( from, OCCUPIED_DIAG1 );
1141 to = LastOne( bb_check );
1142 Xor( to, bb_check );
1144 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1146 if ( (int)adirec[SQ_BKING][to] & flag_cross )
1148 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0] );
1149 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1151 else { AttackDragon( bb_attacks, to ); }
1153 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1154 if ( IsDiscoverBK( from, to ) );
1155 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1156 if ( IsDiscoverWK( from, to ) ) { continue; }
1158 XorFile( from, OCCUPIED_FILE );
1159 XorDiag2( from, OCCUPIED_DIAG2 );
1160 XorDiag1( from, OCCUPIED_DIAG1 );
1161 Xor( from, BB_WOCCUPY );
1162 Xor( from, BB_W_RD );
1163 Xor( from, BB_W_HDK );
1164 return ( To2Move(to) | From2Move(from)
1165 | Cap2Move(BOARD[to]) | Piece2Move(dragon) );
1166 } while ( BBTest(bb_check) );
1168 XorFile( from, OCCUPIED_FILE );
1169 XorDiag2( from, OCCUPIED_DIAG2 );
1170 XorDiag1( from, OCCUPIED_DIAG1 );
1171 Xor( from, BB_WOCCUPY );
1172 Xor( from, BB_W_RD );
1173 Xor( from, BB_W_HDK );
1176 bb.p[2] = BB_WROOK.p[2];
1178 from = first_one2( bb.p[2] );
1179 bb.p[2] ^= abb_mask[from].p[2];
1181 AttackRook( bb_attacks, from );
1182 BBAnd( bb_check, bb_move, bb_attacks );
1183 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1184 if ( ! BBTest(bb_check) ) { continue; }
1186 BB_W_RD.p[2] ^= abb_mask[from].p[2];
1187 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1188 XorFile( from, OCCUPIED_FILE );
1189 XorDiag2( from, OCCUPIED_DIAG2 );
1190 XorDiag1( from, OCCUPIED_DIAG1 );
1193 to = LastOne( bb_check );
1194 Xor( to, bb_check );
1196 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1198 if ( (int)adirec[SQ_BKING][to] & flag_cross )
1200 BBOr( bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0] );
1201 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1203 else { AttackDragon( bb_attacks, to ); }
1205 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1206 if ( IsDiscoverBK( from, to ) );
1207 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1208 if ( IsDiscoverWK( from, to ) ) { continue; }
1210 XorFile( from, OCCUPIED_FILE );
1211 XorDiag2( from, OCCUPIED_DIAG2 );
1212 XorDiag1( from, OCCUPIED_DIAG1 );
1213 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1214 BB_W_RD.p[2] ^= abb_mask[from].p[2];
1215 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1216 | Cap2Move(BOARD[to]) | Piece2Move(rook) );
1217 } while ( BBTest(bb_check) );
1219 XorFile( from, OCCUPIED_FILE );
1220 XorDiag2( from, OCCUPIED_DIAG2 );
1221 XorDiag1( from, OCCUPIED_DIAG1 );
1222 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1223 BB_W_RD.p[2] ^= abb_mask[from].p[2];
1226 bb.p[0] = BB_WROOK.p[0];
1227 bb.p[1] = BB_WROOK.p[1];
1228 while ( bb.p[0] | bb.p[1] ) {
1229 from = last_one01( bb.p[0], bb.p[1] );
1230 bb.p[0] ^= abb_mask[from].p[0];
1231 bb.p[1] ^= abb_mask[from].p[1];
1233 AttackRook( bb_attacks, from );
1234 BBAnd( bb_check, bb_move, bb_attacks );
1235 bb_check.p[0] &= abb_b_gold_attacks[SQ_BKING].p[0];
1236 bb_check.p[1] &= abb_b_gold_attacks[SQ_BKING].p[1];
1237 bb_check.p[0] &= abb_w_gold_attacks[SQ_BKING].p[0];
1238 bb_check.p[1] &= abb_w_gold_attacks[SQ_BKING].p[1];
1239 bb_check.p[2] &= abb_king_attacks[SQ_BKING].p[2];
1240 if ( ! BBTest(bb_check) ) { continue; }
1242 BB_W_RD.p[0] ^= abb_mask[from].p[0];
1243 BB_W_RD.p[1] ^= abb_mask[from].p[1];
1244 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1245 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1246 XorFile( from, OCCUPIED_FILE );
1247 XorDiag2( from, OCCUPIED_DIAG2 );
1248 XorDiag1( from, OCCUPIED_DIAG1 );
1251 to = LastOne( bb_check );
1252 Xor( to, bb_check );
1254 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1257 if ( (int)adirec[SQ_BKING][to] & flag_cross )
1259 BBOr(bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0]);
1260 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
1261 bb_attacks.p[2] |= abb_king_attacks[to].p[2];
1263 else { AttackDragon( bb_attacks, to ); }
1265 BBOr(bb_attacks, abb_file_attacks[to][0], abb_rank_attacks[to][0]);
1267 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1268 if ( IsDiscoverBK( from, to ) );
1269 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1270 if ( IsDiscoverWK( from, to ) ) { continue; }
1272 XorFile( from, OCCUPIED_FILE );
1273 XorDiag2( from, OCCUPIED_DIAG2 );
1274 XorDiag1( from, OCCUPIED_DIAG1 );
1275 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1276 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1277 BB_W_RD.p[0] ^= abb_mask[from].p[0];
1278 BB_W_RD.p[1] ^= abb_mask[from].p[1];
1279 return ( To2Move(to) | From2Move(from)
1280 | ( (to > I4) ? FLAG_PROMO : 0 )
1281 | Cap2Move(BOARD[to]) | Piece2Move(rook) );
1282 } while ( BBTest(bb_check) );
1284 XorFile( from, OCCUPIED_FILE );
1285 XorDiag2( from, OCCUPIED_DIAG2 );
1286 XorDiag1( from, OCCUPIED_DIAG1 );
1287 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1288 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1289 BB_W_RD.p[0] ^= abb_mask[from].p[0];
1290 BB_W_RD.p[1] ^= abb_mask[from].p[1];
1294 while ( BBTest(bb) ) {
1295 from = LastOne( bb );
1298 AttackHorse( bb_attacks, from );
1299 BBAnd( bb_check, bb_move, bb_attacks );
1300 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1301 if ( ! BBTest(bb_check) ) { continue; }
1303 Xor( from, BB_W_HDK );
1304 Xor( from, BB_W_BH );
1305 Xor( from, BB_WOCCUPY );
1306 XorFile( from, OCCUPIED_FILE );
1307 XorDiag2( from, OCCUPIED_DIAG2 );
1308 XorDiag1( from, OCCUPIED_DIAG1 );
1311 to = LastOne( bb_check );
1312 Xor( to, bb_check );
1314 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1316 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1317 abb_bishop_attacks_rl45[to][0] );
1318 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1319 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1320 if ( IsDiscoverBK( from, to ) );
1321 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1322 if ( IsDiscoverWK( from, to ) ) { continue; }
1324 XorFile( from, OCCUPIED_FILE );
1325 XorDiag2( from, OCCUPIED_DIAG2 );
1326 XorDiag1( from, OCCUPIED_DIAG1 );
1327 Xor( from, BB_WOCCUPY );
1328 Xor( from, BB_W_BH );
1329 Xor( from, BB_W_HDK );
1330 return ( To2Move(to) | From2Move(from)
1331 | Cap2Move(BOARD[to]) | Piece2Move(horse) );
1332 } while ( BBTest(bb_check) );
1334 XorFile( from, OCCUPIED_FILE );
1335 XorDiag2( from, OCCUPIED_DIAG2 );
1336 XorDiag1( from, OCCUPIED_DIAG1 );
1337 Xor( from, BB_WOCCUPY );
1338 Xor( from, BB_W_BH );
1339 Xor( from, BB_W_HDK );
1342 bb.p[2] = BB_WBISHOP.p[2];
1344 from = first_one2( bb.p[2] );
1345 bb.p[2] ^= abb_mask[from].p[2];
1347 AttackBishop( bb_attacks, from );
1348 BBAnd( bb_check, bb_move, bb_attacks );
1349 BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1350 if ( ! BBTest(bb_check) ) { continue; }
1352 BB_W_BH.p[2] ^= abb_mask[from].p[2];
1353 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1354 XorFile( from, OCCUPIED_FILE );
1355 XorDiag2( from, OCCUPIED_DIAG2 );
1356 XorDiag1( from, OCCUPIED_DIAG1 );
1359 to = LastOne( bb_check );
1360 Xor( to, bb_check );
1362 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1364 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1365 abb_bishop_attacks_rl45[to][0] );
1366 BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1367 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1368 if ( IsDiscoverBK( from, to ) );
1369 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1370 if ( IsDiscoverWK( from, to ) ) { continue; }
1372 XorFile( from, OCCUPIED_FILE );
1373 XorDiag2( from, OCCUPIED_DIAG2 );
1374 XorDiag1( from, OCCUPIED_DIAG1 );
1375 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1376 BB_W_BH.p[2] ^= abb_mask[from].p[2];
1377 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1378 | Cap2Move(BOARD[to]) | Piece2Move(bishop) );
1379 } while ( BBTest(bb_check) );
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];
1388 bb.p[0] = BB_WBISHOP.p[0];
1389 bb.p[1] = BB_WBISHOP.p[1];
1390 while ( bb.p[0] | bb.p[1] ) {
1391 from = last_one01( bb.p[0], bb.p[1] );
1392 bb.p[0] ^= abb_mask[from].p[0];
1393 bb.p[1] ^= abb_mask[from].p[1];
1395 AttackBishop( bb_attacks, from );
1396 BBAnd( bb_check, bb_move, bb_attacks );
1397 bb_check.p[0] &= abb_b_silver_attacks[SQ_BKING].p[0];
1398 bb_check.p[1] &= abb_b_silver_attacks[SQ_BKING].p[1];
1399 bb_check.p[0] &= abb_w_silver_attacks[SQ_BKING].p[0];
1400 bb_check.p[1] &= abb_w_silver_attacks[SQ_BKING].p[1];
1401 bb_check.p[2] &= abb_king_attacks[SQ_BKING].p[2];
1402 if ( ! BBTest(bb_check) ) { continue; }
1404 BB_W_BH.p[0] ^= abb_mask[from].p[0];
1405 BB_W_BH.p[1] ^= abb_mask[from].p[1];
1406 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1407 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1408 XorFile( from, OCCUPIED_FILE );
1409 XorDiag2( from, OCCUPIED_DIAG2 );
1410 XorDiag1( from, OCCUPIED_DIAG1 );
1413 to = LastOne( bb_check );
1414 Xor( to, bb_check );
1416 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1418 BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1419 abb_bishop_attacks_rl45[to][0] );
1421 bb_attacks.p[1] |= abb_king_attacks[to].p[1];
1422 bb_attacks.p[2] |= abb_king_attacks[to].p[2];
1424 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1425 if ( IsDiscoverBK( from, to ) );
1426 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1427 if ( IsDiscoverWK( from, to ) ) { continue; }
1429 XorFile( from, OCCUPIED_FILE );
1430 XorDiag2( from, OCCUPIED_DIAG2 );
1431 XorDiag1( from, OCCUPIED_DIAG1 );
1432 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1433 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1434 BB_W_BH.p[0] ^= abb_mask[from].p[0];
1435 BB_W_BH.p[1] ^= abb_mask[from].p[1];
1436 return ( To2Move(to) | From2Move(from)
1437 | ( (to > I4) ? FLAG_PROMO : 0 )
1438 | Cap2Move(BOARD[to]) | Piece2Move(bishop) );
1439 } while ( BBTest(bb_check) );
1441 XorFile( from, OCCUPIED_FILE );
1442 XorDiag2( from, OCCUPIED_DIAG2 );
1443 XorDiag1( from, OCCUPIED_DIAG1 );
1444 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1445 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1446 BB_W_BH.p[0] ^= abb_mask[from].p[0];
1447 BB_W_BH.p[1] ^= abb_mask[from].p[1];
1450 BBAnd( bb, BB_WTGOLD, w_chk_tbl[SQ_BKING].gold );
1451 while ( BBTest(bb) ) {
1452 from = LastOne( bb );
1455 BBAnd( bb_check, bb_move, abb_w_gold_attacks[from] );
1456 BBAnd( bb_check, bb_check, abb_b_gold_attacks[SQ_BKING] );
1457 if ( ! BBTest(bb_check) ) { continue; }
1459 Xor( from, BB_WTGOLD );
1460 Xor( from, BB_WOCCUPY );
1461 XorFile( from, OCCUPIED_FILE );
1462 XorDiag2( from, OCCUPIED_DIAG2 );
1463 XorDiag1( from, OCCUPIED_DIAG1 );
1466 to = LastOne( bb_check );
1467 Xor( to, bb_check );
1469 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1471 bb_attacks = abb_w_gold_attacks[to];
1472 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1473 if ( IsDiscoverBK( from, to ) );
1474 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1475 if ( IsDiscoverWK( from, to ) ) { continue; }
1477 XorFile( from, OCCUPIED_FILE );
1478 XorDiag2( from, OCCUPIED_DIAG2 );
1479 XorDiag1( from, OCCUPIED_DIAG1 );
1480 Xor( from, BB_WOCCUPY );
1481 Xor( from, BB_WTGOLD );
1482 return ( To2Move(to) | From2Move(from)
1483 | Cap2Move(BOARD[to]) | Piece2Move(-BOARD[from]) );
1484 } while ( BBTest(bb_check) );
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 );
1493 BBAnd( bb, BB_WSILVER, w_chk_tbl[SQ_BKING].silver );
1495 from = first_one2( bb.p[2] );
1496 bb.p[2] ^= abb_mask[from].p[2];
1498 bb_check_pro.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1499 & abb_b_gold_attacks[SQ_BKING].p[1];
1500 bb_check_pro.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1501 & abb_b_gold_attacks[SQ_BKING].p[2];
1503 bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1504 & abb_b_silver_attacks[SQ_BKING].p[1]
1505 & ~abb_b_gold_attacks[SQ_BKING].p[1];
1506 bb_check.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1507 & abb_b_silver_attacks[SQ_BKING].p[2]
1508 & ~abb_b_gold_attacks[SQ_BKING].p[2];
1510 if ( ! ( bb_check_pro.p[1] | bb_check_pro.p[2]
1511 | bb_check.p[1]| bb_check.p[2] ) ) { continue; }
1513 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1514 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1515 XorFile( from, OCCUPIED_FILE );
1516 XorDiag2( from, OCCUPIED_DIAG2 );
1517 XorDiag1( from, OCCUPIED_DIAG1 );
1519 while ( bb_check_pro.p[1] | bb_check_pro.p[2] ) {
1520 to = last_one12( bb_check_pro.p[1], bb_check_pro.p[2] );
1521 bb_check_pro.p[1] ^= abb_mask[to].p[1];
1522 bb_check_pro.p[2] ^= abb_mask[to].p[2];
1524 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1526 bb_attacks = abb_w_gold_attacks[to];
1527 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1528 if ( IsDiscoverBK( from, to ) );
1529 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1530 if ( IsDiscoverWK( from, to ) ) { continue; }
1532 XorFile( from, OCCUPIED_FILE );
1533 XorDiag2( from, OCCUPIED_DIAG2 );
1534 XorDiag1( from, OCCUPIED_DIAG1 );
1535 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1536 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1537 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1538 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1541 while ( bb_check.p[1] | bb_check.p[2] ) {
1542 to = last_one12( bb_check.p[1], bb_check.p[2] );
1543 bb_check.p[1] ^= abb_mask[to].p[1];
1544 bb_check.p[2] ^= abb_mask[to].p[2];
1546 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1548 bb_attacks = abb_w_silver_attacks[to];
1549 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1550 if ( IsDiscoverBK( from, to ) );
1551 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1552 if ( IsDiscoverWK( from, to ) ) { continue; }
1554 XorFile( from, OCCUPIED_FILE );
1555 XorDiag2( from, OCCUPIED_DIAG2 );
1556 XorDiag1( from, OCCUPIED_DIAG1 );
1557 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1558 BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1559 return ( To2Move(to) | From2Move(from)
1560 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
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];
1570 ubb = bb.p[1] & 0x1ffU;
1572 from = first_one1( ubb );
1573 ubb ^= abb_mask[from].p[1];
1575 bb_check_pro.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1576 & abb_b_gold_attacks[SQ_BKING].p[2];
1578 bb_check.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1579 & abb_b_silver_attacks[SQ_BKING].p[2]
1580 & ~abb_b_gold_attacks[SQ_BKING].p[2];
1581 bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1582 & abb_b_silver_attacks[SQ_BKING].p[1];
1584 if ( ! (bb_check_pro.p[2]|bb_check.p[2]|bb_check.p[1]) ) { continue; }
1586 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1587 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1588 XorFile( from, OCCUPIED_FILE );
1589 XorDiag2( from, OCCUPIED_DIAG2 );
1590 XorDiag1( from, OCCUPIED_DIAG1 );
1592 while ( bb_check_pro.p[2] ) {
1593 to = first_one2( bb_check_pro.p[2] );
1594 bb_check_pro.p[2] ^= abb_mask[to].p[2];
1596 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1598 bb_attacks = abb_w_gold_attacks[to];
1599 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1600 if ( IsDiscoverBK( from, to ) );
1601 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1602 if ( IsDiscoverWK( from, to ) ) { continue; }
1604 XorFile( from, OCCUPIED_FILE );
1605 XorDiag2( from, OCCUPIED_DIAG2 );
1606 XorDiag1( from, OCCUPIED_DIAG1 );
1607 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1608 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1609 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1610 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1613 while ( bb_check.p[1] | bb_check.p[2] ) {
1614 to = last_one12( bb_check.p[1], bb_check.p[2] );
1615 bb_check.p[1] ^= abb_mask[to].p[1];
1616 bb_check.p[2] ^= abb_mask[to].p[2];
1618 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1620 bb_attacks = abb_w_silver_attacks[to];
1621 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1622 if ( IsDiscoverBK( from, to ) );
1623 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1624 if ( IsDiscoverWK( from, to ) ) { continue; }
1626 XorFile( from, OCCUPIED_FILE );
1627 XorDiag2( from, OCCUPIED_DIAG2 );
1628 XorDiag1( from, OCCUPIED_DIAG1 );
1629 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1630 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1631 return ( To2Move(to) | From2Move(from)
1632 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
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];
1643 bb.p[1] = bb.p[1] & 0x7fffe00U;
1644 while ( bb.p[0] | bb.p[1] ) {
1645 from = last_one01( bb.p[0], bb.p[1] );
1646 bb.p[0] ^= abb_mask[from].p[0];
1647 bb.p[1] ^= abb_mask[from].p[1];
1649 bb_check.p[0] = bb_move.p[0] & abb_w_silver_attacks[from].p[0]
1650 & abb_b_silver_attacks[SQ_BKING].p[0];
1651 bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1652 & abb_b_silver_attacks[SQ_BKING].p[1];
1653 if ( ! ( bb_check.p[0] | bb_check.p[1] ) ) { continue; }
1655 BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1656 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1657 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1658 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1659 XorFile( from, OCCUPIED_FILE );
1660 XorDiag2( from, OCCUPIED_DIAG2 );
1661 XorDiag1( from, OCCUPIED_DIAG1 );
1664 to = last_one01( bb_check.p[0], bb_check.p[1] );
1665 bb_check.p[0] ^= abb_mask[to].p[0];
1666 bb_check.p[1] ^= abb_mask[to].p[1];
1668 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1670 bb_attacks = abb_w_silver_attacks[to];
1671 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1672 if ( IsDiscoverBK( from, to ) );
1673 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1674 if ( IsDiscoverWK( from, to ) ) { continue; }
1676 XorFile( from, OCCUPIED_FILE );
1677 XorDiag2( from, OCCUPIED_DIAG2 );
1678 XorDiag1( from, OCCUPIED_DIAG1 );
1679 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1680 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1681 BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1682 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1683 return ( To2Move(to) | From2Move(from)
1684 | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1685 } while ( bb_check.p[0] | bb_check.p[1] );
1687 XorFile( from, OCCUPIED_FILE );
1688 XorDiag2( from, OCCUPIED_DIAG2 );
1689 XorDiag1( from, OCCUPIED_DIAG1 );
1690 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1691 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1692 BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1693 BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1696 BBAnd( bb, BB_WKNIGHT, w_chk_tbl[SQ_BKING].knight );
1697 while ( BBTest(bb) ) {
1698 from = LastOne( bb );
1701 bb_check.p[2] = bb_move.p[2] & abb_w_knight_attacks[from].p[2]
1702 & abb_b_gold_attacks[SQ_BKING].p[2];
1704 if ( bb_check.p[2] ) {
1705 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1706 BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1707 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1708 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1709 XorFile( from, OCCUPIED_FILE );
1710 XorDiag2( from, OCCUPIED_DIAG2 );
1711 XorDiag1( from, OCCUPIED_DIAG1 );
1714 to = first_one2( bb_check.p[2] );
1715 bb_check.p[2] ^= abb_mask[to].p[2];
1717 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1719 bb_attacks = abb_w_gold_attacks[to];
1720 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1721 if ( IsDiscoverBK( from, to ) );
1722 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1723 if ( IsDiscoverWK( from, to ) ) { continue; }
1725 XorFile( from, OCCUPIED_FILE );
1726 XorDiag2( from, OCCUPIED_DIAG2 );
1727 XorDiag1( from, OCCUPIED_DIAG1 );
1728 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1729 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1730 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1731 BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1732 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1733 | Cap2Move(BOARD[to]) | Piece2Move(knight) );
1734 } while ( bb_check.p[2] );
1736 XorFile( from, OCCUPIED_FILE );
1737 XorDiag2( from, OCCUPIED_DIAG2 );
1738 XorDiag1( from, OCCUPIED_DIAG1 );
1739 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1740 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1741 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1742 BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1745 BBAnd( bb_check, bb_move, abb_w_knight_attacks[from] );
1746 BBAnd( bb_check, bb_check, abb_b_knight_attacks[SQ_BKING] );
1748 if ( BBTest(bb_check) ) {
1749 BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1750 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1751 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1752 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1753 XorFile( from, OCCUPIED_FILE );
1754 XorDiag2( from, OCCUPIED_DIAG2 );
1755 XorDiag1( from, OCCUPIED_DIAG1 );
1758 to = LastOne( bb_check );
1759 Xor( to, bb_check );
1761 BBIni( bb_attacks );
1762 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1763 if ( IsDiscoverBK( from, to ) );
1764 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1765 if ( IsDiscoverWK( from, to ) ) { continue; }
1767 XorFile( from, OCCUPIED_FILE );
1768 XorDiag2( from, OCCUPIED_DIAG2 );
1769 XorDiag1( from, OCCUPIED_DIAG1 );
1770 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1771 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1772 BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1773 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1774 return ( To2Move(to) | From2Move(from)
1775 | Cap2Move(BOARD[to]) | Piece2Move(knight) );
1776 } while ( BBTest(bb_check) );
1778 XorFile( from, OCCUPIED_FILE );
1779 XorDiag2( from, OCCUPIED_DIAG2 );
1780 XorDiag1( from, OCCUPIED_DIAG1 );
1781 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1782 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1783 BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1784 BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1789 BBAnd( bb, BB_WLANCE, w_chk_tbl[SQ_BKING].lance );
1790 while ( BBTest(bb) ) {
1791 from = LastOne( bb );
1794 bb_attacks = AttackFile(from);
1795 BBAnd( bb_attacks, bb_attacks, abb_plus_rays[from] );
1796 BBAnd( bb_attacks, bb_attacks, bb_move );
1798 BBAnd( bb_check, bb_attacks, abb_mask[SQ_BKING-nfile] );
1799 bb_check_pro.p[2] = bb_attacks.p[2] & abb_b_gold_attacks[SQ_BKING].p[2];
1801 if ( ! ( bb_check_pro.p[2] | bb_check.p[0]
1802 | bb_check.p[1] | bb_check.p[2] ) ) { continue; }
1804 Xor( from, BB_WLANCE );
1805 Xor( from, BB_WOCCUPY );
1806 XorFile( from, OCCUPIED_FILE );
1807 XorDiag2( from, OCCUPIED_DIAG2 );
1808 XorDiag1( from, OCCUPIED_DIAG1 );
1810 bb_check.p[2] &= 0x7fc0000U;
1811 if ( BBTest(bb_check) ) {
1813 to = SQ_BKING-nfile;
1814 if ( ! is_black_attacked( ptree, to ) ) {
1815 bb_check.p[2] &= ~abb_mask[to].p[2];
1818 bb_temp = abb_file_attacks[to][0];
1819 if ( can_b_king_escape( ptree, to, &bb_temp ) ) { goto w_lance_next; }
1820 if ( IsDiscoverBK( from, to ) );
1821 else if ( can_b_piece_capture( ptree, to ) ) { goto w_lance_next; }
1822 if ( IsDiscoverWK( from, to ) ) { goto w_lance_next; }
1824 XorFile( from, OCCUPIED_FILE );
1825 XorDiag2( from, OCCUPIED_DIAG2 );
1826 XorDiag1( from, OCCUPIED_DIAG1 );
1827 Xor( from, BB_WOCCUPY );
1828 Xor( from, BB_WLANCE );
1829 return ( To2Move(to) | From2Move(from)
1830 | Cap2Move(BOARD[to]) | Piece2Move(lance) );
1834 while ( bb_check_pro.p[2] )
1836 to = first_one2( bb_check_pro.p[2] );
1837 bb_check_pro.p[2] ^= abb_mask[to].p[2];
1839 if ( ! is_black_attacked( ptree, to ) ) { continue; }
1841 bb_attacks = abb_w_gold_attacks[to];
1842 if ( can_b_king_escape( ptree, to, &bb_attacks ) ) { continue; }
1843 if ( IsDiscoverBK( from, to ) );
1844 else if ( can_b_piece_capture( ptree, to ) ) { continue; }
1845 if ( IsDiscoverWK( from, to ) ) { continue; }
1847 XorFile( from, OCCUPIED_FILE );
1848 XorDiag2( from, OCCUPIED_DIAG2 );
1849 XorDiag1( from, OCCUPIED_DIAG1 );
1850 Xor( from, BB_WOCCUPY );
1851 Xor( from, BB_WLANCE );
1852 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1853 | Cap2Move(BOARD[to]) | Piece2Move(lance) );
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 );
1863 bb_check.p[2] = bb_move.p[2] & BB_WPAWN_ATK.p[2]
1864 & abb_b_gold_attacks[SQ_BKING].p[2];
1865 while ( bb_check.p[2] ) {
1866 to = first_one2( bb_check.p[2] );
1868 bb_check.p[2] ^= abb_mask[to].p[2];
1870 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1871 BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1872 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1873 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1874 XorFile( from, OCCUPIED_FILE );
1875 XorDiag2( from, OCCUPIED_DIAG2 );
1876 XorDiag1( from, OCCUPIED_DIAG1 );
1878 if ( ! is_black_attacked( ptree, to ) ) { goto w_pawn_pro_next; }
1879 bb_attacks = abb_w_gold_attacks[to];
1880 if ( can_b_king_escape( ptree,to,&bb_attacks ) ) { goto w_pawn_pro_next; }
1881 if ( IsDiscoverBK( from, to ) );
1882 else if ( can_b_piece_capture( ptree, to ) ) { goto w_pawn_pro_next; }
1883 if ( IsDiscoverWK( from, to ) ) { goto w_pawn_pro_next; }
1885 XorFile( from, OCCUPIED_FILE );
1886 XorDiag2( from, OCCUPIED_DIAG2 );
1887 XorDiag1( from, OCCUPIED_DIAG1 );
1888 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1889 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1890 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1891 BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1892 return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1893 | Cap2Move(BOARD[to]) | Piece2Move(pawn) );
1896 XorFile( from, OCCUPIED_FILE );
1897 XorDiag2( from, OCCUPIED_DIAG2 );
1898 XorDiag1( from, OCCUPIED_DIAG1 );
1899 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1900 BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1901 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1902 BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1905 if ( SQ_BKING <= I3 && SQ_BKING >= A7 ) {
1906 to = SQ_BKING - nfile;
1908 if ( BOARD[from] == -pawn && BOARD[to] >= 0 ) {
1910 BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1911 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1912 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1913 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1914 XorFile( from, OCCUPIED_FILE );
1915 XorDiag2( from, OCCUPIED_DIAG2 );
1916 XorDiag1( from, OCCUPIED_DIAG1 );
1918 if ( ! is_black_attacked( ptree, to ) ) { goto w_pawn_end; }
1919 BBIni( bb_attacks );
1920 if ( can_b_king_escape( ptree,to,&bb_attacks ) ) { goto w_pawn_end; }
1921 if ( can_b_piece_capture( ptree, to ) ) { goto w_pawn_end; }
1922 if ( IsDiscoverWK( from, to ) ) { goto w_pawn_end; }
1924 XorFile( from, OCCUPIED_FILE );
1925 XorDiag2( from, OCCUPIED_DIAG2 );
1926 XorDiag1( from, OCCUPIED_DIAG1 );
1927 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1928 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1929 BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1930 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1931 return ( To2Move(to) | From2Move(from)
1932 | Cap2Move(BOARD[to]) | Piece2Move(pawn) );
1935 XorFile( from, OCCUPIED_FILE );
1936 XorDiag2( from, OCCUPIED_DIAG2 );
1937 XorDiag1( from, OCCUPIED_DIAG1 );
1938 BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1939 BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1940 BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1941 BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1950 can_w_piece_capture( const tree_t * restrict ptree, int to )
1952 bitboard_t bb_sum, bb, bb_attacks;
1956 if ( to >= A8 && BOARD[from] == -pawn )
1958 if ( IsDiscoverWK(from,to) );
1962 BBAnd( bb_sum, BB_WKNIGHT, abb_b_knight_attacks[to] );
1964 BBAndOr( bb_sum, BB_WSILVER, abb_b_silver_attacks[to] );
1965 BBAndOr( bb_sum, BB_WTGOLD, abb_b_gold_attacks[to] );
1967 BBOr( bb, BB_WHORSE, BB_WDRAGON );
1968 BBAndOr( bb_sum, bb, abb_king_attacks[to] );
1970 AttackBishop( bb, to );
1971 BBAndOr( bb_sum, BB_W_BH, bb );
1973 BBAndOr( bb_sum, BB_W_RD, AttackRank(to) );
1975 BBAndOr( bb, BB_WLANCE, abb_minus_rays[to] );
1976 bb_attacks = AttackFile( to );
1977 BBAndOr( bb_sum, bb, bb_attacks );
1979 while ( BBTest( bb_sum ) )
1981 from = FirstOne( bb_sum );
1982 Xor( from, bb_sum );
1984 if ( IsDiscoverWK(from,to) ) { continue; }
1993 can_b_piece_capture( const tree_t * restrict ptree, int to )
1995 bitboard_t bb_sum, bb;
1999 if ( to <= I2 && BOARD[from] == pawn )
2001 if ( IsDiscoverBK(from,to) );
2005 BBAnd( bb_sum, BB_BKNIGHT, abb_w_knight_attacks[to] );
2007 BBAndOr( bb_sum, BB_BSILVER, abb_w_silver_attacks[to] );
2008 BBAndOr( bb_sum, BB_BTGOLD, abb_w_gold_attacks[to] );
2010 BBOr( bb, BB_BHORSE, BB_BDRAGON );
2011 BBAndOr( bb_sum, bb, abb_king_attacks[to] );
2013 AttackBishop( bb, to );
2014 BBAndOr( bb_sum, bb, BB_B_BH );
2015 BBAndOr( bb_sum, BB_B_RD, AttackRank(to) );
2018 BBAndOr( bb, BB_BLANCE, abb_plus_rays[to] );
2019 BBAndOr( bb_sum, bb, AttackFile( to ) );
2021 while ( BBTest( bb_sum ) )
2023 from = LastOne( bb_sum );
2024 Xor( from, bb_sum );
2026 if ( IsDiscoverBK( from, to ) ) { continue; }
2035 can_w_king_escape( tree_t * restrict ptree, int to,
2036 const bitboard_t * restrict pbb )
2038 bitboard_t bb = *pbb;
2039 int iret = 0, iescape;
2043 Xor( to, BB_BOCCUPY );
2044 XorFile( to, OCCUPIED_FILE );
2045 XorDiag2( to, OCCUPIED_DIAG2 );
2046 XorDiag1( to, OCCUPIED_DIAG1 );
2048 Xor( SQ_WKING, BB_WOCCUPY );
2049 XorFile( SQ_WKING, OCCUPIED_FILE );
2050 XorDiag2( SQ_WKING, OCCUPIED_DIAG2 );
2051 XorDiag1( SQ_WKING, OCCUPIED_DIAG1 );
2053 BBOr( bb, bb, abb_mask[to] );
2054 BBOr( bb, bb, BB_WOCCUPY );
2055 BBNotAnd( bb, abb_king_attacks[SQ_WKING], bb );
2059 iescape = FirstOne( bb );
2060 if ( ! is_white_attacked( ptree, iescape ) )
2068 XorFile( SQ_WKING, OCCUPIED_FILE );
2069 XorDiag2( SQ_WKING, OCCUPIED_DIAG2 );
2070 XorDiag1( SQ_WKING, OCCUPIED_DIAG1 );
2071 Xor( SQ_WKING, BB_WOCCUPY );
2074 Xor( to, BB_BOCCUPY );
2075 XorFile( to, OCCUPIED_FILE );
2076 XorDiag2( to, OCCUPIED_DIAG2 );
2077 XorDiag1( to, OCCUPIED_DIAG1 );
2085 can_b_king_escape( tree_t * restrict ptree, int to,
2086 const bitboard_t * restrict pbb )
2088 bitboard_t bb = *pbb;
2089 int iret = 0, iescape;
2093 Xor( to, BB_WOCCUPY );
2094 XorFile( to, OCCUPIED_FILE );
2095 XorDiag2( to, OCCUPIED_DIAG2 );
2096 XorDiag1( to, OCCUPIED_DIAG1 );
2099 Xor( SQ_BKING, BB_BOCCUPY );
2100 XorFile( SQ_BKING, OCCUPIED_FILE );
2101 XorDiag2( SQ_BKING, OCCUPIED_DIAG2 );
2102 XorDiag1( SQ_BKING, OCCUPIED_DIAG1 );
2104 BBOr( bb, bb, abb_mask[to] );
2105 BBOr( bb, bb, BB_BOCCUPY );
2106 BBNotAnd( bb, abb_king_attacks[SQ_BKING], bb );
2110 iescape = LastOne( bb );
2111 if ( ! is_black_attacked( ptree, iescape ) )
2119 XorFile( SQ_BKING, OCCUPIED_FILE );
2120 XorDiag2( SQ_BKING, OCCUPIED_DIAG2 );
2121 XorDiag1( SQ_BKING, OCCUPIED_DIAG1 );
2122 Xor( SQ_BKING, BB_BOCCUPY );
2126 XorFile( to, OCCUPIED_FILE );
2127 XorDiag2( to, OCCUPIED_DIAG2 );
2128 XorDiag1( to, OCCUPIED_DIAG1 );
2129 Xor( to, BB_WOCCUPY );