Fix pondering in XBoard mode
[bonanza.git] / genevasn.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "shogi.h"
4
5
6 unsigned int *
7 b_gen_evasion( tree_t * restrict ptree, unsigned int * restrict pmove )
8 {
9   bitboard_t bb_desti, bb_checker, bb_inter, bb_target, bb_piece;
10   unsigned int hand, ubb_target0a, ubb_target0b, ubb_pawn_cmp, utemp;
11   unsigned ais_pawn[nfile];
12   int nchecker, sq_bk, to, sq_check, idirec;
13   int nhand, i, nolance, noknight, from;
14   int ahand[6];
15   
16   /* move the king */
17   sq_bk = SQ_BKING;
18   
19   Xor( sq_bk, BB_BOCCUPY );
20   XorFile( sq_bk, OCCUPIED_FILE );
21   XorDiag2( sq_bk, OCCUPIED_DIAG2 );
22   XorDiag1( sq_bk, OCCUPIED_DIAG1 );
23
24   BBNot( bb_desti, BB_BOCCUPY );
25   BBAnd( bb_desti, bb_desti, abb_king_attacks[sq_bk] );
26   utemp = From2Move(sq_bk) | Piece2Move(king);
27   while ( BBToU( bb_desti ) )
28     {
29       to = LastOne( bb_desti );
30       if ( ! is_black_attacked( ptree, to ) )
31         {
32           *pmove++ = To2Move(to) | Cap2Move(-BOARD[to]) | utemp;
33         }
34       Xor( to, bb_desti );
35     }
36   
37   Xor( sq_bk, BB_BOCCUPY );
38   XorFile( sq_bk, OCCUPIED_FILE );
39   XorDiag2( sq_bk, OCCUPIED_DIAG2 );
40   XorDiag1( sq_bk, OCCUPIED_DIAG1 );
41   
42   bb_checker = attacks_to_piece( ptree, sq_bk );
43   BBAnd( bb_checker, bb_checker, BB_WOCCUPY );
44   nchecker = PopuCount( bb_checker );
45   if ( nchecker == 2 ) { return pmove; }
46   
47   sq_check = LastOne( bb_checker );
48   bb_inter = abb_obstacle[sq_bk][sq_check];
49
50   /* move other pieces */
51   BBOr( bb_target, bb_inter, bb_checker );
52   
53   BBAnd( bb_desti, bb_target, BB_BPAWN_ATK );
54   while ( BBToU( bb_desti ) )
55     {
56       to = LastOne( bb_desti );
57       Xor( to, bb_desti );
58
59       from = to + 9;
60       idirec = (int)adirec[sq_bk][from];
61       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
62         {
63           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(pawn)
64                     | Cap2Move(-BOARD[to]) );
65           if ( to < A6 ) { utemp |= FLAG_PROMO; }
66           *pmove++ = utemp;
67         }
68     }
69
70   bb_piece = BB_BLANCE;
71   while ( BBToU( bb_piece ) )
72     {
73       from = LastOne( bb_piece );
74       Xor( from, bb_piece );
75
76       bb_desti = AttackFile( from );
77       BBAnd( bb_desti, bb_desti, abb_minus_rays[from] );
78       BBAnd( bb_desti, bb_desti, bb_target );
79       if ( ! BBToU( bb_desti ) ) { continue; }
80
81       idirec = (int)adirec[sq_bk][from];
82       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
83         {
84           to = LastOne( bb_desti );
85
86           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(lance)
87                     | Cap2Move(-BOARD[to]) );
88           if ( to <  A6 ) { *pmove++ = utemp | FLAG_PROMO; }
89           if ( to >= A7 ) { *pmove++ = utemp; }
90         }
91     }
92
93   bb_piece = BB_BKNIGHT;
94   while ( BBToU( bb_piece ) )
95     {
96       from = LastOne( bb_piece );
97       Xor( from, bb_piece );
98
99       BBAnd( bb_desti, bb_target, abb_b_knight_attacks[from] );
100       if ( ! BBToU( bb_desti ) ) { continue; }
101
102       idirec = (int)adirec[sq_bk][from];
103       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
104         do {
105           to = LastOne( bb_desti );
106           Xor( to, bb_desti );
107
108           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(knight)
109                     | Cap2Move(-BOARD[to]) );
110           if ( to <  A6 ) { *pmove++ = utemp | FLAG_PROMO; }
111           if ( to >= A7 ) { *pmove++ = utemp; }
112           
113         } while ( BBToU( bb_desti ) );
114     }
115
116   bb_piece = BB_BSILVER;
117   while ( BBToU( bb_piece ) )
118     {
119       from = LastOne( bb_piece );
120       Xor( from, bb_piece );
121       
122       BBAnd( bb_desti, bb_target, abb_b_silver_attacks[from] );
123       if ( ! BBToU( bb_desti ) ) { continue; }
124
125       idirec = (int)adirec[sq_bk][from];
126       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
127         do {
128           to = LastOne( bb_desti );
129           Xor( to, bb_desti );
130           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(silver)
131                     | Cap2Move(-BOARD[to]) );
132           if ( from < A6 || to < A6 ) { *pmove++ = utemp | FLAG_PROMO; }
133           *pmove++ = utemp;
134         } while ( BBToU( bb_desti ) );
135     }
136
137   bb_piece = BB_BTGOLD;
138   while( BBToU( bb_piece ) )
139     {
140       from  = LastOne( bb_piece );
141       Xor( from, bb_piece );
142
143       BBAnd( bb_desti, bb_target, abb_b_gold_attacks[from] );
144       if ( ! BBToU(bb_desti) ) { continue; }
145
146       idirec = (int)adirec[sq_bk][from];
147       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
148         do {
149           to = LastOne( bb_desti );
150           Xor( to, bb_desti );
151           *pmove++ = ( To2Move(to) | From2Move(from)
152                        | Piece2Move(BOARD[from])
153                        | Cap2Move(-BOARD[to]) );
154         } while( BBToU( bb_desti ) );
155     }
156
157   bb_piece = BB_BBISHOP;
158   while ( BBToU( bb_piece ) )
159     {
160       from = LastOne( bb_piece );
161       Xor( from, bb_piece );
162
163       AttackBishop( bb_desti, from );
164       BBAnd( bb_desti, bb_desti, bb_target );
165       if ( ! BBToU( bb_desti ) ) { continue; }
166       idirec = (int)adirec[sq_bk][from];
167       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
168         do {
169           to = LastOne( bb_desti );
170           Xor( to, bb_desti );
171
172           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(bishop)
173                     | Cap2Move(-BOARD[to]) );
174           if ( from < A6 || to < A6 ) { utemp |= FLAG_PROMO; }
175           *pmove++ = utemp;
176         } while ( BBToU( bb_desti ) );
177     }
178
179   bb_piece = BB_BROOK;
180   while ( BBToU( bb_piece ) )
181     {
182       from = LastOne( bb_piece );
183       Xor( from, bb_piece );
184
185       AttackRook( bb_desti, from );
186       BBAnd( bb_desti, bb_desti, bb_target );
187       if ( ! BBToU( bb_desti ) ) { continue; }
188       idirec = (int)adirec[sq_bk][from];
189       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
190         do {
191           to = LastOne( bb_desti );
192           Xor( to, bb_desti );
193
194           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(rook)
195                     | Cap2Move(-BOARD[to]) );
196           if ( from < A6 || to < A6 ) { utemp |= FLAG_PROMO; }
197           *pmove++ = utemp;
198         } while ( BBToU( bb_desti ) );
199     }
200
201   bb_piece = BB_BHORSE;
202   while( BBToU( bb_piece ) )
203     {
204       from = LastOne( bb_piece );
205       Xor( from, bb_piece );
206
207       AttackHorse( bb_desti, from );
208       BBAnd( bb_desti, bb_desti, bb_target );
209       if ( ! BBToU(bb_desti) ) { continue; }
210
211       idirec = (int)adirec[sq_bk][from];
212       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
213         do {
214           to = LastOne( bb_desti );
215           Xor( to, bb_desti);
216           *pmove++ = ( To2Move(to) | From2Move(from) | Piece2Move(horse)
217                        | Cap2Move(-BOARD[to]) );
218         } while ( BBToU( bb_desti ) );
219     }
220   
221   bb_piece = BB_BDRAGON;
222   while( BBToU( bb_piece ) )
223     {
224       from = LastOne( bb_piece );
225       Xor( from, bb_piece );
226
227       AttackDragon( bb_desti, from );
228       BBAnd( bb_desti, bb_desti, bb_target );
229       if ( ! BBToU(bb_desti) ) { continue; }
230
231       idirec = (int)adirec[sq_bk][from];
232       if ( ! idirec || ! is_pinned_on_black_king( ptree, from, idirec ) )
233         do {
234           to = LastOne( bb_desti );
235           Xor( to, bb_desti );
236           *pmove++ = ( To2Move(to) | From2Move(from) | Piece2Move(dragon)
237                        | Cap2Move(-BOARD[to]) );
238         } while ( BBToU( bb_desti ) );
239     }
240
241   if ( ! HAND_B )          { return pmove; }
242   if ( ! BBToU(bb_inter) ) { return pmove; }
243
244   /* drops */
245   bb_target = bb_inter;
246   ubb_target0a = bb_target.p[0] & 0x7fc0000U;
247   ubb_target0b = bb_target.p[0] & 0x003fe00U;
248   bb_target.p[0] &= 0x00001ffU;
249   bb_target.p[1] &= 0x7ffffffU;
250   bb_target.p[2] &= 0x7ffffffU;
251
252   hand = HAND_B;
253   nhand = 0;
254   if ( IsHandKnight( hand ) ) { ahand[ nhand++ ] = Drop2Move(knight); }
255   noknight = nhand;
256   if ( IsHandLance( hand ) )  { ahand[ nhand++ ] = Drop2Move(lance); }
257   nolance  = nhand;
258   if ( IsHandSilver( hand ) ) { ahand[ nhand++ ] = Drop2Move(silver); }
259   if ( IsHandGold( hand ) )   { ahand[ nhand++ ] = Drop2Move(gold); }
260   if ( IsHandBishop( hand ) ) { ahand[ nhand++ ] = Drop2Move(bishop); }
261   if ( IsHandRook( hand ) )   { ahand[ nhand++ ] = Drop2Move(rook); }
262
263   if ( IsHandPawn( hand ) )
264     {
265       ubb_pawn_cmp= BBToU( BB_BPAWN_ATK );
266       ais_pawn[0] = ubb_pawn_cmp & ( mask_file1 >> 0 );
267       ais_pawn[1] = ubb_pawn_cmp & ( mask_file1 >> 1 );
268       ais_pawn[2] = ubb_pawn_cmp & ( mask_file1 >> 2 );
269       ais_pawn[3] = ubb_pawn_cmp & ( mask_file1 >> 3 );
270       ais_pawn[4] = ubb_pawn_cmp & ( mask_file1 >> 4 );
271       ais_pawn[5] = ubb_pawn_cmp & ( mask_file1 >> 5 );
272       ais_pawn[6] = ubb_pawn_cmp & ( mask_file1 >> 6 );
273       ais_pawn[7] = ubb_pawn_cmp & ( mask_file1 >> 7 );
274       ais_pawn[8] = ubb_pawn_cmp & ( mask_file1 >> 8 );
275  
276       while ( BBToU( bb_target ) )
277         {
278           to = LastOne( bb_target );
279           utemp = To2Move(to);
280           if ( ! ais_pawn[aifile[to]] && ! IsMateBPawnDrop( ptree, to ) )
281             {
282               *pmove++ = utemp | Drop2Move(pawn);
283             }
284           for ( i = 0; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
285           Xor( to, bb_target );
286         }
287
288       while ( ubb_target0b )
289         {
290           to = last_one0( ubb_target0b );
291           utemp = To2Move(to);
292           if ( ! ais_pawn[aifile[to]] && ! IsMateBPawnDrop( ptree, to ) )
293             {
294               *pmove++ = utemp | Drop2Move(pawn);
295             }
296           for ( i = noknight; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
297           ubb_target0b ^= abb_mask[ to ].p[0];
298         }
299     }
300   else {
301     while ( BBToU( bb_target ) )
302       {
303         to = LastOne( bb_target );
304         utemp = To2Move(to);
305         for ( i = 0; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
306         Xor( to, bb_target );
307       }
308
309     while ( ubb_target0b )
310       {
311         to = last_one0( ubb_target0b );
312         utemp = To2Move(to);
313         for ( i = noknight; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
314         ubb_target0b ^= abb_mask[ to ].p[0];
315       }
316   }
317
318   while ( ubb_target0a )
319     {
320       to = last_one0( ubb_target0a );
321       utemp = To2Move(to);
322       for ( i = nolance; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
323       ubb_target0a ^= abb_mask[ to ].p[0];
324     }
325
326   return pmove;
327 }
328
329
330 unsigned int *
331 w_gen_evasion( tree_t * restrict ptree, unsigned int * restrict pmove )
332 {
333   bitboard_t bb_desti, bb_checker, bb_inter, bb_target, bb_piece;
334   unsigned int hand, ubb_target2a, ubb_target2b, ubb_pawn_cmp, utemp;
335   unsigned int ais_pawn[nfile];
336   int nchecker, sq_wk, to, sq_check, idirec;
337   int nhand, i, nolance, noknight, from;
338   int ahand[6];
339
340   /* move the king */
341   sq_wk = SQ_WKING;
342
343   Xor( sq_wk, BB_WOCCUPY );
344   XorFile( sq_wk, OCCUPIED_FILE );
345   XorDiag2( sq_wk, OCCUPIED_DIAG2 );
346   XorDiag1( sq_wk, OCCUPIED_DIAG1 );
347
348   BBNot( bb_desti, BB_WOCCUPY );
349   BBAnd( bb_desti, bb_desti, abb_king_attacks[sq_wk] );
350   utemp = From2Move(sq_wk) | Piece2Move(king);
351   while ( BBToU( bb_desti ) )
352     {
353       to = FirstOne( bb_desti );
354       if ( ! is_white_attacked( ptree, to ) )
355         {
356           *pmove++ = To2Move(to) | Cap2Move(BOARD[to]) | utemp;
357         }
358       Xor( to, bb_desti );
359     }
360
361   Xor( sq_wk, BB_WOCCUPY );
362   XorFile( sq_wk, OCCUPIED_FILE );
363   XorDiag2( sq_wk, OCCUPIED_DIAG2 );
364   XorDiag1( sq_wk, OCCUPIED_DIAG1 );
365
366   bb_checker = attacks_to_piece( ptree, sq_wk );
367   BBAnd( bb_checker, bb_checker, BB_BOCCUPY );
368   nchecker = PopuCount( bb_checker );
369   if ( nchecker == 2 ) { return pmove; }
370
371   sq_check = FirstOne( bb_checker );
372   bb_inter = abb_obstacle[sq_wk][sq_check];
373
374   /* move other pieces */
375   BBOr( bb_target, bb_inter, bb_checker );
376
377   BBAnd( bb_desti, bb_target, BB_WPAWN_ATK );
378   while ( BBToU( bb_desti ) )
379     {
380       to = FirstOne( bb_desti );
381       Xor( to, bb_desti );
382
383       from = to - 9;
384       idirec = (int)adirec[sq_wk][from];
385       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
386         {
387           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(pawn)
388                     | Cap2Move(BOARD[to]) );
389           if ( to > I4 ) { utemp |= FLAG_PROMO; }
390           *pmove++ = utemp;
391         }
392     }
393
394   bb_piece = BB_WLANCE;
395   while ( BBToU( bb_piece ) )
396     {
397       from = FirstOne( bb_piece );
398       Xor( from, bb_piece );
399
400       bb_desti = AttackFile( from );
401       BBAnd( bb_desti, bb_desti, abb_plus_rays[from] );
402       BBAnd( bb_desti, bb_desti, bb_target );
403       if ( ! BBToU( bb_desti ) ) { continue; }
404
405       idirec = (int)adirec[sq_wk][from];
406       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
407         {
408           to = FirstOne( bb_desti );
409
410           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(lance)
411                     | Cap2Move(BOARD[to]) );
412           if ( to >  I4 ) { *pmove++ = utemp | FLAG_PROMO; }
413           if ( to <= I3 ) { *pmove++ = utemp; }
414         }
415     }
416
417   bb_piece = BB_WKNIGHT;
418   while ( BBToU( bb_piece ) )
419     {
420       from = FirstOne( bb_piece );
421       Xor( from, bb_piece );
422
423       BBAnd( bb_desti, bb_target, abb_w_knight_attacks[from] );
424       if ( ! BBToU( bb_desti ) ) { continue; }
425
426       idirec = (int)adirec[sq_wk][from];
427       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
428         do {
429           to = FirstOne( bb_desti );
430           Xor( to, bb_desti );
431
432           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(knight)
433                     | Cap2Move(BOARD[to]) );
434           if ( to >  I4 ) { *pmove++ = utemp | FLAG_PROMO; }
435           if ( to <= I3 ) { *pmove++ = utemp; }
436         } while ( BBToU( bb_desti ) );
437     }
438
439   bb_piece = BB_WSILVER;
440   while ( BBToU( bb_piece ) )
441     {
442       from = FirstOne( bb_piece );
443       Xor( from, bb_piece );
444       
445       BBAnd( bb_desti, bb_target, abb_w_silver_attacks[from] );
446       if ( ! BBToU( bb_desti ) ) { continue; }
447
448       idirec = (int)adirec[sq_wk][from];
449       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
450         do {
451           to = FirstOne( bb_desti );
452           Xor( to, bb_desti );
453           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(silver)
454                     | Cap2Move(BOARD[to]) );
455           if ( from > I4 || to > I4 ) { *pmove++ = utemp | FLAG_PROMO; }
456           *pmove++ = utemp;
457         } while ( BBToU( bb_desti ) );
458     }
459
460   bb_piece = BB_WTGOLD;
461   while( BBToU( bb_piece ) )
462     {
463       from  = FirstOne( bb_piece );
464       Xor( from, bb_piece );
465
466       BBAnd( bb_desti, bb_target, abb_w_gold_attacks[from] );
467       if ( ! BBToU(bb_desti) ) { continue; }
468
469       idirec = (int)adirec[sq_wk][from];
470       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
471         do {
472           to = FirstOne( bb_desti );
473           Xor( to, bb_desti );
474           *pmove++ = ( To2Move(to) | From2Move(from)
475                        | Piece2Move(-BOARD[from])
476                        | Cap2Move(BOARD[to]) );
477         } while( BBToU( bb_desti ) );
478     }
479
480   bb_piece = BB_WBISHOP;
481   while ( BBToU( bb_piece ) )
482     {
483       from = FirstOne( bb_piece );
484       Xor( from, bb_piece );
485
486       AttackBishop( bb_desti, from );
487       BBAnd( bb_desti, bb_desti, bb_target );
488       if ( ! BBToU( bb_desti ) ) { continue; }
489
490       idirec = (int)adirec[sq_wk][from];
491       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
492         do {
493           to = FirstOne( bb_desti );
494           Xor( to, bb_desti );
495
496           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(bishop)
497                     | Cap2Move(BOARD[to]) );
498           if ( from > I4 || to > I4 ) { utemp |= FLAG_PROMO; }
499           *pmove++ = utemp;
500         } while ( BBToU( bb_desti ) );
501     }
502
503   bb_piece = BB_WROOK;
504   while ( BBToU( bb_piece ) )
505     {
506       from = FirstOne( bb_piece );
507       Xor( from, bb_piece );
508
509       AttackRook( bb_desti, from );
510       BBAnd( bb_desti, bb_desti, bb_target );
511       if ( ! BBToU( bb_desti ) ) { continue; }
512       idirec = (int)adirec[sq_wk][from];
513       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
514         do {
515           to = FirstOne( bb_desti );
516           Xor( to, bb_desti );
517
518           utemp = ( To2Move(to) | From2Move(from) | Piece2Move(rook)
519                     | Cap2Move(BOARD[to]) );
520           if ( from > I4 || to > I4 ) { utemp |= FLAG_PROMO; }
521           *pmove++ = utemp;
522         } while ( BBToU( bb_desti ) );
523     }
524
525   bb_piece = BB_WHORSE;
526   while( BBToU( bb_piece ) )
527     {
528       from = FirstOne( bb_piece );
529       Xor( from, bb_piece );
530
531       AttackHorse( bb_desti, from );
532       BBAnd( bb_desti, bb_desti, bb_target );
533       if ( ! BBToU(bb_desti) ) { continue; }
534
535       idirec = (int)adirec[sq_wk][from];
536       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
537         do {
538           to = FirstOne( bb_desti );
539           Xor( to, bb_desti);
540           *pmove++ = ( To2Move(to) | From2Move(from) | Piece2Move(horse)
541                        | Cap2Move(BOARD[to]) );
542         } while ( BBToU( bb_desti ) );
543     }
544   
545   bb_piece = BB_WDRAGON;
546   while( BBToU( bb_piece ) )
547     {
548       from = FirstOne( bb_piece );
549       Xor( from, bb_piece );
550
551       AttackDragon( bb_desti, from );
552       BBAnd( bb_desti, bb_desti, bb_target );
553       if ( ! BBToU(bb_desti) ) { continue; }
554
555       idirec = (int)adirec[sq_wk][from];
556       if ( ! idirec || ! is_pinned_on_white_king( ptree, from, idirec ) )
557         do {
558           to = FirstOne( bb_desti );
559           Xor( to, bb_desti );
560           *pmove++ = ( To2Move(to) | From2Move(from) | Piece2Move(dragon)
561                        | Cap2Move(BOARD[to]) );
562         } while ( BBToU( bb_desti ) );
563     }
564
565   if ( ! HAND_W )          { return pmove; }
566   if ( ! BBToU(bb_inter) ) { return pmove; }
567
568   /* drop */
569   bb_target = bb_inter;
570   ubb_target2a = bb_target.p[2] & 0x00001ffU;
571   ubb_target2b = bb_target.p[2] & 0x003fe00U;
572   bb_target.p[0] &= 0x7ffffffU;
573   bb_target.p[1] &= 0x7ffffffU;
574   bb_target.p[2] &= 0x7fc0000U;
575
576   hand = HAND_W;
577   nhand = 0;
578   if ( IsHandKnight( hand ) ) { ahand[ nhand++ ] = Drop2Move(knight); }
579   noknight = nhand;
580   if ( IsHandLance( hand ) )  { ahand[ nhand++ ] = Drop2Move(lance); }
581   nolance  = nhand;
582   if ( IsHandSilver( hand ) ) { ahand[ nhand++ ] = Drop2Move(silver); }
583   if ( IsHandGold( hand ) )   { ahand[ nhand++ ] = Drop2Move(gold); }
584   if ( IsHandBishop( hand ) ) { ahand[ nhand++ ] = Drop2Move(bishop); }
585   if ( IsHandRook( hand ) )   { ahand[ nhand++ ] = Drop2Move(rook); }
586
587   if ( IsHandPawn( hand ) )
588     {
589       ubb_pawn_cmp= BBToU( BB_WPAWN_ATK );
590       ais_pawn[0] = ubb_pawn_cmp & ( mask_file1 >> 0 );
591       ais_pawn[1] = ubb_pawn_cmp & ( mask_file1 >> 1 );
592       ais_pawn[2] = ubb_pawn_cmp & ( mask_file1 >> 2 );
593       ais_pawn[3] = ubb_pawn_cmp & ( mask_file1 >> 3 );
594       ais_pawn[4] = ubb_pawn_cmp & ( mask_file1 >> 4 );
595       ais_pawn[5] = ubb_pawn_cmp & ( mask_file1 >> 5 );
596       ais_pawn[6] = ubb_pawn_cmp & ( mask_file1 >> 6 );
597       ais_pawn[7] = ubb_pawn_cmp & ( mask_file1 >> 7 );
598       ais_pawn[8] = ubb_pawn_cmp & ( mask_file1 >> 8 );
599  
600       while ( BBToU( bb_target ) )
601         {
602           to = FirstOne( bb_target );
603           utemp = To2Move(to);
604           if ( ! ais_pawn[aifile[to]] && ! IsMateWPawnDrop( ptree, to ) )
605             {
606               *pmove++ = utemp | Drop2Move(pawn);
607             }
608           for ( i = 0; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
609           Xor( to, bb_target );
610         }
611
612       while ( ubb_target2b )
613         {
614           to = first_one2( ubb_target2b );
615           utemp = To2Move(to);
616           if ( ! ais_pawn[aifile[to]] && ! IsMateWPawnDrop( ptree, to ) )
617             {
618               *pmove++ = utemp | Drop2Move(pawn);
619             }
620           for ( i = noknight; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
621           ubb_target2b ^= abb_mask[ to ].p[2];
622         }
623     }
624   else {
625     while ( BBToU( bb_target ) )
626       {
627         to = FirstOne( bb_target );
628         utemp = To2Move(to);
629         for ( i = 0; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
630         Xor( to, bb_target );
631       }
632
633     while ( ubb_target2b )
634       {
635         to = first_one2( ubb_target2b );
636         utemp = To2Move(to);
637         for ( i = noknight; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
638         ubb_target2b ^= abb_mask[ to ].p[2];
639       }
640   }
641
642   while ( ubb_target2a )
643     {
644       to = first_one2( ubb_target2a );
645       utemp = To2Move(to);
646       for ( i = nolance; i < nhand; i++ ) { *pmove++ = utemp|ahand[i]; }
647       ubb_target2a ^= abb_mask[ to ].p[2];
648     }
649
650   return pmove;
651 }