Fix pondering in XBoard mode
[bonanza.git] / mate1ply.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include "shogi.h"
4
5 #define DebugOut { static int count = 0; \
6                    if ( count++ < 16 ) { out_CSA_posi( ptree, stdout, 0 ); } }
7
8 static int can_w_king_escape( tree_t * restrict ptree, int to, bitboard_t bb );
9 static int can_b_king_escape( tree_t * restrict ptree, int to, bitboard_t bb );
10 static int can_w_piece_capture( const tree_t * restrict ptree, int to );
11 static int can_b_piece_capture( const tree_t * restrict ptree, int to );
12
13
14 unsigned int
15 is_b_mate_in_1ply( tree_t * restrict ptree )
16 {
17   bitboard_t bb, bb_temp, bb_check, bb_check_pro, bb_attacks, bb_drop, bb_move;
18   unsigned int ubb;
19   int to, from, idirec;
20
21   assert( ! is_black_attacked( ptree, SQ_BKING ) );
22
23   /*  Drops  */
24   BBOr( bb_drop, BB_BOCCUPY, BB_WOCCUPY );
25   BBNot( bb_drop, bb_drop );
26
27   if ( IsHandRook(HAND_B) ) {
28
29     BBAnd( bb, abb_w_gold_attacks[SQ_WKING],
30            abb_b_gold_attacks[SQ_WKING] );
31     BBAnd( bb, bb, bb_drop );
32     while( BBToU(bb) )
33       {
34         to = FirstOne( bb );
35         Xor( to, bb );
36
37         if ( ! is_white_attacked( ptree, to ) ) { continue; }
38         
39         bb_attacks                     = abb_file_attacks[to][0];
40         bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[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);
44       }
45
46   } else if ( IsHandLance(HAND_B) && SQ_WKING <= I2 ) {
47
48     to = SQ_WKING+nfile;
49     if ( ! BOARD[to] && is_white_attacked( ptree, to ) )
50       {
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 ) )
54           {
55             return To2Move(to) | Drop2Move(lance);
56           }
57       }
58   }
59
60   if ( IsHandBishop(HAND_B) ) {
61
62     BBAnd( bb, abb_w_silver_attacks[SQ_WKING],
63            abb_b_silver_attacks[SQ_WKING] );
64     BBAnd( bb, bb, bb_drop );
65     while( BBToU(bb) )
66       {
67         to = FirstOne( bb );
68         Xor( to, bb );
69
70         if ( ! is_white_attacked( ptree, to ) ) { continue; }
71         
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);
77       }
78   }
79
80   if ( IsHandGold(HAND_B) ) {
81
82     if ( IsHandRook(HAND_B) )
83       {
84         BBAnd( bb, abb_b_gold_attacks[SQ_WKING],
85                abb_b_silver_attacks[SQ_WKING] );
86         BBNot( bb, bb );
87         BBAnd( bb, bb, bb_drop );
88         BBAnd( bb, bb, abb_w_gold_attacks[SQ_WKING] );
89       }
90     else { BBAnd( bb, bb_drop, abb_w_gold_attacks[SQ_WKING] ); }
91
92     while ( BBToU(bb) )
93       {
94         to = FirstOne( bb );
95         Xor( to, bb );
96         
97         if ( ! is_white_attacked( ptree, to ) ) { continue; }
98         
99         bb_attacks = abb_b_gold_attacks[to];
100         if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
101         if ( can_w_piece_capture( ptree, to ) )           { continue; }
102         return To2Move(to) | Drop2Move(gold);
103       }
104   }
105   
106   if ( IsHandSilver(HAND_B) ) {
107     
108     if ( IsHandGold(HAND_B) )
109       {
110         if ( IsHandBishop(HAND_B) ) { goto b_silver_drop_end; }
111         BBNot( bb, abb_w_gold_attacks[SQ_WKING] );
112         BBAnd( bb, bb, abb_w_silver_attacks[SQ_WKING] );
113         BBAnd( bb, bb, bb_drop );
114       }
115     else {
116       BBAnd( bb, bb_drop, abb_w_silver_attacks[SQ_WKING] );
117       if ( IsHandBishop(HAND_B) )
118         {
119           BBAnd( bb, bb, abb_w_gold_attacks[SQ_WKING] );
120         }
121     }
122     
123     while ( BBToU(bb) )
124       {
125         to = FirstOne( bb );
126         Xor( to, bb );
127         
128         if ( ! is_white_attacked( ptree, to ) ) { continue; }
129         
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);
134       }
135   }
136  b_silver_drop_end:
137  
138   if ( IsHandKnight(HAND_B) ) {
139     
140     BBAnd( bb, bb_drop, abb_w_knight_attacks[SQ_WKING] );
141     while ( BBToU(bb) )
142       {
143         to = FirstOne( bb );
144         Xor( to, bb );
145         
146         BBIni( bb_attacks );
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);
150       }
151   }
152
153   /*  Moves  */
154   BBNot( bb_move, BB_BOCCUPY );
155
156   bb = BB_BDRAGON;
157   while ( BBToU(bb) ) {
158     from = FirstOne( bb );
159     Xor( from, bb );
160
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 ( ! BBToU(bb_check) ) { continue; }
165
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 );
172
173     do {
174       to = FirstOne( bb_check );
175       Xor( to, bb_check );
176
177       if ( ! is_white_attacked( ptree, to ) ) { continue; }
178
179       if ( (int)adirec[SQ_WKING][to] & flag_cross )
180         {
181           bb_attacks = abb_file_attacks[to][0];
182           bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
183           BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
184         }
185       else { AttackDragon( bb_attacks, to ); }
186
187       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
188       if ( IsDiscoverWK( from, to ) );
189       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
190       if ( IsDiscoverBK( from, to ) )                  { continue; }
191         
192       XorFile( from, OCCUPIED_FILE );
193       XorDiag2( from, OCCUPIED_DIAG2 );
194       XorDiag1( from, OCCUPIED_DIAG1 );
195       Xor( from, BB_BOCCUPY );
196       Xor( from, BB_B_RD );
197       Xor( from, BB_B_HDK );
198       return ( To2Move(to) | From2Move(from)
199                | Cap2Move(-BOARD[to]) | Piece2Move(dragon) );
200     } while ( BBToU(bb_check) );
201
202     XorFile( from, OCCUPIED_FILE );
203     XorDiag2( from, OCCUPIED_DIAG2 );
204     XorDiag1( from, OCCUPIED_DIAG1 );
205     Xor( from, BB_BOCCUPY );
206     Xor( from, BB_B_RD );
207     Xor( from, BB_B_HDK );
208   }
209
210   bb.p[0] = BB_BROOK.p[0];
211   while ( bb.p[0] ) {
212     from = last_one0( bb.p[0] );
213     bb.p[0] ^= abb_mask[from].p[0];
214
215     AttackRook( bb_attacks, from );
216     BBAnd( bb_check, bb_move, bb_attacks );
217     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
218     if ( ! BBToU(bb_check) ) { continue; }
219
220     BB_B_RD.p[0]    ^= abb_mask[from].p[0];
221     BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
222     XorFile( from, OCCUPIED_FILE );
223     XorDiag2( from, OCCUPIED_DIAG2 );
224     XorDiag1( from, OCCUPIED_DIAG1 );
225
226     do {
227       to = FirstOne( bb_check );
228       Xor( to, bb_check );
229
230       if ( ! is_white_attacked( ptree, to ) ) { continue; }
231         
232       if ( (int)adirec[SQ_WKING][to] & flag_cross )
233         {
234           bb_attacks = abb_file_attacks[to][0];
235           bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
236           BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
237         }
238       else { AttackDragon( bb_attacks, to ); }
239
240       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
241       if ( IsDiscoverWK( from, to ) );
242       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
243       if ( IsDiscoverBK( from, to ) )                  { continue; }
244         
245       XorFile( from, OCCUPIED_FILE );
246       XorDiag2( from, OCCUPIED_DIAG2 );
247       XorDiag1( from, OCCUPIED_DIAG1 );
248       BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
249       BB_B_RD.p[0]    ^= abb_mask[from].p[0];
250       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
251                | Cap2Move(-BOARD[to]) | Piece2Move(rook) );
252     } while ( BBToU(bb_check) );
253
254     XorFile( from, OCCUPIED_FILE );
255     XorDiag2( from, OCCUPIED_DIAG2 );
256     XorDiag1( from, OCCUPIED_DIAG1 );
257     BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
258     BB_B_RD.p[0]    ^= abb_mask[from].p[0];
259   }
260
261   bb.p[1] = BB_BROOK.p[1];
262   bb.p[2] = BB_BROOK.p[2];
263   while ( bb.p[1] | bb.p[2] ) {
264     from = first_one12( bb.p[1], bb.p[2] );
265     bb.p[1] ^= abb_mask[from].p[1];
266     bb.p[2] ^= abb_mask[from].p[2];
267
268     AttackRook( bb_attacks, from );
269     BBAnd( bb_check, bb_move, bb_attacks );
270     bb_check.p[0] &= abb_king_attacks[SQ_WKING].p[0];
271     bb_check.p[1] &= abb_b_gold_attacks[SQ_WKING].p[1];
272     bb_check.p[2] &= abb_b_gold_attacks[SQ_WKING].p[2];
273     bb_check.p[1] &= abb_w_gold_attacks[SQ_WKING].p[1];
274     bb_check.p[2] &= abb_w_gold_attacks[SQ_WKING].p[2];
275     if ( ! BBToU(bb_check) ) { continue; }
276
277     BB_B_RD.p[1]    ^= abb_mask[from].p[1];
278     BB_B_RD.p[2]    ^= abb_mask[from].p[2];
279     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
280     BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
281     XorFile( from, OCCUPIED_FILE );
282     XorDiag2( from, OCCUPIED_DIAG2 );
283     XorDiag1( from, OCCUPIED_DIAG1 );
284
285     do {
286       to = FirstOne( bb_check );
287       Xor( to, bb_check );
288
289       if ( ! is_white_attacked( ptree, to ) ) { continue; }
290         
291       if ( to <= I7 ) {
292         if ( (int)adirec[SQ_WKING][to] & flag_cross )
293           {
294             bb_attacks = abb_file_attacks[to][0];
295             bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
296             bb_attacks.p[0] |= abb_king_attacks[to].p[0];
297             bb_attacks.p[1] |= abb_king_attacks[to].p[1];
298           }
299         else { AttackDragon( bb_attacks, to ); }
300
301       } else {
302         bb_attacks = abb_file_attacks[to][0];
303         bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
304       }
305       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
306       if ( IsDiscoverWK( from, to ) );
307       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
308       if ( IsDiscoverBK( from, to ) )                  { continue; }
309         
310       XorFile( from, OCCUPIED_FILE );
311       XorDiag2( from, OCCUPIED_DIAG2 );
312       XorDiag1( from, OCCUPIED_DIAG1 );
313       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
314       BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
315       BB_B_RD.p[1]    ^= abb_mask[from].p[1];
316       BB_B_RD.p[2]    ^= abb_mask[from].p[2];
317       return ( To2Move(to) | From2Move(from)
318                | ( (to < A6) ? FLAG_PROMO : 0 )
319                | Cap2Move(-BOARD[to]) | Piece2Move(rook) );
320     } while ( BBToU(bb_check) );
321
322     XorFile( from, OCCUPIED_FILE );
323     XorDiag2( from, OCCUPIED_DIAG2 );
324     XorDiag1( from, OCCUPIED_DIAG1 );
325     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
326     BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
327     BB_B_RD.p[1]    ^= abb_mask[from].p[1];
328     BB_B_RD.p[2]    ^= abb_mask[from].p[2];
329   }
330
331   bb = BB_BHORSE;
332   while ( BBToU(bb) ) {
333     from = FirstOne( bb );
334     Xor( from, bb );
335
336     AttackHorse( bb_attacks, from );
337     BBAnd( bb_check, bb_move,  bb_attacks );
338     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
339     if ( ! BBToU(bb_check) ) { continue; }
340
341     Xor( from, BB_B_HDK );
342     Xor( from, BB_B_BH );
343     Xor( from, BB_BOCCUPY );
344     XorFile( from, OCCUPIED_FILE );
345     XorDiag2( from, OCCUPIED_DIAG2 );
346     XorDiag1( from, OCCUPIED_DIAG1 );
347
348     do {
349       to = FirstOne( bb_check );
350       Xor( to, bb_check );
351
352       if ( ! is_white_attacked( ptree, to ) ) { continue; }
353         
354       BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
355             abb_bishop_attacks_rl45[to][0] );
356       BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
357       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
358       if ( IsDiscoverWK( from, to ) );
359       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
360       if ( IsDiscoverBK( from, to ) )                  { continue; }
361         
362       XorFile( from, OCCUPIED_FILE );
363       XorDiag2( from, OCCUPIED_DIAG2 );
364       XorDiag1( from, OCCUPIED_DIAG1 );
365       Xor( from, BB_BOCCUPY );
366       Xor( from, BB_B_BH );
367       Xor( from, BB_B_HDK );
368       return ( To2Move(to) | From2Move(from)
369                | Cap2Move(-BOARD[to]) | Piece2Move(horse) );
370     } while ( BBToU(bb_check) );
371
372     XorFile( from, OCCUPIED_FILE );
373     XorDiag2( from, OCCUPIED_DIAG2 );
374     XorDiag1( from, OCCUPIED_DIAG1 );
375     Xor( from, BB_BOCCUPY );
376     Xor( from, BB_B_BH );
377     Xor( from, BB_B_HDK );
378   }
379
380   bb.p[0] = BB_BBISHOP.p[0];
381   while ( bb.p[0] ) {
382     from = last_one0( bb.p[0] );
383     bb.p[0] ^= abb_mask[from].p[0];
384
385     AttackBishop( bb_attacks, from );
386     BBAnd( bb_check, bb_move, bb_attacks );
387     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_WKING] );
388     if ( ! BBToU(bb_check) ) { continue; }
389
390     BB_B_BH.p[0]    ^= abb_mask[from].p[0];
391     BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
392     XorFile( from, OCCUPIED_FILE );
393     XorDiag2( from, OCCUPIED_DIAG2 );
394     XorDiag1( from, OCCUPIED_DIAG1 );
395
396     do {
397       to = FirstOne( bb_check );
398       Xor( to, bb_check );
399
400       if ( ! is_white_attacked( ptree, to ) ) { continue; }
401         
402       BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
403             abb_bishop_attacks_rl45[to][0] );
404       BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
405       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
406       if ( IsDiscoverWK( from, to ) );
407       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
408       if ( IsDiscoverBK( from, to ) )                  { continue; }
409         
410       XorFile( from, OCCUPIED_FILE );
411       XorDiag2( from, OCCUPIED_DIAG2 );
412       XorDiag1( from, OCCUPIED_DIAG1 );
413       BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
414       BB_B_BH.p[0]    ^= abb_mask[from].p[0];
415       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
416                | Cap2Move(-BOARD[to]) | Piece2Move(bishop) );
417     } while ( BBToU(bb_check) );
418
419     XorFile( from, OCCUPIED_FILE );
420     XorDiag2( from, OCCUPIED_DIAG2 );
421     XorDiag1( from, OCCUPIED_DIAG1 );
422     BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
423     BB_B_BH.p[0]    ^= abb_mask[from].p[0];
424   }
425
426   bb.p[1] = BB_BBISHOP.p[1];
427   bb.p[2] = BB_BBISHOP.p[2];
428   while ( bb.p[1] | bb.p[2] ) {
429     from = first_one12( bb.p[1], bb.p[2] );
430     bb.p[1] ^= abb_mask[from].p[1];
431     bb.p[2] ^= abb_mask[from].p[2];
432
433     AttackBishop( bb_attacks, from );
434     BBAnd( bb_check, bb_move, bb_attacks );
435     bb_check.p[0] &= abb_king_attacks[SQ_WKING].p[0];
436     bb_check.p[1] &= abb_b_silver_attacks[SQ_WKING].p[1];
437     bb_check.p[2] &= abb_b_silver_attacks[SQ_WKING].p[2];
438     bb_check.p[1] &= abb_w_silver_attacks[SQ_WKING].p[1];
439     bb_check.p[2] &= abb_w_silver_attacks[SQ_WKING].p[2];
440     if ( ! BBToU(bb_check) ) { continue; }
441
442     BB_B_BH.p[1]    ^= abb_mask[from].p[1];
443     BB_B_BH.p[2]    ^= abb_mask[from].p[2];
444     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
445     BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
446     XorFile( from, OCCUPIED_FILE );
447     XorDiag2( from, OCCUPIED_DIAG2 );
448     XorDiag1( from, OCCUPIED_DIAG1 );
449
450     do {
451       to = FirstOne( bb_check );
452       Xor( to, bb_check );
453
454       if ( ! is_white_attacked( ptree, to ) ) { continue; }
455         
456       BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
457             abb_bishop_attacks_rl45[to][0] );
458       if ( to <= I7 ) {
459         bb_attacks.p[0] |= abb_king_attacks[to].p[0];
460         bb_attacks.p[1] |= abb_king_attacks[to].p[1];
461       }
462       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
463       if ( IsDiscoverWK( from, to ) );
464       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
465       if ( IsDiscoverBK( from, to ) )                  { continue; }
466         
467       XorFile( from, OCCUPIED_FILE );
468       XorDiag2( from, OCCUPIED_DIAG2 );
469       XorDiag1( from, OCCUPIED_DIAG1 );
470       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
471       BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
472       BB_B_BH.p[1]    ^= abb_mask[from].p[1];
473       BB_B_BH.p[2]    ^= abb_mask[from].p[2];
474       return ( To2Move(to) | From2Move(from)
475                | ( (to < A6) ? FLAG_PROMO : 0 )
476                | Cap2Move(-BOARD[to]) | Piece2Move(bishop) );
477     } while ( BBToU(bb_check) );
478
479     XorFile( from, OCCUPIED_FILE );
480     XorDiag2( from, OCCUPIED_DIAG2 );
481     XorDiag1( from, OCCUPIED_DIAG1 );
482     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
483     BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
484     BB_B_BH.p[1]    ^= abb_mask[from].p[1];
485     BB_B_BH.p[2]    ^= abb_mask[from].p[2];
486   }
487
488   BBAnd( bb, BB_BTGOLD, b_chk_tbl[SQ_WKING].gold );
489   while ( BBToU(bb) ) {
490     from = FirstOne( bb );
491     Xor( from, bb );
492
493     BBAnd( bb_check, bb_move, abb_b_gold_attacks[from] );
494     BBAnd( bb_check, bb_check, abb_w_gold_attacks[SQ_WKING] );
495     if ( ! BBToU(bb_check) ) { continue; }
496
497     Xor( from, BB_BTGOLD );
498     Xor( from, BB_BOCCUPY );
499     XorFile( from, OCCUPIED_FILE );
500     XorDiag2( from, OCCUPIED_DIAG2 );
501     XorDiag1( from, OCCUPIED_DIAG1 );
502
503     do {
504       to = FirstOne( bb_check );
505       Xor( to, bb_check );
506
507       if ( ! is_white_attacked( ptree, to ) ) { continue; }
508         
509       bb_attacks = abb_b_gold_attacks[to];
510       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
511       if ( IsDiscoverWK( from, to ) );
512       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
513       if ( IsDiscoverBK( from, to ) )                  { continue; }
514         
515       XorFile( from, OCCUPIED_FILE );
516       XorDiag2( from, OCCUPIED_DIAG2 );
517       XorDiag1( from, OCCUPIED_DIAG1 );
518       Xor( from, BB_BOCCUPY );
519       Xor( from, BB_BTGOLD );
520       return ( To2Move(to) | From2Move(from)
521                | Cap2Move(-BOARD[to]) | Piece2Move(BOARD[from]) );
522     } while ( BBToU(bb_check) );
523
524     XorFile( from, OCCUPIED_FILE );
525     XorDiag2( from, OCCUPIED_DIAG2 );
526     XorDiag1( from, OCCUPIED_DIAG1 );
527     Xor( from, BB_BOCCUPY );
528     Xor( from, BB_BTGOLD );
529   }
530
531   BBAnd( bb, BB_BSILVER, b_chk_tbl[SQ_WKING].silver );
532   while ( bb.p[0] ) {
533     from = last_one0( bb.p[0] );
534     bb.p[0] ^= abb_mask[from].p[0];
535
536     bb_check_pro.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
537       & abb_w_gold_attacks[SQ_WKING].p[0];
538     bb_check_pro.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
539       & abb_w_gold_attacks[SQ_WKING].p[1];
540
541     bb_check.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
542       & abb_w_silver_attacks[SQ_WKING].p[0]
543       & ~abb_w_gold_attacks[SQ_WKING].p[0];
544     bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
545       & abb_w_silver_attacks[SQ_WKING].p[1]
546       & ~abb_w_gold_attacks[SQ_WKING].p[1];
547
548     if ( ! ( bb_check_pro.p[0] | bb_check_pro.p[1]
549              | bb_check.p[0]| bb_check.p[1] ) ) { continue; }
550
551     BB_BSILVER.p[0] ^= abb_mask[from].p[0];
552     BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
553     XorFile( from, OCCUPIED_FILE );
554     XorDiag2( from, OCCUPIED_DIAG2 );
555     XorDiag1( from, OCCUPIED_DIAG1 );
556
557     while ( bb_check_pro.p[0] | bb_check_pro.p[1] ) {
558       to = first_one01( bb_check_pro.p[0], bb_check_pro.p[1] );
559       bb_check_pro.p[0] ^= abb_mask[to].p[0];
560       bb_check_pro.p[1] ^= abb_mask[to].p[1];
561       
562       if ( ! is_white_attacked( ptree, to ) ) { continue; }
563       
564       bb_attacks = abb_b_gold_attacks[to];
565       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
566       if ( IsDiscoverWK( from, to ) );
567       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
568       if ( IsDiscoverBK( from, to ) )                  { continue; }
569       
570       XorFile( from, OCCUPIED_FILE );
571       XorDiag2( from, OCCUPIED_DIAG2 );
572       XorDiag1( from, OCCUPIED_DIAG1 );
573       BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
574       BB_BSILVER.p[0] ^= abb_mask[from].p[0];
575       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
576                | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
577     }
578
579     while ( bb_check.p[0] | bb_check.p[1] ) {
580       to = first_one01( bb_check.p[0], bb_check.p[1] );
581       bb_check.p[0] ^= abb_mask[to].p[0];
582       bb_check.p[1] ^= abb_mask[to].p[1];
583       
584       if ( ! is_white_attacked( ptree, to ) ) { continue; }
585       
586       bb_attacks = abb_b_silver_attacks[to];
587       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
588       if ( IsDiscoverWK( from, to ) );
589       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
590       if ( IsDiscoverBK( from, to ) )                  { continue; }
591       
592       XorFile( from, OCCUPIED_FILE );
593       XorDiag2( from, OCCUPIED_DIAG2 );
594       XorDiag1( from, OCCUPIED_DIAG1 );
595       BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
596       BB_BSILVER.p[0] ^= abb_mask[from].p[0];
597       return ( To2Move(to) | From2Move(from)
598                | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
599     }
600
601     XorFile( from, OCCUPIED_FILE );
602     XorDiag2( from, OCCUPIED_DIAG2 );
603     XorDiag1( from, OCCUPIED_DIAG1 );
604     BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
605     BB_BSILVER.p[0] ^= abb_mask[from].p[0];
606   }
607
608   ubb = bb.p[1] & 0x7fc0000U;
609   while ( ubb ) {
610     from = last_one1( ubb );
611     ubb ^= abb_mask[from].p[1];
612
613     bb_check_pro.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
614       & abb_w_gold_attacks[SQ_WKING].p[0];
615
616     bb_check.p[0] = bb_move.p[0] & abb_b_silver_attacks[from].p[0]
617       & abb_w_silver_attacks[SQ_WKING].p[0]
618       & ~abb_w_gold_attacks[SQ_WKING].p[0];
619     bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
620       & abb_w_silver_attacks[SQ_WKING].p[1];
621
622     if ( ! (bb_check_pro.p[0]|bb_check.p[0]|bb_check.p[1]) ) { continue; }
623
624     BB_BSILVER.p[1] ^= abb_mask[from].p[1];
625     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
626     XorFile( from, OCCUPIED_FILE );
627     XorDiag2( from, OCCUPIED_DIAG2 );
628     XorDiag1( from, OCCUPIED_DIAG1 );
629
630     while ( bb_check_pro.p[0] ) {
631       to = last_one0( bb_check_pro.p[0] );
632       bb_check_pro.p[0] ^= abb_mask[to].p[0];
633       
634       if ( ! is_white_attacked( ptree, to ) ) { continue; }
635       
636       bb_attacks = abb_b_gold_attacks[to];
637       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
638       if ( IsDiscoverWK( from, to ) );
639       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
640       if ( IsDiscoverBK( from, to ) )                  { continue; }
641       
642       XorFile( from, OCCUPIED_FILE );
643       XorDiag2( from, OCCUPIED_DIAG2 );
644       XorDiag1( from, OCCUPIED_DIAG1 );
645       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
646       BB_BSILVER.p[1] ^= abb_mask[from].p[1];
647       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
648                | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
649     }
650
651     while ( bb_check.p[0] | bb_check.p[1] ) {
652       to = first_one01( bb_check.p[0], bb_check.p[1] );
653       bb_check.p[0] ^= abb_mask[to].p[0];
654       bb_check.p[1] ^= abb_mask[to].p[1];
655       
656       if ( ! is_white_attacked( ptree, to ) ) { continue; }
657       
658       bb_attacks = abb_b_silver_attacks[to];
659       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
660       if ( IsDiscoverWK( from, to ) );
661       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
662       if ( IsDiscoverBK( from, to ) )                  { continue; }
663       
664       XorFile( from, OCCUPIED_FILE );
665       XorDiag2( from, OCCUPIED_DIAG2 );
666       XorDiag1( from, OCCUPIED_DIAG1 );
667       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
668       BB_BSILVER.p[1] ^= abb_mask[from].p[1];
669       return ( To2Move(to) | From2Move(from)
670                | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
671     }
672
673     XorFile( from, OCCUPIED_FILE );
674     XorDiag2( from, OCCUPIED_DIAG2 );
675     XorDiag1( from, OCCUPIED_DIAG1 );
676     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
677     BB_BSILVER.p[1] ^= abb_mask[from].p[1];
678   }
679
680   bb.p[1] &= 0x003ffffU;
681   while ( bb.p[1] | bb.p[2] ) {
682     from = first_one12( bb.p[1], bb.p[2] );
683     bb.p[1] ^= abb_mask[from].p[1];
684     bb.p[2] ^= abb_mask[from].p[2];
685
686     bb_check.p[1] = bb_move.p[1] & abb_b_silver_attacks[from].p[1]
687       & abb_w_silver_attacks[SQ_WKING].p[1];
688     bb_check.p[2] = bb_move.p[2] & abb_b_silver_attacks[from].p[2]
689       & abb_w_silver_attacks[SQ_WKING].p[2];
690     if ( ! ( bb_check.p[1] | bb_check.p[2] ) ) { continue; }
691
692     BB_BSILVER.p[1] ^= abb_mask[from].p[1];
693     BB_BSILVER.p[2] ^= abb_mask[from].p[2];
694     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
695     BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
696     XorFile( from, OCCUPIED_FILE );
697     XorDiag2( from, OCCUPIED_DIAG2 );
698     XorDiag1( from, OCCUPIED_DIAG1 );
699
700     do {
701       to = first_one12( bb_check.p[1], bb_check.p[2] );
702       bb_check.p[1] ^= abb_mask[to].p[1];
703       bb_check.p[2] ^= abb_mask[to].p[2];
704
705       if ( ! is_white_attacked( ptree, to ) ) { continue; }
706         
707       bb_attacks = abb_b_silver_attacks[to];
708       if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
709       if ( IsDiscoverWK( from, to ) );
710       else if ( can_w_piece_capture( ptree, to ) )      { continue; }
711       if ( IsDiscoverBK( from, to ) )                  { continue; }
712         
713       XorFile( from, OCCUPIED_FILE );
714       XorDiag2( from, OCCUPIED_DIAG2 );
715       XorDiag1( from, OCCUPIED_DIAG1 );
716       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
717       BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
718       BB_BSILVER.p[1] ^= abb_mask[from].p[1];
719       BB_BSILVER.p[2] ^= abb_mask[from].p[2];
720       return ( To2Move(to) | From2Move(from)
721                | Cap2Move(-BOARD[to]) | Piece2Move(silver) );
722     } while ( bb_check.p[1] | bb_check.p[2] );
723
724     XorFile( from, OCCUPIED_FILE );
725     XorDiag2( from, OCCUPIED_DIAG2 );
726     XorDiag1( from, OCCUPIED_DIAG1 );
727     BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
728     BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
729     BB_BSILVER.p[1] ^= abb_mask[from].p[1];
730     BB_BSILVER.p[2] ^= abb_mask[from].p[2];
731   }
732
733   BBAnd( bb, BB_BKNIGHT, b_chk_tbl[SQ_WKING].knight );
734   while ( BBToU(bb) ) {
735     from = FirstOne( bb );
736     Xor( from, bb );
737
738     bb_check.p[0] = bb_move.p[0] & abb_b_knight_attacks[from].p[0]
739       & abb_w_gold_attacks[SQ_WKING].p[0];
740
741     if ( bb_check.p[0] ) {
742       BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
743       BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
744       BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
745       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
746       XorFile( from, OCCUPIED_FILE );
747       XorDiag2( from, OCCUPIED_DIAG2 );
748       XorDiag1( from, OCCUPIED_DIAG1 );
749
750       do {
751         to = last_one0( bb_check.p[0] );
752         bb_check.p[0] ^= abb_mask[to].p[0];
753       
754         if ( ! is_white_attacked( ptree, to ) ) { continue; }
755       
756         bb_attacks = abb_b_gold_attacks[to];
757         if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
758         if ( IsDiscoverWK( from, to ) );
759         else if ( can_w_piece_capture( ptree, to ) )      { continue; }
760         if ( IsDiscoverBK( from, to ) )                  { continue; }
761       
762         XorFile( from, OCCUPIED_FILE );
763         XorDiag2( from, OCCUPIED_DIAG2 );
764         XorDiag1( from, OCCUPIED_DIAG1 );
765         BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
766         BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
767         BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
768         BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
769         return ( To2Move(to) | From2Move(from) | FLAG_PROMO
770                  | Cap2Move(-BOARD[to]) | Piece2Move(knight) );
771       } while ( bb_check.p[0] );
772
773       XorFile( from, OCCUPIED_FILE );
774       XorDiag2( from, OCCUPIED_DIAG2 );
775       XorDiag1( from, OCCUPIED_DIAG1 );
776       BB_BOCCUPY.p[0] ^= abb_mask[from].p[0];
777       BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
778       BB_BKNIGHT.p[0] ^= abb_mask[from].p[0];
779       BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
780     } else {
781
782       BBAnd( bb_check, bb_move, abb_b_knight_attacks[from] );
783       BBAnd( bb_check, bb_check, abb_w_knight_attacks[SQ_WKING] );
784       
785       if ( BBToU(bb_check) ) {
786         BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
787         BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
788         BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
789         BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
790         XorFile( from, OCCUPIED_FILE );
791         XorDiag2( from, OCCUPIED_DIAG2 );
792         XorDiag1( from, OCCUPIED_DIAG1 );
793         
794         do {
795           to = FirstOne( bb_check );
796           Xor( to, bb_check );
797       
798           BBIni( bb_attacks );
799           if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
800           if ( IsDiscoverWK( from, to ) );
801           else if ( can_w_piece_capture( ptree, to ) )      { continue; }
802           if ( IsDiscoverBK( from, to ) )                  { continue; }
803       
804           XorFile( from, OCCUPIED_FILE );
805           XorDiag2( from, OCCUPIED_DIAG2 );
806           XorDiag1( from, OCCUPIED_DIAG1 );
807           BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
808           BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
809           BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
810           BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
811           return ( To2Move(to) | From2Move(from)
812                    | Cap2Move(-BOARD[to]) | Piece2Move(knight) );
813         } while ( BBToU(bb_check) );
814
815         XorFile( from, OCCUPIED_FILE );
816         XorDiag2( from, OCCUPIED_DIAG2 );
817         XorDiag1( from, OCCUPIED_DIAG1 );
818         BB_BOCCUPY.p[1] ^= abb_mask[from].p[1];
819         BB_BOCCUPY.p[2] ^= abb_mask[from].p[2];
820         BB_BKNIGHT.p[1] ^= abb_mask[from].p[1];
821         BB_BKNIGHT.p[2] ^= abb_mask[from].p[2];
822       }
823     }
824   }
825
826   BBAnd( bb, BB_BLANCE, b_chk_tbl[SQ_WKING].lance );
827   while ( BBToU(bb) ) {
828     from = FirstOne( bb );
829     Xor( from, bb );
830
831     bb_attacks = AttackFile(from);
832     BBAnd( bb_attacks, bb_attacks, abb_minus_rays[from] );
833     BBAnd( bb_attacks, bb_attacks, bb_move );
834
835     BBAnd( bb_check, bb_attacks, abb_mask[SQ_WKING+nfile] );
836     bb_check_pro.p[0] = bb_attacks.p[0] & abb_w_gold_attacks[SQ_WKING].p[0];
837
838     if ( ! ( bb_check_pro.p[0] | bb_check.p[0]
839              | bb_check.p[1] | bb_check.p[2] ) ) { continue; }
840
841     Xor( from, BB_BLANCE );
842     Xor( from, BB_BOCCUPY );
843     XorFile( from, OCCUPIED_FILE );
844     XorDiag2( from, OCCUPIED_DIAG2 );
845     XorDiag1( from, OCCUPIED_DIAG1 );
846
847     bb_check.p[0] &= 0x1ffU;
848     if ( BBToU(bb_check) ) {
849
850       to = SQ_WKING+nfile;
851       if ( ! is_white_attacked( ptree, to ) ) {
852         bb_check.p[0] &= ~abb_mask[to].p[0];
853         goto b_lance_next;
854       }
855       bb_temp = abb_file_attacks[to][0];
856       if ( can_w_king_escape( ptree, to, bb_temp ) ) { goto b_lance_next; }
857       if ( IsDiscoverWK( from, to ) );
858       else if ( can_w_piece_capture( ptree, to ) )   { goto b_lance_next; }
859       if ( IsDiscoverBK( from, to ) )               { goto b_lance_next; }
860       
861       XorFile( from, OCCUPIED_FILE );
862       XorDiag2( from, OCCUPIED_DIAG2 );
863       XorDiag1( from, OCCUPIED_DIAG1 );
864       Xor( from, BB_BOCCUPY );
865       Xor( from, BB_BLANCE );
866       return ( To2Move(to) | From2Move(from)
867                | Cap2Move(-BOARD[to]) | Piece2Move(lance) );
868     }
869     
870   b_lance_next:
871     while ( bb_check_pro.p[0] )
872       {
873         to = last_one0( bb_check_pro.p[0] );
874         bb_check_pro.p[0] ^= abb_mask[to].p[0];
875         
876         if ( ! is_white_attacked( ptree, to ) ) { continue; }
877         
878         bb_attacks = abb_b_gold_attacks[to];
879         if ( can_w_king_escape( ptree, to, bb_attacks ) ) { continue; }
880         if ( IsDiscoverWK( from, to ) );
881         else if ( can_w_piece_capture( ptree, to ) )      { continue; }
882         if ( IsDiscoverBK( from, to ) )                  { continue; }
883         
884         XorFile( from, OCCUPIED_FILE );
885         XorDiag2( from, OCCUPIED_DIAG2 );
886         XorDiag1( from, OCCUPIED_DIAG1 );
887         Xor( from, BB_BOCCUPY );
888         Xor( from, BB_BLANCE );
889         return ( To2Move(to) | From2Move(from) | FLAG_PROMO
890                  | Cap2Move(-BOARD[to]) | Piece2Move(lance) );
891       }
892     
893     XorFile( from, OCCUPIED_FILE );
894     XorDiag2( from, OCCUPIED_DIAG2 );
895     XorDiag1( from, OCCUPIED_DIAG1 );
896     Xor( from, BB_BOCCUPY );
897     Xor( from, BB_BLANCE );
898   }
899
900   bb_check.p[0] = bb_move.p[0] & BB_BPAWN_ATK.p[0]
901     & abb_w_gold_attacks[SQ_WKING].p[0];
902   while ( bb_check.p[0] ) {
903     to   = last_one0( bb_check.p[0] );
904     from = to + nfile;
905     bb_check.p[0] ^= abb_mask[to].p[0];
906
907     BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
908     BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
909     BB_BOCCUPY.p[0]   ^= abb_mask[from].p[0];
910     BB_BOCCUPY.p[1]   ^= abb_mask[from].p[1];
911     XorFile( from, OCCUPIED_FILE );
912     XorDiag2( from, OCCUPIED_DIAG2 );
913     XorDiag1( from, OCCUPIED_DIAG1 );
914
915     if ( ! is_white_attacked( ptree, to ) )         { goto b_pawn_pro_next; }
916     bb_attacks = abb_b_gold_attacks[to];
917     if ( can_w_king_escape( ptree,to,bb_attacks ) ) { goto b_pawn_pro_next; }
918     if ( IsDiscoverWK( from, to ) );
919     else if ( can_w_piece_capture( ptree, to ) )    { goto b_pawn_pro_next; }
920     if ( IsDiscoverBK( from, to ) )                { goto b_pawn_pro_next; }
921     
922     XorFile( from, OCCUPIED_FILE );
923     XorDiag2( from, OCCUPIED_DIAG2 );
924     XorDiag1( from, OCCUPIED_DIAG1 );
925     BB_BOCCUPY.p[0]   ^= abb_mask[from].p[0];
926     BB_BOCCUPY.p[1]   ^= abb_mask[from].p[1];
927     BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
928     BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
929     return ( To2Move(to) | From2Move(from) | FLAG_PROMO
930              | Cap2Move(-BOARD[to]) | Piece2Move(pawn) );
931
932   b_pawn_pro_next:
933     XorFile( from, OCCUPIED_FILE );
934     XorDiag2( from, OCCUPIED_DIAG2 );
935     XorDiag1( from, OCCUPIED_DIAG1 );
936     BB_BOCCUPY.p[0]   ^= abb_mask[from].p[0];
937     BB_BOCCUPY.p[1]   ^= abb_mask[from].p[1];
938     BB_BPAWN_ATK.p[0] ^= abb_mask[to].p[0];
939     BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
940   }
941
942   if ( SQ_WKING >= A7 && SQ_WKING <= I3 ) {
943     to   = SQ_WKING + nfile;
944     from = to        + nfile;
945     if ( BOARD[from] == pawn && BOARD[to] <= 0 ) {
946
947       BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
948       BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
949       BB_BOCCUPY.p[1]   ^= abb_mask[from].p[1];
950       BB_BOCCUPY.p[2]   ^= abb_mask[from].p[2];
951       XorFile( from, OCCUPIED_FILE );
952       XorDiag2( from, OCCUPIED_DIAG2 );
953       XorDiag1( from, OCCUPIED_DIAG1 );
954       
955       if ( ! is_white_attacked( ptree, to ) )         { goto b_pawn_end; }
956       BBIni( bb_attacks );
957       if ( can_w_king_escape( ptree,to,bb_attacks ) ) { goto b_pawn_end; }
958       if ( can_w_piece_capture( ptree, to ) )         { goto b_pawn_end; }
959       if ( IsDiscoverBK( from, to ) )                { goto b_pawn_end; }
960       
961       XorFile( from, OCCUPIED_FILE );
962       XorDiag2( from, OCCUPIED_DIAG2 );
963       XorDiag1( from, OCCUPIED_DIAG1 );
964       BB_BOCCUPY.p[1]   ^= abb_mask[from].p[1];
965       BB_BOCCUPY.p[2]   ^= abb_mask[from].p[2];
966       BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
967       BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
968       return ( To2Move(to) | From2Move(from)
969                | Cap2Move(-BOARD[to]) | Piece2Move(pawn) );
970       
971     b_pawn_end:
972       XorFile( from, OCCUPIED_FILE );
973       XorDiag2( from, OCCUPIED_DIAG2 );
974       XorDiag1( from, OCCUPIED_DIAG1 );
975       BB_BOCCUPY.p[1]   ^= abb_mask[from].p[1];
976       BB_BOCCUPY.p[2]   ^= abb_mask[from].p[2];
977       BB_BPAWN_ATK.p[1] ^= abb_mask[to].p[1];
978       BB_BPAWN_ATK.p[2] ^= abb_mask[to].p[2];
979     }
980   }
981
982   return 0;
983 }
984
985
986 unsigned int
987 is_w_mate_in_1ply( tree_t * restrict ptree )
988 {
989   bitboard_t bb, bb_temp, bb_check, bb_check_pro, bb_attacks, bb_drop, bb_move;
990   unsigned int ubb;
991   int to, from, idirec;
992
993   assert( ! is_white_attacked( ptree, SQ_WKING ) );
994
995   /* Drops */
996   BBOr( bb_drop, BB_BOCCUPY, BB_WOCCUPY );
997   BBNot( bb_drop, bb_drop );
998
999   if ( IsHandRook(HAND_W) ) {
1000
1001     BBAnd( bb, abb_w_gold_attacks[SQ_BKING],
1002            abb_b_gold_attacks[SQ_BKING] );
1003     BBAnd( bb, bb, bb_drop );
1004     while( BBToU(bb) )
1005       {
1006         to = LastOne( bb );
1007         Xor( to, bb );
1008
1009         if ( ! is_black_attacked( ptree, to ) ) { continue; }
1010         
1011         bb_attacks                     = abb_file_attacks[to][0];
1012         bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1013         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1014         if ( can_b_piece_capture( ptree, to ) )           { continue; }
1015         return To2Move(to) | Drop2Move(rook);
1016       }
1017
1018   } else if ( IsHandLance(HAND_W) && SQ_BKING >= A8 ) {
1019
1020     to = SQ_BKING-nfile;
1021     if ( ( ! BOARD[to] ) && is_black_attacked( ptree, to ) )
1022       {
1023         bb_attacks = abb_file_attacks[to][0];
1024         if ( ( ! can_b_king_escape( ptree, to, bb_attacks ) )
1025              && ( ! can_b_piece_capture( ptree, to ) ) )
1026           {
1027             return To2Move(to) | Drop2Move(lance);
1028           }
1029       }
1030   }
1031
1032   if ( IsHandBishop(HAND_W) ) {
1033
1034     BBAnd( bb, abb_w_silver_attacks[SQ_BKING],
1035            abb_b_silver_attacks[SQ_BKING] );
1036     BBAnd( bb, bb, bb_drop );
1037     while( BBToU(bb) )
1038       {
1039         to = LastOne( bb );
1040         Xor( to, bb );
1041
1042         if ( ! is_black_attacked( ptree, to ) ) { continue; }
1043         
1044         BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1045               abb_bishop_attacks_rl45[to][0] );
1046         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1047         if ( can_b_piece_capture( ptree, to ) )           { continue; }
1048         return To2Move(to) | Drop2Move(bishop);
1049       }
1050   }
1051
1052   if ( IsHandGold(HAND_W) ) {
1053     
1054     if ( IsHandRook(HAND_W) )
1055       {
1056         BBAnd( bb, abb_w_gold_attacks[SQ_BKING],
1057                abb_w_silver_attacks[SQ_BKING] );
1058         BBNot( bb, bb );
1059         BBAnd( bb, bb, bb_drop );
1060         BBAnd( bb, bb, abb_b_gold_attacks[SQ_BKING] );
1061       }
1062     else { BBAnd( bb, bb_drop, abb_b_gold_attacks[SQ_BKING] ); }
1063
1064     while ( BBToU(bb) )
1065       {
1066         to = LastOne( bb );
1067         Xor( to, bb );
1068         
1069         if ( ! is_black_attacked( ptree, to ) ) { continue; }
1070         
1071         bb_attacks = abb_w_gold_attacks[to];
1072         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1073         if ( can_b_piece_capture( ptree, to ) )           { continue; }
1074         return To2Move(to) | Drop2Move(gold);
1075       }
1076   }
1077   
1078   if ( IsHandSilver(HAND_W) ) {
1079     
1080     if ( IsHandGold(HAND_W) )
1081       {
1082         if ( IsHandBishop(HAND_W) ) { goto w_silver_drop_end; }
1083         BBNot( bb, abb_b_gold_attacks[SQ_BKING] );
1084         BBAnd( bb, bb, abb_b_silver_attacks[SQ_BKING] );
1085         BBAnd( bb, bb, bb_drop );
1086       }
1087     else {
1088       BBAnd( bb, bb_drop, abb_b_silver_attacks[SQ_BKING] );
1089       if ( IsHandBishop(HAND_W) )
1090         {
1091           BBAnd( bb, bb, abb_b_gold_attacks[SQ_BKING] );
1092         }
1093     }
1094     
1095     while ( BBToU(bb) )
1096       {
1097         to = LastOne( bb );
1098         Xor( to, bb );
1099         
1100         if ( ! is_black_attacked( ptree, to ) ) { continue; }
1101         
1102         bb_attacks = abb_w_silver_attacks[to];
1103         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1104         if ( can_b_piece_capture( ptree, to ) )           { continue; }
1105         return To2Move(to) | Drop2Move(silver);
1106       }
1107   }
1108  w_silver_drop_end:
1109   
1110   if ( IsHandKnight(HAND_W) ) {
1111     
1112     BBAnd( bb, bb_drop, abb_b_knight_attacks[SQ_BKING] );
1113     while ( BBToU(bb) )
1114       {
1115         to = LastOne( bb );
1116         Xor( to, bb );
1117         
1118         BBIni( bb_attacks );
1119         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1120         if ( can_b_piece_capture( ptree, to ) )           { continue; }
1121         return To2Move(to) | Drop2Move(knight);
1122       }
1123   }
1124
1125   /* Moves */
1126   BBNot( bb_move, BB_WOCCUPY );
1127
1128   bb = BB_WDRAGON;
1129   while ( BBToU(bb) ) {
1130     from = LastOne( bb );
1131     Xor( from, bb );
1132
1133     AttackDragon( bb_attacks, from );
1134     BBAnd( bb_check, bb_move,  bb_attacks );
1135     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1136     if ( ! BBToU(bb_check) ) { continue; }
1137
1138     Xor( from, BB_W_HDK );
1139     Xor( from, BB_W_RD );
1140     Xor( from, BB_WOCCUPY );
1141     XorFile( from, OCCUPIED_FILE );
1142     XorDiag2( from, OCCUPIED_DIAG2 );
1143     XorDiag1( from, OCCUPIED_DIAG1 );
1144
1145     do {
1146       to = LastOne( bb_check );
1147       Xor( to, bb_check );
1148
1149       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1150         
1151       if ( (int)adirec[SQ_BKING][to] & flag_cross )
1152         {
1153           bb_attacks = abb_file_attacks[to][0];
1154           bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1155           BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1156         }
1157       else { AttackDragon( bb_attacks, to ); }
1158
1159       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1160       if ( IsDiscoverBK( from, to ) );
1161       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1162       if ( IsDiscoverWK( from, to ) )                  { continue; }
1163         
1164       XorFile( from, OCCUPIED_FILE );
1165       XorDiag2( from, OCCUPIED_DIAG2 );
1166       XorDiag1( from, OCCUPIED_DIAG1 );
1167       Xor( from, BB_WOCCUPY );
1168       Xor( from, BB_W_RD );
1169       Xor( from, BB_W_HDK );
1170       return ( To2Move(to) | From2Move(from)
1171                | Cap2Move(BOARD[to]) | Piece2Move(dragon) );
1172     } while ( BBToU(bb_check) );
1173
1174     XorFile( from, OCCUPIED_FILE );
1175     XorDiag2( from, OCCUPIED_DIAG2 );
1176     XorDiag1( from, OCCUPIED_DIAG1 );
1177     Xor( from, BB_WOCCUPY );
1178     Xor( from, BB_W_RD );
1179     Xor( from, BB_W_HDK );
1180   }
1181
1182   bb.p[2] = BB_WROOK.p[2];
1183   while ( bb.p[2] ) {
1184     from = first_one2( bb.p[2] );
1185     bb.p[2] ^= abb_mask[from].p[2];
1186
1187     AttackRook( bb_attacks, from );
1188     BBAnd( bb_check, bb_move, bb_attacks );
1189     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1190     if ( ! BBToU(bb_check) ) { continue; }
1191
1192     BB_W_RD.p[2]    ^= abb_mask[from].p[2];
1193     BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1194     XorFile( from, OCCUPIED_FILE );
1195     XorDiag2( from, OCCUPIED_DIAG2 );
1196     XorDiag1( from, OCCUPIED_DIAG1 );
1197
1198     do {
1199       to = LastOne( bb_check );
1200       Xor( to, bb_check );
1201
1202       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1203         
1204       if ( (int)adirec[SQ_BKING][to] & flag_cross )
1205         {
1206           bb_attacks = abb_file_attacks[to][0];
1207           bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1208           BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1209         }
1210       else { AttackDragon( bb_attacks, to ); }
1211
1212       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1213       if ( IsDiscoverBK( from, to ) );
1214       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1215       if ( IsDiscoverWK( from, to ) )                  { continue; }
1216         
1217       XorFile( from, OCCUPIED_FILE );
1218       XorDiag2( from, OCCUPIED_DIAG2 );
1219       XorDiag1( from, OCCUPIED_DIAG1 );
1220       BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1221       BB_W_RD.p[2]    ^= abb_mask[from].p[2];
1222       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1223                | Cap2Move(BOARD[to]) | Piece2Move(rook) );
1224     } while ( BBToU(bb_check) );
1225
1226     XorFile( from, OCCUPIED_FILE );
1227     XorDiag2( from, OCCUPIED_DIAG2 );
1228     XorDiag1( from, OCCUPIED_DIAG1 );
1229     BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1230     BB_W_RD.p[2]    ^= abb_mask[from].p[2];
1231   }
1232
1233   bb.p[0] = BB_WROOK.p[0];
1234   bb.p[1] = BB_WROOK.p[1];
1235   while ( bb.p[0] | bb.p[1] ) {
1236     from = last_one01( bb.p[0], bb.p[1] );
1237     bb.p[0] ^= abb_mask[from].p[0];
1238     bb.p[1] ^= abb_mask[from].p[1];
1239
1240     AttackRook( bb_attacks, from );
1241     BBAnd( bb_check, bb_move, bb_attacks );
1242     bb_check.p[0] &= abb_b_gold_attacks[SQ_BKING].p[0];
1243     bb_check.p[1] &= abb_b_gold_attacks[SQ_BKING].p[1];
1244     bb_check.p[0] &= abb_w_gold_attacks[SQ_BKING].p[0];
1245     bb_check.p[1] &= abb_w_gold_attacks[SQ_BKING].p[1];
1246     bb_check.p[2] &= abb_king_attacks[SQ_BKING].p[2];
1247     if ( ! BBToU(bb_check) ) { continue; }
1248
1249     BB_W_RD.p[0]    ^= abb_mask[from].p[0];
1250     BB_W_RD.p[1]    ^= abb_mask[from].p[1];
1251     BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1252     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1253     XorFile( from, OCCUPIED_FILE );
1254     XorDiag2( from, OCCUPIED_DIAG2 );
1255     XorDiag1( from, OCCUPIED_DIAG1 );
1256
1257     do {
1258       to = LastOne( bb_check );
1259       Xor( to, bb_check );
1260
1261       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1262         
1263       if ( to >= A3 ) {
1264         if ( (int)adirec[SQ_BKING][to] & flag_cross )
1265           {
1266             bb_attacks = abb_file_attacks[to][0];
1267             bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1268             bb_attacks.p[1] |= abb_king_attacks[to].p[1];
1269             bb_attacks.p[2] |= abb_king_attacks[to].p[2];
1270           }
1271         else { AttackDragon( bb_attacks, to ); }
1272       } else {
1273         bb_attacks = abb_file_attacks[to][0];
1274         bb_attacks.p[aslide[to].ir0] |= ai_rook_attacks_r0[to][0];
1275       }
1276       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1277       if ( IsDiscoverBK( from, to ) );
1278       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1279       if ( IsDiscoverWK( from, to ) )                  { continue; }
1280         
1281       XorFile( from, OCCUPIED_FILE );
1282       XorDiag2( from, OCCUPIED_DIAG2 );
1283       XorDiag1( from, OCCUPIED_DIAG1 );
1284       BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1285       BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1286       BB_W_RD.p[0]    ^= abb_mask[from].p[0];
1287       BB_W_RD.p[1]    ^= abb_mask[from].p[1];
1288       return ( To2Move(to) | From2Move(from)
1289                | ( (to > I4) ? FLAG_PROMO : 0 )
1290                | Cap2Move(BOARD[to]) | Piece2Move(rook) );
1291     } while ( BBToU(bb_check) );
1292
1293     XorFile( from, OCCUPIED_FILE );
1294     XorDiag2( from, OCCUPIED_DIAG2 );
1295     XorDiag1( from, OCCUPIED_DIAG1 );
1296     BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1297     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1298     BB_W_RD.p[0]    ^= abb_mask[from].p[0];
1299     BB_W_RD.p[1]    ^= abb_mask[from].p[1];
1300   }
1301
1302   bb = BB_WHORSE;
1303   while ( BBToU(bb) ) {
1304     from = LastOne( bb );
1305     Xor( from, bb );
1306
1307     AttackHorse( bb_attacks, from );
1308     BBAnd( bb_check, bb_move,  bb_attacks );
1309     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1310     if ( ! BBToU(bb_check) ) { continue; }
1311
1312     Xor( from, BB_W_HDK );
1313     Xor( from, BB_W_BH );
1314     Xor( from, BB_WOCCUPY );
1315     XorFile( from, OCCUPIED_FILE );
1316     XorDiag2( from, OCCUPIED_DIAG2 );
1317     XorDiag1( from, OCCUPIED_DIAG1 );
1318
1319     do {
1320       to = LastOne( bb_check );
1321       Xor( to, bb_check );
1322
1323       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1324         
1325       BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1326             abb_bishop_attacks_rl45[to][0] );
1327       BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1328       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1329       if ( IsDiscoverBK( from, to ) );
1330       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1331       if ( IsDiscoverWK( from, to ) )                  { continue; }
1332         
1333       XorFile( from, OCCUPIED_FILE );
1334       XorDiag2( from, OCCUPIED_DIAG2 );
1335       XorDiag1( from, OCCUPIED_DIAG1 );
1336       Xor( from, BB_WOCCUPY );
1337       Xor( from, BB_W_BH );
1338       Xor( from, BB_W_HDK );
1339       return ( To2Move(to) | From2Move(from)
1340                | Cap2Move(BOARD[to]) | Piece2Move(horse) );
1341     } while ( BBToU(bb_check) );
1342
1343     XorFile( from, OCCUPIED_FILE );
1344     XorDiag2( from, OCCUPIED_DIAG2 );
1345     XorDiag1( from, OCCUPIED_DIAG1 );
1346     Xor( from, BB_WOCCUPY );
1347     Xor( from, BB_W_BH );
1348     Xor( from, BB_W_HDK );
1349   }
1350
1351   bb.p[2] = BB_WBISHOP.p[2];
1352   while ( bb.p[2] ) {
1353     from = first_one2( bb.p[2] );
1354     bb.p[2] ^= abb_mask[from].p[2];
1355
1356     AttackBishop( bb_attacks, from );
1357     BBAnd( bb_check, bb_move, bb_attacks );
1358     BBAnd( bb_check, bb_check, abb_king_attacks[SQ_BKING] );
1359     if ( ! BBToU(bb_check) ) { continue; }
1360
1361     BB_W_BH.p[2]    ^= abb_mask[from].p[2];
1362     BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1363     XorFile( from, OCCUPIED_FILE );
1364     XorDiag2( from, OCCUPIED_DIAG2 );
1365     XorDiag1( from, OCCUPIED_DIAG1 );
1366
1367     do {
1368       to = LastOne( bb_check );
1369       Xor( to, bb_check );
1370
1371       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1372         
1373       BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1374             abb_bishop_attacks_rl45[to][0] );
1375       BBOr( bb_attacks, bb_attacks, abb_king_attacks[to] );
1376       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1377       if ( IsDiscoverBK( from, to ) );
1378       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1379       if ( IsDiscoverWK( from, to ) )                  { continue; }
1380         
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];
1386       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1387                | Cap2Move(BOARD[to]) | Piece2Move(bishop) );
1388     } while ( BBToU(bb_check) );
1389
1390     XorFile( from, OCCUPIED_FILE );
1391     XorDiag2( from, OCCUPIED_DIAG2 );
1392     XorDiag1( from, OCCUPIED_DIAG1 );
1393     BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1394     BB_W_BH.p[2]    ^= abb_mask[from].p[2];
1395   }
1396
1397   bb.p[0] = BB_WBISHOP.p[0];
1398   bb.p[1] = BB_WBISHOP.p[1];
1399   while ( bb.p[0] | bb.p[1] ) {
1400     from = last_one01( bb.p[0], bb.p[1] );
1401     bb.p[0] ^= abb_mask[from].p[0];
1402     bb.p[1] ^= abb_mask[from].p[1];
1403
1404     AttackBishop( bb_attacks, from );
1405     BBAnd( bb_check, bb_move, bb_attacks );
1406     bb_check.p[0] &= abb_b_silver_attacks[SQ_BKING].p[0];
1407     bb_check.p[1] &= abb_b_silver_attacks[SQ_BKING].p[1];
1408     bb_check.p[0] &= abb_w_silver_attacks[SQ_BKING].p[0];
1409     bb_check.p[1] &= abb_w_silver_attacks[SQ_BKING].p[1];
1410     bb_check.p[2] &= abb_king_attacks[SQ_BKING].p[2];
1411     if ( ! BBToU(bb_check) ) { continue; }
1412
1413     BB_W_BH.p[0]    ^= abb_mask[from].p[0];
1414     BB_W_BH.p[1]    ^= abb_mask[from].p[1];
1415     BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1416     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1417     XorFile( from, OCCUPIED_FILE );
1418     XorDiag2( from, OCCUPIED_DIAG2 );
1419     XorDiag1( from, OCCUPIED_DIAG1 );
1420
1421     do {
1422       to = LastOne( bb_check );
1423       Xor( to, bb_check );
1424
1425       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1426         
1427       BBOr( bb_attacks, abb_bishop_attacks_rr45[to][0],
1428             abb_bishop_attacks_rl45[to][0] );
1429       if ( to >= A3 ) {
1430         bb_attacks.p[1] |= abb_king_attacks[to].p[1];
1431         bb_attacks.p[2] |= abb_king_attacks[to].p[2];
1432       }
1433       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1434       if ( IsDiscoverBK( from, to ) );
1435       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1436       if ( IsDiscoverWK( from, to ) )                  { continue; }
1437         
1438       XorFile( from, OCCUPIED_FILE );
1439       XorDiag2( from, OCCUPIED_DIAG2 );
1440       XorDiag1( from, OCCUPIED_DIAG1 );
1441       BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1442       BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1443       BB_W_BH.p[0]    ^= abb_mask[from].p[0];
1444       BB_W_BH.p[1]    ^= abb_mask[from].p[1];
1445       return ( To2Move(to) | From2Move(from)
1446                | ( (to > I4) ? FLAG_PROMO : 0 )
1447                | Cap2Move(BOARD[to]) | Piece2Move(bishop) );
1448     } while ( BBToU(bb_check) );
1449
1450     XorFile( from, OCCUPIED_FILE );
1451     XorDiag2( from, OCCUPIED_DIAG2 );
1452     XorDiag1( from, OCCUPIED_DIAG1 );
1453     BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1454     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1455     BB_W_BH.p[0]    ^= abb_mask[from].p[0];
1456     BB_W_BH.p[1]    ^= abb_mask[from].p[1];
1457   }
1458
1459   BBAnd( bb, BB_WTGOLD, w_chk_tbl[SQ_BKING].gold );
1460   while ( BBToU(bb) ) {
1461     from = LastOne( bb );
1462     Xor( from, bb );
1463
1464     BBAnd( bb_check, bb_move, abb_w_gold_attacks[from] );
1465     BBAnd( bb_check, bb_check, abb_b_gold_attacks[SQ_BKING] );
1466     if ( ! BBToU(bb_check) ) { continue; }
1467
1468     Xor( from, BB_WTGOLD );
1469     Xor( from, BB_WOCCUPY );
1470     XorFile( from, OCCUPIED_FILE );
1471     XorDiag2( from, OCCUPIED_DIAG2 );
1472     XorDiag1( from, OCCUPIED_DIAG1 );
1473
1474     do {
1475       to = LastOne( bb_check );
1476       Xor( to, bb_check );
1477
1478       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1479         
1480       bb_attacks = abb_w_gold_attacks[to];
1481       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1482       if ( IsDiscoverBK( from, to ) );
1483       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1484       if ( IsDiscoverWK( from, to ) )                  { continue; }
1485         
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 );
1491       return ( To2Move(to) | From2Move(from)
1492                | Cap2Move(BOARD[to]) | Piece2Move(-BOARD[from]) );
1493     } while ( BBToU(bb_check) );
1494
1495     XorFile( from, OCCUPIED_FILE );
1496     XorDiag2( from, OCCUPIED_DIAG2 );
1497     XorDiag1( from, OCCUPIED_DIAG1 );
1498     Xor( from, BB_WOCCUPY );
1499     Xor( from, BB_WTGOLD );
1500   }
1501
1502   BBAnd( bb, BB_WSILVER, w_chk_tbl[SQ_BKING].silver );
1503   while ( bb.p[2] ) {
1504     from = first_one2( bb.p[2] );
1505     bb.p[2] ^= abb_mask[from].p[2];
1506
1507     bb_check_pro.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1508       & abb_b_gold_attacks[SQ_BKING].p[1];
1509     bb_check_pro.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1510       & abb_b_gold_attacks[SQ_BKING].p[2];
1511
1512     bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1513       & abb_b_silver_attacks[SQ_BKING].p[1]
1514       & ~abb_b_gold_attacks[SQ_BKING].p[1];
1515     bb_check.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1516       & abb_b_silver_attacks[SQ_BKING].p[2]
1517       & ~abb_b_gold_attacks[SQ_BKING].p[2];
1518
1519     if ( ! ( bb_check_pro.p[1] | bb_check_pro.p[2]
1520              | bb_check.p[1]| bb_check.p[2] ) ) { continue; }
1521
1522     BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1523     BB_WOCCUPY.p[2]  ^= abb_mask[from].p[2];
1524     XorFile( from, OCCUPIED_FILE );
1525     XorDiag2( from, OCCUPIED_DIAG2 );
1526     XorDiag1( from, OCCUPIED_DIAG1 );
1527
1528     while ( bb_check_pro.p[1] | bb_check_pro.p[2] ) {
1529       to = last_one12( bb_check_pro.p[1], bb_check_pro.p[2] );
1530       bb_check_pro.p[1] ^= abb_mask[to].p[1];
1531       bb_check_pro.p[2] ^= abb_mask[to].p[2];
1532       
1533       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1534       
1535       bb_attacks = abb_w_gold_attacks[to];
1536       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1537       if ( IsDiscoverBK( from, to ) );
1538       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1539       if ( IsDiscoverWK( from, to ) )                  { continue; }
1540       
1541       XorFile( from, OCCUPIED_FILE );
1542       XorDiag2( from, OCCUPIED_DIAG2 );
1543       XorDiag1( from, OCCUPIED_DIAG1 );
1544       BB_WOCCUPY.p[2]  ^= abb_mask[from].p[2];
1545       BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1546       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1547                | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1548     }
1549
1550     while ( bb_check.p[1] | bb_check.p[2] ) {
1551       to = last_one12( bb_check.p[1], bb_check.p[2] );
1552       bb_check.p[1] ^= abb_mask[to].p[1];
1553       bb_check.p[2] ^= abb_mask[to].p[2];
1554       
1555       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1556       
1557       bb_attacks = abb_w_silver_attacks[to];
1558       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1559       if ( IsDiscoverBK( from, to ) );
1560       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1561       if ( IsDiscoverWK( from, to ) )                  { continue; }
1562       
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];
1568       return ( To2Move(to) | From2Move(from)
1569                | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1570     }
1571
1572     XorFile( from, OCCUPIED_FILE );
1573     XorDiag2( from, OCCUPIED_DIAG2 );
1574     XorDiag1( from, OCCUPIED_DIAG1 );
1575     BB_WOCCUPY.p[2]  ^= abb_mask[from].p[2];
1576     BB_WSILVER.p[2] ^= abb_mask[from].p[2];
1577   }
1578
1579   ubb = bb.p[1] & 0x1ffU;
1580   while ( ubb ) {
1581     from = first_one1( ubb );
1582     ubb ^= abb_mask[from].p[1];
1583
1584     bb_check_pro.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1585       & abb_b_gold_attacks[SQ_BKING].p[2];
1586
1587     bb_check.p[2] = bb_move.p[2] & abb_w_silver_attacks[from].p[2]
1588       & abb_b_silver_attacks[SQ_BKING].p[2]
1589       & ~abb_b_gold_attacks[SQ_BKING].p[2];
1590     bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1591       & abb_b_silver_attacks[SQ_BKING].p[1];
1592
1593     if ( ! (bb_check_pro.p[2]|bb_check.p[2]|bb_check.p[1]) ) { continue; }
1594
1595     BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1596     BB_WOCCUPY.p[1]  ^= abb_mask[from].p[1];
1597     XorFile( from, OCCUPIED_FILE );
1598     XorDiag2( from, OCCUPIED_DIAG2 );
1599     XorDiag1( from, OCCUPIED_DIAG1 );
1600
1601     while ( bb_check_pro.p[2] ) {
1602       to = first_one2( bb_check_pro.p[2] );
1603       bb_check_pro.p[2] ^= abb_mask[to].p[2];
1604       
1605       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1606       
1607       bb_attacks = abb_w_gold_attacks[to];
1608       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1609       if ( IsDiscoverBK( from, to ) );
1610       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1611       if ( IsDiscoverWK( from, to ) )                  { continue; }
1612       
1613       XorFile( from, OCCUPIED_FILE );
1614       XorDiag2( from, OCCUPIED_DIAG2 );
1615       XorDiag1( from, OCCUPIED_DIAG1 );
1616       BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1617       BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1618       return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1619                | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1620     }
1621
1622     while ( bb_check.p[1] | bb_check.p[2] ) {
1623       to = last_one12( bb_check.p[1], bb_check.p[2] );
1624       bb_check.p[1] ^= abb_mask[to].p[1];
1625       bb_check.p[2] ^= abb_mask[to].p[2];
1626       
1627       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1628       
1629       bb_attacks = abb_w_silver_attacks[to];
1630       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1631       if ( IsDiscoverBK( from, to ) );
1632       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1633       if ( IsDiscoverWK( from, to ) )                  { continue; }
1634       
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];
1640       return ( To2Move(to) | From2Move(from)
1641                | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1642     }
1643
1644     XorFile( from, OCCUPIED_FILE );
1645     XorDiag2( from, OCCUPIED_DIAG2 );
1646     XorDiag1( from, OCCUPIED_DIAG1 );
1647     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1648     BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1649   }
1650
1651   bb.p[0] = bb.p[0];
1652   bb.p[1] = bb.p[1] & 0x7fffe00U;
1653   while ( bb.p[0] | bb.p[1] ) {
1654     from = last_one01( bb.p[0], bb.p[1] );
1655     bb.p[0] ^= abb_mask[from].p[0];
1656     bb.p[1] ^= abb_mask[from].p[1];
1657
1658     bb_check.p[0] = bb_move.p[0] & abb_w_silver_attacks[from].p[0]
1659       & abb_b_silver_attacks[SQ_BKING].p[0];
1660     bb_check.p[1] = bb_move.p[1] & abb_w_silver_attacks[from].p[1]
1661       & abb_b_silver_attacks[SQ_BKING].p[1];
1662     if ( ! ( bb_check.p[0] | bb_check.p[1] ) ) { continue; }
1663
1664     BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1665     BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1666     BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1667     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1668     XorFile( from, OCCUPIED_FILE );
1669     XorDiag2( from, OCCUPIED_DIAG2 );
1670     XorDiag1( from, OCCUPIED_DIAG1 );
1671
1672     do {
1673       to = last_one01( bb_check.p[0], bb_check.p[1] );
1674       bb_check.p[0] ^= abb_mask[to].p[0];
1675       bb_check.p[1] ^= abb_mask[to].p[1];
1676
1677       if ( ! is_black_attacked( ptree, to ) ) { continue; }
1678         
1679       bb_attacks = abb_w_silver_attacks[to];
1680       if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1681       if ( IsDiscoverBK( from, to ) );
1682       else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1683       if ( IsDiscoverWK( from, to ) )                   { continue; }
1684         
1685       XorFile( from, OCCUPIED_FILE );
1686       XorDiag2( from, OCCUPIED_DIAG2 );
1687       XorDiag1( from, OCCUPIED_DIAG1 );
1688       BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1689       BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1690       BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1691       BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1692       return ( To2Move(to) | From2Move(from)
1693                | Cap2Move(BOARD[to]) | Piece2Move(silver) );
1694     } while ( bb_check.p[0] | bb_check.p[1] );
1695
1696     XorFile( from, OCCUPIED_FILE );
1697     XorDiag2( from, OCCUPIED_DIAG2 );
1698     XorDiag1( from, OCCUPIED_DIAG1 );
1699     BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1700     BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1701     BB_WSILVER.p[0] ^= abb_mask[from].p[0];
1702     BB_WSILVER.p[1] ^= abb_mask[from].p[1];
1703   }
1704
1705   BBAnd( bb, BB_WKNIGHT, w_chk_tbl[SQ_BKING].knight );
1706   while ( BBToU(bb) ) {
1707     from = LastOne( bb );
1708     Xor( from, bb );
1709
1710     bb_check.p[2] = bb_move.p[2] & abb_w_knight_attacks[from].p[2]
1711       & abb_b_gold_attacks[SQ_BKING].p[2];
1712
1713     if ( bb_check.p[2] ) {
1714       BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1715       BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1716       BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1717       BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1718       XorFile( from, OCCUPIED_FILE );
1719       XorDiag2( from, OCCUPIED_DIAG2 );
1720       XorDiag1( from, OCCUPIED_DIAG1 );
1721
1722       do {
1723         to = first_one2( bb_check.p[2] );
1724         bb_check.p[2] ^= abb_mask[to].p[2];
1725       
1726         if ( ! is_black_attacked( ptree, to ) ) { continue; }
1727       
1728         bb_attacks = abb_w_gold_attacks[to];
1729         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1730         if ( IsDiscoverBK( from, to ) );
1731         else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1732         if ( IsDiscoverWK( from, to ) )                   { continue; }
1733       
1734         XorFile( from, OCCUPIED_FILE );
1735         XorDiag2( from, OCCUPIED_DIAG2 );
1736         XorDiag1( from, OCCUPIED_DIAG1 );
1737         BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1738         BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1739         BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1740         BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1741         return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1742                  | Cap2Move(BOARD[to]) | Piece2Move(knight) );
1743       } while ( bb_check.p[2] );
1744
1745       XorFile( from, OCCUPIED_FILE );
1746       XorDiag2( from, OCCUPIED_DIAG2 );
1747       XorDiag1( from, OCCUPIED_DIAG1 );
1748       BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1749       BB_WOCCUPY.p[2] ^= abb_mask[from].p[2];
1750       BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1751       BB_WKNIGHT.p[2] ^= abb_mask[from].p[2];
1752     } else {
1753
1754       BBAnd( bb_check, bb_move, abb_w_knight_attacks[from] );
1755       BBAnd( bb_check, bb_check, abb_b_knight_attacks[SQ_BKING] );
1756       
1757       if ( BBToU(bb_check) ) {
1758         BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1759         BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1760         BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1761         BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1762         XorFile( from, OCCUPIED_FILE );
1763         XorDiag2( from, OCCUPIED_DIAG2 );
1764         XorDiag1( from, OCCUPIED_DIAG1 );
1765         
1766         do {
1767           to = LastOne( bb_check );
1768           Xor( to, bb_check );
1769       
1770           BBIni( bb_attacks );
1771           if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1772           if ( IsDiscoverBK( from, to ) );
1773           else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1774           if ( IsDiscoverWK( from, to ) )                   { continue; }
1775       
1776           XorFile( from, OCCUPIED_FILE );
1777           XorDiag2( from, OCCUPIED_DIAG2 );
1778           XorDiag1( from, OCCUPIED_DIAG1 );
1779           BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1780           BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1781           BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1782           BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1783           return ( To2Move(to) | From2Move(from)
1784                    | Cap2Move(BOARD[to]) | Piece2Move(knight) );
1785         } while ( BBToU(bb_check) );
1786
1787         XorFile( from, OCCUPIED_FILE );
1788         XorDiag2( from, OCCUPIED_DIAG2 );
1789         XorDiag1( from, OCCUPIED_DIAG1 );
1790         BB_WOCCUPY.p[0] ^= abb_mask[from].p[0];
1791         BB_WOCCUPY.p[1] ^= abb_mask[from].p[1];
1792         BB_WKNIGHT.p[0] ^= abb_mask[from].p[0];
1793         BB_WKNIGHT.p[1] ^= abb_mask[from].p[1];
1794       }
1795     }
1796   }
1797
1798   BBAnd( bb, BB_WLANCE, w_chk_tbl[SQ_BKING].lance );
1799   while ( BBToU(bb) ) {
1800     from = LastOne( bb );
1801     Xor( from, bb );
1802
1803     bb_attacks = AttackFile(from);
1804     BBAnd( bb_attacks, bb_attacks, abb_plus_rays[from] );
1805     BBAnd( bb_attacks, bb_attacks, bb_move );
1806
1807     BBAnd( bb_check, bb_attacks, abb_mask[SQ_BKING-nfile] );
1808     bb_check_pro.p[2] = bb_attacks.p[2] & abb_b_gold_attacks[SQ_BKING].p[2];
1809
1810     if ( ! ( bb_check_pro.p[2] | bb_check.p[0]
1811              | bb_check.p[1] | bb_check.p[2] ) ) { continue; }
1812
1813     Xor( from, BB_WLANCE );
1814     Xor( from, BB_WOCCUPY );
1815     XorFile( from, OCCUPIED_FILE );
1816     XorDiag2( from, OCCUPIED_DIAG2 );
1817     XorDiag1( from, OCCUPIED_DIAG1 );
1818
1819     bb_check.p[2] &= 0x7fc0000U;
1820     if ( BBToU(bb_check) ) {
1821
1822       to = SQ_BKING-nfile;
1823       if ( ! is_black_attacked( ptree, to ) ) {
1824         bb_check.p[2] &= ~abb_mask[to].p[2];
1825         goto w_lance_next;
1826       }
1827       bb_temp = abb_file_attacks[to][0];
1828       if ( can_b_king_escape( ptree, to, bb_temp ) ) { goto w_lance_next; }
1829       if ( IsDiscoverBK( from, to ) );
1830       else if ( can_b_piece_capture( ptree, to ) )   { goto w_lance_next; }
1831       if ( IsDiscoverWK( from, to ) )                { goto w_lance_next; }
1832       
1833       XorFile( from, OCCUPIED_FILE );
1834       XorDiag2( from, OCCUPIED_DIAG2 );
1835       XorDiag1( from, OCCUPIED_DIAG1 );
1836       Xor( from, BB_WOCCUPY );
1837       Xor( from, BB_WLANCE );
1838       return ( To2Move(to) | From2Move(from)
1839                | Cap2Move(BOARD[to]) | Piece2Move(lance) );
1840     }
1841     
1842   w_lance_next:
1843     while ( bb_check_pro.p[2] )
1844       {
1845         to = first_one2( bb_check_pro.p[2] );
1846         bb_check_pro.p[2] ^= abb_mask[to].p[2];
1847         
1848         if ( ! is_black_attacked( ptree, to ) ) { continue; }
1849         
1850         bb_attacks = abb_w_gold_attacks[to];
1851         if ( can_b_king_escape( ptree, to, bb_attacks ) ) { continue; }
1852         if ( IsDiscoverBK( from, to ) );
1853         else if ( can_b_piece_capture( ptree, to ) )      { continue; }
1854         if ( IsDiscoverWK( from, to ) )                   { continue; }
1855         
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 );
1861         return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1862                  | Cap2Move(BOARD[to]) | Piece2Move(lance) );
1863       }
1864     
1865     XorFile( from, OCCUPIED_FILE );
1866     XorDiag2( from, OCCUPIED_DIAG2 );
1867     XorDiag1( from, OCCUPIED_DIAG1 );
1868     Xor( from, BB_WOCCUPY );
1869     Xor( from, BB_WLANCE );
1870   }
1871
1872   bb_check.p[2] = bb_move.p[2] & BB_WPAWN_ATK.p[2]
1873     & abb_b_gold_attacks[SQ_BKING].p[2];
1874   while ( bb_check.p[2] ) {
1875     to   = first_one2( bb_check.p[2] );
1876     from = to - nfile;
1877     bb_check.p[2] ^= abb_mask[to].p[2];
1878
1879     BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1880     BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1881     BB_WOCCUPY.p[1]   ^= abb_mask[from].p[1];
1882     BB_WOCCUPY.p[2]   ^= abb_mask[from].p[2];
1883     XorFile( from, OCCUPIED_FILE );
1884     XorDiag2( from, OCCUPIED_DIAG2 );
1885     XorDiag1( from, OCCUPIED_DIAG1 );
1886
1887     if ( ! is_black_attacked( ptree, to ) )         { goto w_pawn_pro_next; }
1888     bb_attacks = abb_w_gold_attacks[to];
1889     if ( can_b_king_escape( ptree,to,bb_attacks ) ) { goto w_pawn_pro_next; }
1890     if ( IsDiscoverBK( from, to ) );
1891     else if ( can_b_piece_capture( ptree, to ) )    { goto w_pawn_pro_next; }
1892     if ( IsDiscoverWK( from, to ) )                 { goto w_pawn_pro_next; }
1893     
1894     XorFile( from, OCCUPIED_FILE );
1895     XorDiag2( from, OCCUPIED_DIAG2 );
1896     XorDiag1( from, OCCUPIED_DIAG1 );
1897     BB_WOCCUPY.p[1]   ^= abb_mask[from].p[1];
1898     BB_WOCCUPY.p[2]   ^= abb_mask[from].p[2];
1899     BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1900     BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1901     return ( To2Move(to) | From2Move(from) | FLAG_PROMO
1902              | Cap2Move(BOARD[to]) | Piece2Move(pawn) );
1903
1904   w_pawn_pro_next:
1905     XorFile( from, OCCUPIED_FILE );
1906     XorDiag2( from, OCCUPIED_DIAG2 );
1907     XorDiag1( from, OCCUPIED_DIAG1 );
1908     BB_WOCCUPY.p[1]   ^= abb_mask[from].p[1];
1909     BB_WOCCUPY.p[2]   ^= abb_mask[from].p[2];
1910     BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1911     BB_WPAWN_ATK.p[2] ^= abb_mask[to].p[2];
1912   }
1913
1914   if ( SQ_BKING <= I3 && SQ_BKING >= A7 ) {
1915     to   = SQ_BKING - nfile;
1916     from = to        - nfile;
1917     if ( BOARD[from] == -pawn && BOARD[to] >= 0 ) {
1918
1919       BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1920       BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1921       BB_WOCCUPY.p[0]   ^= abb_mask[from].p[0];
1922       BB_WOCCUPY.p[1]   ^= abb_mask[from].p[1];
1923       XorFile( from, OCCUPIED_FILE );
1924       XorDiag2( from, OCCUPIED_DIAG2 );
1925       XorDiag1( from, OCCUPIED_DIAG1 );
1926       
1927       if ( ! is_black_attacked( ptree, to ) )         { goto w_pawn_end; }
1928       BBIni( bb_attacks );
1929       if ( can_b_king_escape( ptree,to,bb_attacks ) ) { goto w_pawn_end; }
1930       if ( can_b_piece_capture( ptree, to ) )         { goto w_pawn_end; }
1931       if ( IsDiscoverWK( from, to ) )                 { goto w_pawn_end; }
1932       
1933       XorFile( from, OCCUPIED_FILE );
1934       XorDiag2( from, OCCUPIED_DIAG2 );
1935       XorDiag1( from, OCCUPIED_DIAG1 );
1936       BB_WOCCUPY.p[0]   ^= abb_mask[from].p[0];
1937       BB_WOCCUPY.p[1]   ^= abb_mask[from].p[1];
1938       BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1939       BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1940       return ( To2Move(to) | From2Move(from)
1941                | Cap2Move(BOARD[to]) | Piece2Move(pawn) );
1942       
1943     w_pawn_end:
1944       XorFile( from, OCCUPIED_FILE );
1945       XorDiag2( from, OCCUPIED_DIAG2 );
1946       XorDiag1( from, OCCUPIED_DIAG1 );
1947       BB_WOCCUPY.p[0]   ^= abb_mask[from].p[0];
1948       BB_WOCCUPY.p[1]   ^= abb_mask[from].p[1];
1949       BB_WPAWN_ATK.p[0] ^= abb_mask[to].p[0];
1950       BB_WPAWN_ATK.p[1] ^= abb_mask[to].p[1];
1951     }
1952   }
1953
1954   return 0;
1955 }
1956
1957
1958 static int
1959 can_w_piece_capture( const tree_t * restrict ptree, int to )
1960 {
1961   bitboard_t bb_sum, bb, bb_attacks;
1962   int idirec, from;
1963   
1964   from = to-nfile;
1965   if ( to >= A8 && BOARD[from] == -pawn )
1966     {
1967       if ( IsDiscoverWK(from,to) );
1968       else { return 1; }
1969     }
1970   
1971   BBAnd( bb_sum, BB_WKNIGHT, abb_b_knight_attacks[to] );
1972   
1973   BBAnd( bb, BB_WSILVER, abb_b_silver_attacks[to] );
1974   BBOr( bb_sum, bb, bb_sum );
1975   
1976   BBAnd( bb, BB_WTGOLD, abb_b_gold_attacks[to] );
1977   BBOr( bb_sum, bb, bb_sum );
1978
1979   BBOr( bb, BB_WHORSE, BB_WDRAGON );
1980   BBAnd( bb, bb, abb_king_attacks[to] );
1981   BBOr( bb_sum, bb, bb_sum );
1982   
1983   AttackBishop( bb, to );
1984   BBAnd( bb, BB_W_BH, bb );
1985   BBOr( bb_sum, bb, bb_sum );
1986
1987   bb_sum.p[aslide[to].ir0] |= BB_W_RD.p[aslide[to].ir0] & AttackRank(to);
1988
1989   BBAnd( bb, BB_WLANCE, abb_minus_rays[to] );
1990   BBOr( bb, bb, BB_W_RD );
1991   bb_attacks = AttackFile( to );
1992   BBAnd( bb, bb, bb_attacks );
1993   BBOr( bb_sum, bb_sum, bb );
1994
1995   while ( BBToU( bb_sum ) )
1996     {
1997       from  = FirstOne( bb_sum );
1998       Xor( from, bb_sum );
1999
2000       if ( IsDiscoverWK(from,to) ) { continue; }
2001       return 1;
2002     }
2003
2004   return 0;
2005 }
2006
2007
2008 static int
2009 can_b_piece_capture( const tree_t * restrict ptree, int to )
2010 {
2011   bitboard_t bb_sum, bb, bb_attacks;
2012   int idirec, from;
2013
2014   from = to+nfile;
2015   if ( to <= I2 && BOARD[from] == pawn )
2016     {
2017       if ( IsDiscoverBK(from,to) );
2018       else { return 1; }
2019     }
2020
2021   BBAnd( bb_sum, BB_BKNIGHT, abb_w_knight_attacks[to] );
2022
2023   BBAnd( bb, BB_BSILVER, abb_w_silver_attacks[to] );
2024   BBOr( bb_sum, bb_sum, bb );
2025
2026   BBAnd( bb, BB_BTGOLD, abb_w_gold_attacks[to] );
2027   BBOr( bb_sum, bb_sum, bb );
2028
2029   BBOr( bb, BB_BHORSE, BB_BDRAGON );
2030   BBAnd( bb, bb, abb_king_attacks[to] );
2031   BBOr( bb_sum, bb_sum, bb );
2032   
2033   AttackBishop( bb, to );
2034   BBAnd( bb, bb, BB_B_BH );
2035   BBOr( bb_sum, bb_sum, bb );
2036
2037   bb_sum.p[aslide[to].ir0] |= BB_B_RD.p[aslide[to].ir0] & AttackRank(to);
2038
2039   BBAnd( bb, BB_BLANCE, abb_plus_rays[to] );
2040   BBOr( bb, bb, BB_B_RD );
2041   bb_attacks = AttackFile( to );
2042   BBAnd( bb, bb, bb_attacks );
2043   BBOr( bb_sum, bb_sum, bb );
2044
2045   while ( BBToU( bb_sum ) )
2046     {
2047       from  = LastOne( bb_sum );
2048       Xor( from, bb_sum );
2049
2050       if ( IsDiscoverBK( from, to ) ) { continue; }
2051       return 1;
2052     }
2053
2054   return 0;
2055 }
2056
2057
2058 static int
2059 can_w_king_escape( tree_t * restrict ptree, int to, bitboard_t bb )
2060 {
2061   int iret = 0, iescape;
2062
2063   if ( !BOARD[to] )
2064     {
2065       Xor( to, BB_BOCCUPY );
2066       XorFile( to, OCCUPIED_FILE );
2067       XorDiag2( to, OCCUPIED_DIAG2 );
2068       XorDiag1( to, OCCUPIED_DIAG1 );
2069     }
2070   Xor( SQ_WKING, BB_WOCCUPY );
2071   XorFile( SQ_WKING, OCCUPIED_FILE );
2072   XorDiag2( SQ_WKING, OCCUPIED_DIAG2 );
2073   XorDiag1( SQ_WKING, OCCUPIED_DIAG1 );
2074
2075   BBOr( bb, bb, abb_mask[to] );
2076   BBOr( bb, bb, BB_WOCCUPY );
2077   BBNot( bb, bb );
2078   BBAnd( bb, bb, abb_king_attacks[SQ_WKING] );
2079   
2080   while( BBToU(bb) )
2081     {
2082       iescape = FirstOne( bb );
2083       if ( ! is_white_attacked( ptree, iescape ) )
2084         {
2085           iret = 1;
2086           break;
2087         }
2088       Xor( iescape, bb );
2089     }
2090
2091   XorFile( SQ_WKING, OCCUPIED_FILE );
2092   XorDiag2( SQ_WKING, OCCUPIED_DIAG2 );
2093   XorDiag1( SQ_WKING, OCCUPIED_DIAG1 );
2094   Xor( SQ_WKING, BB_WOCCUPY );
2095   if ( !BOARD[to] )
2096     {
2097       Xor( to, BB_BOCCUPY );
2098       XorFile( to, OCCUPIED_FILE );
2099       XorDiag2( to, OCCUPIED_DIAG2 );
2100       XorDiag1( to, OCCUPIED_DIAG1 );
2101     }
2102
2103   return iret;
2104 }
2105
2106
2107 static int
2108 can_b_king_escape( tree_t * restrict ptree, int to, bitboard_t bb )
2109 {
2110   int iret = 0, iescape;
2111
2112   if ( !BOARD[to] )
2113     {
2114       Xor( to, BB_WOCCUPY );
2115       XorFile( to, OCCUPIED_FILE );
2116       XorDiag2( to, OCCUPIED_DIAG2 );
2117       XorDiag1( to, OCCUPIED_DIAG1 );
2118     }
2119
2120   Xor( SQ_BKING, BB_BOCCUPY );
2121   XorFile( SQ_BKING, OCCUPIED_FILE );
2122   XorDiag2( SQ_BKING, OCCUPIED_DIAG2 );
2123   XorDiag1( SQ_BKING, OCCUPIED_DIAG1 );
2124
2125   BBOr( bb, bb, abb_mask[to] );
2126   BBOr( bb, bb, BB_BOCCUPY );
2127   BBNot( bb, bb );
2128   BBAnd( bb, bb, abb_king_attacks[SQ_BKING] );
2129   
2130   while( BBToU(bb) )
2131     {
2132       iescape = LastOne( bb );
2133       if ( ! is_black_attacked( ptree, iescape ) )
2134         {
2135           iret = 1;
2136           break;
2137         }
2138       Xor( iescape, bb );
2139     }
2140
2141   XorFile( SQ_BKING, OCCUPIED_FILE );
2142   XorDiag2( SQ_BKING, OCCUPIED_DIAG2 );
2143   XorDiag1( SQ_BKING, OCCUPIED_DIAG1 );
2144   Xor( SQ_BKING, BB_BOCCUPY );
2145
2146   if ( !BOARD[to] )
2147     {
2148       XorFile( to, OCCUPIED_FILE );
2149       XorDiag2( to, OCCUPIED_DIAG2 );
2150       XorDiag1( to, OCCUPIED_DIAG1 );
2151       Xor( to, BB_WOCCUPY );
2152     }
2153
2154   return iret;
2155 }