6 is_pinned_on_white_king( const tree_t * restrict ptree, int isquare,
9 bitboard_t bb_attacks, bb_attacker;
14 bb_attacks = AttackRank( isquare );
15 if ( BBContract( bb_attacks, BB_WKING ) )
17 return BBContract( bb_attacks, BB_B_RD );
22 bb_attacks = AttackFile( isquare );
23 if ( BBContract( bb_attacks, BB_WKING ) )
25 BBAnd( bb_attacker, BB_BLANCE, abb_plus_rays[isquare] );
26 BBOr( bb_attacker, bb_attacker, BB_B_RD );
27 return BBContract( bb_attacks, bb_attacker ); /* return! */
32 bb_attacks = AttackDiag1( isquare );
33 if ( BBContract( bb_attacks, BB_WKING ) )
35 return BBContract( bb_attacks, BB_B_BH ); /* return! */
40 assert( idirec == direc_diag2 );
41 bb_attacks = AttackDiag2( isquare );
42 if ( BBContract( bb_attacks, BB_WKING ) )
44 return BBContract( bb_attacks, BB_B_BH ); /* return! */
54 is_pinned_on_black_king( const tree_t * restrict ptree, int isquare,
57 bitboard_t bb_attacks, bb_attacker;
62 bb_attacks = AttackRank( isquare );
63 if ( BBContract( bb_attacks, BB_BKING ) )
65 return BBContract( bb_attacks, BB_W_RD );
70 bb_attacks = AttackFile( isquare );
71 if ( BBContract( bb_attacks, BB_BKING ) )
73 BBAnd( bb_attacker, BB_WLANCE, abb_minus_rays[isquare] );
74 BBOr( bb_attacker, bb_attacker, BB_W_RD );
75 return BBContract( bb_attacks, bb_attacker ); /* return! */
80 bb_attacks = AttackDiag1( isquare );
81 if ( BBContract( bb_attacks, BB_BKING ) )
83 return BBContract( bb_attacks, BB_W_BH ); /* return! */
88 assert( idirec == direc_diag2 );
89 bb_attacks = AttackDiag2( isquare );
90 if ( BBContract( bb_attacks, BB_BKING ) )
92 return BBContract( bb_attacks, BB_W_BH ); /* return! */
100 /* perpetual check detections are omitted. */
102 is_mate_b_pawn_drop( tree_t * restrict ptree, int sq_drop )
104 bitboard_t bb, bb_sum, bb_move;
105 int iwk, ito, iret, ifrom, idirec;
107 BBAnd( bb_sum, BB_WKNIGHT, abb_b_knight_attacks[sq_drop] );
109 BBAndOr( bb_sum, BB_WSILVER, abb_b_silver_attacks[sq_drop] );
110 BBAndOr( bb_sum, BB_WTGOLD, abb_b_gold_attacks[sq_drop] );
112 AttackBishop( bb, sq_drop );
113 BBAndOr( bb_sum, BB_W_BH, bb );
115 AttackRook( bb, sq_drop );
116 BBAndOr( bb_sum, BB_W_RD, bb );
118 BBOr( bb, BB_WHORSE, BB_WDRAGON );
119 BBAndOr( bb_sum, bb, abb_king_attacks[sq_drop] );
121 while ( BBTest( bb_sum ) )
123 ifrom = FirstOne( bb_sum );
124 Xor( ifrom, bb_sum );
126 if ( IsDiscoverWK( ifrom, sq_drop ) ) { continue; }
132 Xor( sq_drop, BB_BOCCUPY );
133 XorFile( sq_drop, OCCUPIED_FILE );
134 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
135 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
137 BBNotAnd( bb_move, abb_king_attacks[iwk], BB_WOCCUPY );
138 while ( BBTest( bb_move ) )
140 ito = FirstOne( bb_move );
141 if ( ! is_white_attacked( ptree, ito ) )
149 Xor( sq_drop, BB_BOCCUPY );
150 XorFile( sq_drop, OCCUPIED_FILE );
151 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
152 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
159 is_mate_w_pawn_drop( tree_t * restrict ptree, int sq_drop )
161 bitboard_t bb, bb_sum, bb_move;
162 int ibk, ito, ifrom, iret, idirec;
164 BBAnd( bb_sum, BB_BKNIGHT, abb_w_knight_attacks[sq_drop] );
166 BBAndOr( bb_sum, BB_BSILVER, abb_w_silver_attacks[sq_drop] );
167 BBAndOr( bb_sum, BB_BTGOLD, abb_w_gold_attacks[sq_drop] );
169 AttackBishop( bb, sq_drop );
170 BBAndOr( bb_sum, BB_B_BH, bb );
172 AttackRook( bb, sq_drop );
173 BBAndOr( bb_sum, BB_B_RD, bb );
175 BBOr( bb, BB_BHORSE, BB_BDRAGON );
176 BBAndOr( bb_sum, bb, abb_king_attacks[sq_drop] );
178 while ( BBTest( bb_sum ) )
180 ifrom = FirstOne( bb_sum );
181 Xor( ifrom, bb_sum );
183 if ( IsDiscoverBK( ifrom, sq_drop ) ) { continue; }
189 Xor( sq_drop, BB_WOCCUPY );
190 XorFile( sq_drop, OCCUPIED_FILE );
191 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
192 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
194 BBNotAnd( bb_move, abb_king_attacks[ibk], BB_BOCCUPY );
195 while ( BBTest( bb_move ) )
197 ito = FirstOne( bb_move );
198 if ( ! is_black_attacked( ptree, ito ) )
206 Xor( sq_drop, BB_WOCCUPY );
207 XorFile( sq_drop, OCCUPIED_FILE );
208 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
209 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
216 is_move_check_b( const tree_t * restrict ptree, unsigned int move )
218 const int from = (int)I2From(move);
219 const int to = (int)I2To(move);
220 int ipiece_move, idirec;
223 if ( from >= nsquare ) { ipiece_move = From2Drop(from); }
225 ipiece_move = (int)I2PieceMove(move);
226 if ( I2IsPromote(move) ) { ipiece_move += promote; }
228 idirec = (int)adirec[SQ_WKING][from];
229 if ( idirec && idirec != (int)adirec[SQ_WKING][to]
230 && is_pinned_on_white_king( ptree, from, idirec ) ) { return 1; }
233 switch ( ipiece_move )
236 return BOARD[to-nfile] == -king;
239 AttackBLance( bb, to );
240 return BBContract( bb, BB_WKING );
243 return BBContract( abb_b_knight_attacks[to], BB_WKING );
246 return BBContract( abb_b_silver_attacks[to], BB_WKING );
249 AttackBishop( bb, to );
250 return BBContract( bb, BB_WKING );
253 AttackRook( bb, to );
254 return BBContract( bb, BB_WKING );
260 AttackHorse( bb, to );
261 return BBContract( bb, BB_WKING );
264 assert( ipiece_move == dragon );
265 AttackDragon( bb, to );
266 return BBContract( bb, BB_WKING );
269 case gold: case pro_pawn:
270 case pro_lance: case pro_knight:
273 return BBContract( abb_b_gold_attacks[to], BB_WKING );
278 is_move_check_w( const tree_t * restrict ptree, unsigned int move )
280 const int from = (int)I2From(move);
281 const int to = (int)I2To(move);
282 int ipiece_move, idirec;
285 if ( from >= nsquare ) { ipiece_move = From2Drop(from); }
287 ipiece_move = (int)I2PieceMove(move);
288 if ( I2IsPromote(move) ) { ipiece_move += promote; }
290 idirec = (int)adirec[SQ_BKING][from];
291 if ( idirec && idirec != (int)adirec[SQ_BKING][to]
292 && is_pinned_on_black_king( ptree, from, idirec ) ) { return 1; }
295 switch ( ipiece_move )
298 return BOARD[to+nfile] == king;
301 AttackWLance( bb, to );
302 return BBContract( bb, BB_BKING );
305 return BBContract( abb_w_knight_attacks[to], BB_BKING );
308 return BBContract( abb_w_silver_attacks[to], BB_BKING );
311 AttackBishop( bb, to );
312 return BBContract( bb, BB_BKING );
315 AttackRook( bb, to );
316 return BBContract( bb, BB_BKING );
322 AttackHorse( bb, to );
323 return BBContract( bb, BB_BKING );
326 AttackDragon( bb, to );
327 return BBContract( bb, BB_BKING );
331 case gold: case pro_pawn:
332 case pro_lance: case pro_knight:
335 return BBContract( abb_w_gold_attacks[to], BB_BKING );
340 attacks_to_piece( const tree_t * restrict ptree, int sq )
342 bitboard_t bb_ret, bb_attacks, bb;
345 if ( sq < rank9*nfile && BOARD[sq+nfile] == pawn )
347 bb_ret = abb_mask[sq+nfile];
349 if ( sq >= nfile && BOARD[sq-nfile] == -pawn )
351 BBOr( bb_ret, bb_ret, abb_mask[sq-nfile] );
354 BBAndOr( bb_ret, BB_BKNIGHT, abb_w_knight_attacks[sq] );
355 BBAndOr( bb_ret, BB_WKNIGHT, abb_b_knight_attacks[sq] );
356 BBAndOr( bb_ret, BB_BSILVER, abb_w_silver_attacks[sq] );
357 BBAndOr( bb_ret, BB_WSILVER, abb_b_silver_attacks[sq] );
358 BBAndOr( bb_ret, BB_BTGOLD, abb_w_gold_attacks[sq] );
359 BBAndOr( bb_ret, BB_WTGOLD, abb_b_gold_attacks[sq] );
361 BBOr( bb, BB_B_HDK, BB_W_HDK );
362 BBAndOr( bb_ret, bb, abb_king_attacks[sq] );
364 BBOr( bb, BB_B_BH, BB_W_BH );
365 AttackBishop( bb_attacks, sq );
366 BBAndOr( bb_ret, bb, bb_attacks );
368 BBOr( bb, BB_B_RD, BB_W_RD );
369 BBAndOr( bb_ret, bb, AttackRank( sq ) );
370 BBAndOr( bb, BB_BLANCE, abb_plus_rays[sq] );
371 BBAndOr( bb, BB_WLANCE, abb_minus_rays[sq] );
372 BBAndOr( bb_ret, bb, AttackFile( sq ) );
379 b_attacks_to_piece( const tree_t * restrict ptree, int sq )
381 bitboard_t bb_ret, bb_attacks, bb;
384 if ( sq < rank9*nfile && BOARD[sq+nfile] == pawn )
386 bb_ret = abb_mask[sq+nfile];
389 BBAndOr( bb_ret, BB_BKNIGHT, abb_w_knight_attacks[sq] );
390 BBAndOr( bb_ret, BB_BSILVER, abb_w_silver_attacks[sq] );
391 BBAndOr( bb_ret, BB_BTGOLD, abb_w_gold_attacks[sq] );
392 BBAndOr( bb_ret, BB_B_HDK, abb_king_attacks[sq] );
394 AttackBishop( bb_attacks, sq );
395 BBAndOr( bb_ret, BB_B_BH, bb_attacks );
398 BBAndOr( bb_ret, bb, AttackRank(sq) );
399 BBAndOr( bb, BB_BLANCE, abb_plus_rays[sq] );
400 BBAndOr( bb_ret, bb, AttackFile(sq) );
407 w_attacks_to_piece( const tree_t * restrict ptree, int sq )
409 bitboard_t bb_ret, bb_attacks, bb;
412 if ( nfile <= sq && BOARD[sq-nfile] == -pawn )
414 bb_ret = abb_mask[sq-nfile];
417 BBAndOr( bb_ret, BB_WKNIGHT, abb_b_knight_attacks[sq] );
418 BBAndOr( bb_ret, BB_WSILVER, abb_b_silver_attacks[sq] );
419 BBAndOr( bb_ret, BB_WTGOLD, abb_b_gold_attacks[sq] );
420 BBAndOr( bb_ret, BB_W_HDK, abb_king_attacks[sq] );
422 AttackBishop( bb_attacks, sq );
423 BBAndOr( bb_ret, BB_W_BH, bb_attacks );
426 BBAndOr( bb_ret, bb, AttackRank(sq) );
427 BBAndOr( bb, BB_WLANCE, abb_minus_rays[sq] );
428 BBAndOr( bb_ret, bb, AttackFile(sq) );
435 is_white_attacked( const tree_t * restrict ptree, int sq )
437 bitboard_t bb, bb1, bb_atk;
439 BBAnd ( bb, BB_BPAWN_ATK, abb_mask[sq] );
440 BBAndOr( bb, BB_BKNIGHT, abb_w_knight_attacks[sq] );
441 BBAndOr( bb, BB_BSILVER, abb_w_silver_attacks[sq] );
442 BBAndOr( bb, BB_BTGOLD, abb_w_gold_attacks[sq] );
443 BBAndOr( bb, BB_B_HDK, abb_king_attacks[sq] );
445 AttackBishop( bb_atk, sq );
446 BBAndOr( bb, BB_B_BH, bb_atk );
449 BBAndOr( bb1, BB_BLANCE, abb_plus_rays[sq] );
450 BBAndOr( bb, bb1, AttackFile( sq ) );
451 BBAndOr( bb, BB_B_RD, AttackRank( sq ) );
458 is_black_attacked( const tree_t * restrict ptree, int sq )
460 bitboard_t bb, bb1, bb_atk;
462 BBAnd ( bb, BB_WPAWN_ATK, abb_mask[sq] );
463 BBAndOr( bb, BB_WKNIGHT, abb_b_knight_attacks[sq] );
464 BBAndOr( bb, BB_WSILVER, abb_b_silver_attacks[sq] );
465 BBAndOr( bb, BB_WTGOLD, abb_b_gold_attacks[sq] );
466 BBAndOr( bb, BB_W_HDK, abb_king_attacks[sq] );
468 AttackBishop( bb_atk, sq );
469 BBAndOr( bb, BB_W_BH, bb_atk );
472 BBAndOr( bb1, BB_WLANCE, abb_minus_rays[sq] );
473 BBAndOr( bb, bb1, AttackFile( sq ) );
474 BBAndOr( bb, BB_W_RD, AttackRank( sq ) );