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