7 is_pinned_on_white_king( const tree_t * restrict ptree, int isquare,
10 unsigned int ubb_attacks;
11 bitboard_t bb_attacks, bb_attacker;
16 ubb_attacks = AttackRank( isquare );
17 if ( ubb_attacks & (BB_WKING.p[aslide[isquare].ir0]) )
19 return ubb_attacks & BB_B_RD.p[aslide[isquare].ir0];
24 bb_attacks = AttackFile( isquare );
25 if ( BBContract( bb_attacks, BB_WKING ) )
27 BBAnd( bb_attacker, BB_BLANCE, abb_plus_rays[isquare] );
28 BBOr( bb_attacker, bb_attacker, BB_B_RD );
29 return BBContract( bb_attacks, bb_attacker ); /* return! */
34 bb_attacks = AttackDiag1( isquare );
35 if ( BBContract( bb_attacks, BB_WKING ) )
37 return BBContract( bb_attacks, BB_B_BH ); /* return! */
42 assert( idirec == direc_diag2 );
43 bb_attacks = AttackDiag2( isquare );
44 if ( BBContract( bb_attacks, BB_WKING ) )
46 return BBContract( bb_attacks, BB_B_BH ); /* return! */
56 is_pinned_on_black_king( const tree_t * restrict ptree, int isquare,
59 unsigned int ubb_attacks;
60 bitboard_t bb_attacks, bb_attacker;
65 ubb_attacks = AttackRank( isquare );
66 if ( ubb_attacks & (BB_BKING.p[aslide[isquare].ir0]) )
68 return ubb_attacks & BB_W_RD.p[aslide[isquare].ir0];
73 bb_attacks = AttackFile( isquare );
74 if ( BBContract( bb_attacks, BB_BKING ) )
76 BBAnd( bb_attacker, BB_WLANCE, abb_minus_rays[isquare] );
77 BBOr( bb_attacker, bb_attacker, BB_W_RD );
78 return BBContract( bb_attacks, bb_attacker ); /* return! */
83 bb_attacks = AttackDiag1( isquare );
84 if ( BBContract( bb_attacks, BB_BKING ) )
86 return BBContract( bb_attacks, BB_W_BH ); /* return! */
91 assert( idirec == direc_diag2 );
92 bb_attacks = AttackDiag2( isquare );
93 if ( BBContract( bb_attacks, BB_BKING ) )
95 return BBContract( bb_attacks, BB_W_BH ); /* return! */
103 /* perpetual check detections are omitted. */
105 is_mate_b_pawn_drop( tree_t * restrict ptree, int sq_drop )
107 bitboard_t bb, bb_sum, bb_move;
108 int iwk, ito, iret, ifrom, idirec;
110 BBAnd( bb_sum, BB_WKNIGHT, abb_b_knight_attacks[sq_drop] );
112 BBAndOr( bb_sum, BB_WSILVER, abb_b_silver_attacks[sq_drop] );
113 BBAndOr( bb_sum, BB_WTGOLD, abb_b_gold_attacks[sq_drop] );
115 AttackBishop( bb, sq_drop );
116 BBAndOr( bb_sum, BB_W_BH, bb );
118 AttackRook( bb, sq_drop );
119 BBAndOr( bb_sum, BB_W_RD, bb );
121 BBOr( bb, BB_WHORSE, BB_WDRAGON );
122 BBAndOr( bb_sum, bb, abb_king_attacks[sq_drop] );
124 while ( BBToU( bb_sum ) )
126 ifrom = FirstOne( bb_sum );
127 Xor( ifrom, bb_sum );
129 if ( IsDiscoverWK( ifrom, sq_drop ) ) { continue; }
135 Xor( sq_drop, BB_BOCCUPY );
136 XorFile( sq_drop, OCCUPIED_FILE );
137 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
138 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
140 BBNot( bb_move, BB_WOCCUPY );
141 BBAnd( bb_move, bb_move, abb_king_attacks[iwk] );
142 while ( BBToU( bb_move ) )
144 ito = FirstOne( bb_move );
145 if ( ! is_white_attacked( ptree, ito ) )
153 Xor( sq_drop, BB_BOCCUPY );
154 XorFile( sq_drop, OCCUPIED_FILE );
155 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
156 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
163 is_mate_w_pawn_drop( tree_t * restrict ptree, int sq_drop )
165 bitboard_t bb, bb_sum, bb_move;
166 int ibk, ito, ifrom, iret, idirec;
168 BBAnd( bb_sum, BB_BKNIGHT, abb_w_knight_attacks[sq_drop] );
170 BBAndOr( bb_sum, BB_BSILVER, abb_w_silver_attacks[sq_drop] );
171 BBAndOr( bb_sum, BB_BTGOLD, abb_w_gold_attacks[sq_drop] );
173 AttackBishop( bb, sq_drop );
174 BBAndOr( bb_sum, BB_B_BH, bb );
176 AttackRook( bb, sq_drop );
177 BBAndOr( bb_sum, BB_B_RD, bb );
179 BBOr( bb, BB_BHORSE, BB_BDRAGON );
180 BBAndOr( bb_sum, bb, abb_king_attacks[sq_drop] );
182 while ( BBToU( bb_sum ) )
184 ifrom = FirstOne( bb_sum );
185 Xor( ifrom, bb_sum );
187 if ( IsDiscoverBK( ifrom, sq_drop ) ) { continue; }
193 Xor( sq_drop, BB_WOCCUPY );
194 XorFile( sq_drop, OCCUPIED_FILE );
195 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
196 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
198 BBNot( bb_move, BB_BOCCUPY );
199 BBAnd( bb_move, bb_move, abb_king_attacks[ibk] );
200 while ( BBToU( bb_move ) )
202 ito = FirstOne( bb_move );
203 if ( ! is_black_attacked( ptree, ito ) )
211 Xor( sq_drop, BB_WOCCUPY );
212 XorFile( sq_drop, OCCUPIED_FILE );
213 XorDiag2( sq_drop, OCCUPIED_DIAG2 );
214 XorDiag1( sq_drop, OCCUPIED_DIAG1 );
221 attacks_to_piece( const tree_t * restrict ptree, int sq )
223 bitboard_t bb_ret, bb_attacks, bb;
226 if ( sq < rank9*nfile && BOARD[sq+nfile] == pawn )
228 bb_ret = abb_mask[sq+nfile];
230 if ( sq >= nfile && BOARD[sq-nfile] == -pawn )
232 BBOr( bb_ret, bb_ret, abb_mask[sq-nfile] );
235 BBAndOr( bb_ret, BB_BKNIGHT, abb_w_knight_attacks[sq] );
236 BBAndOr( bb_ret, BB_WKNIGHT, abb_b_knight_attacks[sq] );
238 BBAndOr( bb_ret, BB_BSILVER, abb_w_silver_attacks[sq] );
239 BBAndOr( bb_ret, BB_WSILVER, abb_b_silver_attacks[sq] );
241 BBAndOr( bb_ret, BB_BTGOLD, abb_w_gold_attacks[sq] );
242 BBAndOr( bb_ret, BB_WTGOLD, abb_b_gold_attacks[sq] );
244 BBOr( bb, BB_B_HDK, BB_W_HDK );
245 BBAndOr( bb_ret, bb, abb_king_attacks[sq] );
247 BBOr( bb, BB_B_BH, BB_W_BH );
248 AttackBishop( bb_attacks, sq );
249 BBAndOr( bb_ret, bb, bb_attacks );
251 BBOr( bb, BB_B_RD, BB_W_RD );
252 bb_ret.p[aslide[sq].ir0]
253 |= bb.p[aslide[sq].ir0] & AttackRank( sq );
255 BBAndOr( bb, BB_BLANCE, abb_plus_rays[sq] );
256 BBAndOr( bb, BB_WLANCE, abb_minus_rays[sq] );
257 bb_attacks = AttackFile( sq );
258 BBAndOr( bb_ret, bb, bb_attacks );
265 is_white_attacked( const tree_t * restrict ptree, int sq )
270 u = BBContract( BB_BPAWN_ATK, abb_mask[sq] );
271 u |= BBContract( BB_BKNIGHT, abb_w_knight_attacks[sq] );
272 u |= BBContract( BB_BSILVER, abb_w_silver_attacks[sq] );
273 u |= BBContract( BB_BTGOLD, abb_w_gold_attacks[sq] );
274 u |= BBContract( BB_B_HDK, abb_king_attacks[sq] );
276 AttackBishop( bb, sq );
277 u |= BBContract( BB_B_BH, bb );
279 u |= BB_B_RD.p[aslide[sq].ir0] & AttackRank( sq );
281 bb = AttackFile( sq );
282 u |= ( ( BB_BLANCE.p[0] & abb_plus_rays[sq].p[0] )
283 | BB_B_RD.p[0] ) & bb.p[0];
284 u |= ( ( BB_BLANCE.p[1] & abb_plus_rays[sq].p[1] )
285 | BB_B_RD.p[1] ) & bb.p[1];
286 u |= ( ( BB_BLANCE.p[2] & abb_plus_rays[sq].p[2] )
287 | BB_B_RD.p[2] ) & bb.p[2];
294 is_black_attacked( const tree_t * restrict ptree, int sq )
299 u = BBContract( BB_WPAWN_ATK, abb_mask[sq] );
300 u |= BBContract( BB_WKNIGHT, abb_b_knight_attacks[sq] );
301 u |= BBContract( BB_WSILVER, abb_b_silver_attacks[sq] );
302 u |= BBContract( BB_WTGOLD, abb_b_gold_attacks[sq] );
303 u |= BBContract( BB_W_HDK, abb_king_attacks[sq] );
305 AttackBishop( bb, sq );
306 u |= BBContract( BB_W_BH, bb );
308 u |= BB_W_RD.p[aslide[sq].ir0] & AttackRank( sq );
310 bb = AttackFile( sq );
311 u |= ( ( BB_WLANCE.p[0] & abb_minus_rays[sq].p[0] )
312 | BB_W_RD.p[0] ) & bb.p[0];
313 u |= ( ( BB_WLANCE.p[1] & abb_minus_rays[sq].p[1] )
314 | BB_W_RD.p[1] ) & bb.p[1];
315 u |= ( ( BB_WLANCE.p[2] & abb_minus_rays[sq].p[2] )
316 | BB_W_RD.p[2] ) & bb.p[2];