7 swap( const tree_t * restrict ptree, unsigned int move, int root_alpha,
8 int root_beta, int turn )
10 bitboard_t bb, bb_temp, bb_attack;
11 int attacked_piece, from, to, nc;
12 int piece_cap, piece, value, xvalue, alpha, beta, is_promo;
14 from = (int)I2From( move );
15 to = (int)I2To( move );
17 if ( from >= nsquare )
20 piece = From2Drop( from );
21 attacked_piece = p_value_ex[15+piece];
24 piece = (int)I2PieceMove( move );
25 piece_cap = (int)UToCap( move );
26 is_promo = (int)I2IsPromote( move );
28 value = p_value_ex[15+piece_cap];
29 attacked_piece = p_value_ex[15+piece];
32 value += p_value_pm[7+piece];
33 attacked_piece += p_value_pm[7+piece];
35 xvalue = value - attacked_piece - MT_PRO_PAWN;
36 if ( xvalue >= root_beta ) { return xvalue; }
39 bb_attack = attacks_to_piece( ptree, to );
44 /* remove an attacker, and add a hidden piece to bb_attack */
47 Xor( from, bb_attack );
48 switch ( adirec[to][from] )
51 bb = AttackRank( from );
52 if ( from > to ) { BBAnd( bb, bb, abb_plus_rays[from] ); }
53 else { BBAnd( bb, bb, abb_minus_rays[from] ); }
54 BBOr( bb_temp, BB_B_RD, BB_W_RD );
55 BBAndOr( bb_attack, bb, bb_temp );
59 bb = AttackFile( from );
60 BBOr( bb_temp, BB_B_RD, BB_W_RD );
63 BBOr( bb_temp, bb_temp, BB_BLANCE );
64 BBAnd( bb, bb, abb_plus_rays[from] );
67 BBOr( bb_temp, bb_temp, BB_WLANCE );
68 BBAnd( bb, bb, abb_minus_rays[from] );
70 BBAnd( bb, bb, bb_temp );
71 BBOr( bb_attack, bb_attack, bb );
75 bb = AttackDiag1( from );
76 if ( from > to ) { BBAnd( bb, bb, abb_plus_rays[from] ); }
77 else { BBAnd( bb, bb, abb_minus_rays[from] ); }
78 BBOr( bb_temp, BB_B_BH, BB_W_BH );
79 BBAnd( bb, bb, bb_temp );
80 BBOr( bb_attack, bb_attack, bb );
84 bb = AttackDiag2( from );
85 if ( from > to ) { BBAnd( bb, bb, abb_plus_rays[from] ); }
86 else { BBAnd( bb, bb, abb_minus_rays[from] ); }
87 BBOr( bb_temp, BB_B_BH, BB_W_BH );
88 BBAnd( bb, bb, bb_temp );
89 BBOr( bb_attack, bb_attack, bb );
95 /* find the cheapest piece attacks the target */
98 if ( ! BBContract( bb_attack, BB_BOCCUPY ) ) { break; }
99 value = attacked_piece - value;
101 if( BBContract( bb_attack, BB_BPAWN ) )
104 attacked_piece = MT_CAP_PAWN;
107 value += MT_PRO_PAWN;
108 attacked_piece += MT_PRO_PAWN;
112 BBAnd( bb, BB_BLANCE, bb_attack );
115 from = FirstOne( bb );
116 attacked_piece = MT_CAP_LANCE;
119 value += MT_PRO_LANCE;
120 attacked_piece += MT_PRO_LANCE;
124 BBAnd( bb, BB_BKNIGHT, bb_attack );
127 from = FirstOne( bb );
128 attacked_piece = MT_CAP_KNIGHT;
131 value += MT_PRO_KNIGHT;
132 attacked_piece += MT_PRO_KNIGHT;
136 BBAnd( bb, BB_BPRO_PAWN, bb_attack );
139 from = FirstOne( bb );
140 attacked_piece = MT_CAP_PRO_PAWN;
143 BBAnd( bb, BB_BPRO_LANCE, bb_attack );
146 from = FirstOne( bb );
147 attacked_piece = MT_CAP_PRO_LANCE;
150 BBAnd( bb, BB_BPRO_KNIGHT, bb_attack );
153 from = FirstOne( bb );
154 attacked_piece = MT_CAP_PRO_KNIGHT;
157 BBAnd( bb, BB_BSILVER, bb_attack );
160 from = FirstOne( bb );
161 attacked_piece = MT_CAP_SILVER;
162 if ( from < 27 || to < 27 )
164 value += MT_PRO_SILVER;
165 attacked_piece += MT_PRO_SILVER;
169 BBAnd( bb, BB_BPRO_SILVER, bb_attack );
172 from = FirstOne( bb );
173 attacked_piece = MT_CAP_PRO_SILVER;
176 BBAnd( bb, BB_BGOLD, bb_attack );
179 from = FirstOne( bb );
180 attacked_piece = MT_CAP_GOLD;
183 BBAnd( bb, BB_BBISHOP, bb_attack );
186 from = FirstOne( bb );
187 attacked_piece = MT_CAP_BISHOP;
188 if ( from < 27 || to < 27 )
190 value += MT_PRO_BISHOP;
191 attacked_piece += MT_PRO_BISHOP;
195 BBAnd( bb, BB_BHORSE, bb_attack );
198 from = FirstOne( bb );
199 attacked_piece = MT_CAP_HORSE;
202 BBAnd( bb, BB_BROOK, bb_attack );
205 from = FirstOne( bb );
206 attacked_piece = MT_CAP_ROOK;
207 if ( from < 27 || to < 27 )
209 value += MT_PRO_ROOK;
210 attacked_piece += MT_PRO_ROOK;
214 BBAnd( bb, BB_BDRAGON, bb_attack );
217 from = FirstOne( bb );
218 attacked_piece = MT_CAP_DRAGON;
222 assert( BBContract( bb_attack, BB_BKING ) );
225 attacked_piece = MT_CAP_KING;
229 if ( ! BBContract( bb_attack, BB_WOCCUPY ) ) { break; }
231 value = attacked_piece - value;
233 if( BBContract( bb_attack, BB_WPAWN ) )
236 attacked_piece = MT_CAP_PAWN;
239 value += MT_PRO_PAWN;
240 attacked_piece += MT_PRO_PAWN;
244 BBAnd( bb, BB_WLANCE, bb_attack );
247 from = FirstOne( bb );
248 attacked_piece = MT_CAP_LANCE;
251 value += MT_PRO_LANCE;
252 attacked_piece += MT_PRO_LANCE;
256 BBAnd( bb, BB_WKNIGHT, bb_attack );
259 from = FirstOne( bb );
260 attacked_piece = MT_CAP_KNIGHT;
263 value += MT_PRO_KNIGHT;
264 attacked_piece += MT_PRO_KNIGHT;
268 BBAnd( bb, BB_WPRO_PAWN, bb_attack );
271 from = FirstOne( bb );
272 attacked_piece = MT_CAP_PRO_PAWN;
275 BBAnd( bb, BB_WPRO_LANCE, bb_attack );
278 from = FirstOne( bb );
279 attacked_piece = MT_CAP_PRO_LANCE;
282 BBAnd( bb, BB_WPRO_KNIGHT, bb_attack );
285 from = FirstOne( bb );
286 attacked_piece = MT_CAP_PRO_KNIGHT;
289 BBAnd( bb, BB_WSILVER, bb_attack );
292 from = FirstOne( bb );
293 attacked_piece = MT_CAP_SILVER;
294 if ( from > 53 || to > 53 )
296 value += MT_PRO_SILVER;
297 attacked_piece += MT_PRO_SILVER;
301 BBAnd( bb, BB_WPRO_SILVER, bb_attack );
304 from = FirstOne( bb );
305 attacked_piece = MT_CAP_PRO_SILVER;
308 BBAnd( bb, BB_WGOLD, bb_attack );
311 from = FirstOne( bb );
312 attacked_piece = MT_CAP_GOLD;
315 BBAnd( bb, BB_WBISHOP, bb_attack );
318 from = FirstOne( bb );
319 attacked_piece = MT_CAP_BISHOP;
320 if ( from > 53 || to > 53 )
322 value += MT_PRO_BISHOP;
323 attacked_piece += MT_PRO_BISHOP;
327 BBAnd( bb, BB_WHORSE, bb_attack );
330 from = FirstOne( bb );
331 attacked_piece = MT_CAP_HORSE;
334 BBAnd( bb, BB_WROOK, bb_attack );
337 from = FirstOne( bb );
338 attacked_piece = MT_CAP_ROOK;
339 if ( from > 53 || to > 53 )
341 value += MT_PRO_ROOK;
342 attacked_piece += MT_PRO_ROOK;
346 BBAnd( bb, BB_WDRAGON, bb_attack );
349 from = FirstOne( bb );
350 attacked_piece = MT_CAP_DRAGON;
354 assert( BBContract( bb_attack, BB_WKING ) );
356 attacked_piece = MT_CAP_KING;
363 if ( -value > alpha )
365 if ( -value >= beta ) { return beta; }
366 if ( -value >= root_beta ) { return -value; }
370 xvalue = attacked_piece + MT_PRO_PAWN - value;
371 if ( xvalue <= alpha ) { return alpha; }
372 if ( xvalue <= root_alpha ) { return xvalue; }
378 if ( value <= alpha ) { return alpha; }
379 if ( value <= root_alpha ) { return value; }
383 xvalue = value - attacked_piece - MT_PRO_PAWN;
384 if ( xvalue >= beta ) { return beta; }
385 if ( xvalue >= root_beta ) { return xvalue; }
390 if ( nc & 1 ) { return beta; }
391 else { return alpha; }