Fix force mode after setboard
[bonanza.git] / evaluate.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <limits.h>
5 #include "shogi.h"
6
7 #define PcPcOnSqAny(k,i,j) ( i >= j ? PcPcOnSq(k,i,j) : PcPcOnSq(k,j,i) )
8
9 static int CONV doacapt( const tree_t * restrict ptree, int pc, int turn,
10                          int hand_index, const int list0[52],
11                          const int list1[52], int nlist );
12 static int CONV doapc( const tree_t * restrict ptree, int pc, int sq,
13                        const int list0[52], const int list1[52], int nlist );
14 static int CONV ehash_probe( uint64_t current_key, unsigned int hand_b,
15                              int * restrict pscore );
16 static void CONV ehash_store( uint64_t key, unsigned int hand_b, int score );
17 static int CONV calc_difference( const tree_t * restrict ptree, int ply,
18                                  int turn, int list0[52], int list1[52],
19                                  int * restrict pscore );
20 static int CONV make_list( const tree_t * restrict ptree,
21                            int * restrict pscore,
22                            int list0[52], int list1[52] );
23
24 #if defined(INANIWA_SHIFT)
25 static int inaniwa_score( const tree_t * restrict ptree );
26 #endif
27
28 int CONV
29 eval_material( const tree_t * restrict ptree )
30 {
31   int material, itemp;
32
33   itemp     = PopuCount( BB_BPAWN )   + (int)I2HandPawn( HAND_B );
34   itemp    -= PopuCount( BB_WPAWN )   + (int)I2HandPawn( HAND_W );
35   material  = itemp * p_value[15+pawn];
36
37   itemp     = PopuCount( BB_BLANCE )  + (int)I2HandLance( HAND_B );
38   itemp    -= PopuCount( BB_WLANCE )  + (int)I2HandLance( HAND_W );
39   material += itemp * p_value[15+lance];
40
41   itemp     = PopuCount( BB_BKNIGHT ) + (int)I2HandKnight( HAND_B );
42   itemp    -= PopuCount( BB_WKNIGHT ) + (int)I2HandKnight( HAND_W );
43   material += itemp * p_value[15+knight];
44
45   itemp     = PopuCount( BB_BSILVER ) + (int)I2HandSilver( HAND_B );
46   itemp    -= PopuCount( BB_WSILVER ) + (int)I2HandSilver( HAND_W );
47   material += itemp * p_value[15+silver];
48
49   itemp     = PopuCount( BB_BGOLD )   + (int)I2HandGold( HAND_B );
50   itemp    -= PopuCount( BB_WGOLD )   + (int)I2HandGold( HAND_W );
51   material += itemp * p_value[15+gold];
52
53   itemp     = PopuCount( BB_BBISHOP ) + (int)I2HandBishop( HAND_B );
54   itemp    -= PopuCount( BB_WBISHOP ) + (int)I2HandBishop( HAND_W );
55   material += itemp * p_value[15+bishop];
56
57   itemp     = PopuCount( BB_BROOK )   + (int)I2HandRook( HAND_B );
58   itemp    -= PopuCount( BB_WROOK )   + (int)I2HandRook( HAND_W );
59   material += itemp * p_value[15+rook];
60
61   itemp     = PopuCount( BB_BPRO_PAWN );
62   itemp    -= PopuCount( BB_WPRO_PAWN );
63   material += itemp * p_value[15+pro_pawn];
64
65   itemp     = PopuCount( BB_BPRO_LANCE );
66   itemp    -= PopuCount( BB_WPRO_LANCE );
67   material += itemp * p_value[15+pro_lance];
68
69   itemp     = PopuCount( BB_BPRO_KNIGHT );
70   itemp    -= PopuCount( BB_WPRO_KNIGHT );
71   material += itemp * p_value[15+pro_knight];
72
73   itemp     = PopuCount( BB_BPRO_SILVER );
74   itemp    -= PopuCount( BB_WPRO_SILVER );
75   material += itemp * p_value[15+pro_silver];
76
77   itemp     = PopuCount( BB_BHORSE );
78   itemp    -= PopuCount( BB_WHORSE );
79   material += itemp * p_value[15+horse];
80
81   itemp     = PopuCount( BB_BDRAGON );
82   itemp    -= PopuCount( BB_WDRAGON );
83   material += itemp * p_value[15+dragon];
84
85   return material;
86 }
87
88
89 int CONV
90 evaluate( tree_t * restrict ptree, int ply, int turn )
91 {
92   int list0[52], list1[52];
93   int nlist, score, sq_bk, sq_wk, k0, k1, l0, l1, i, j, sum;
94
95   assert( 0 < ply );
96   ptree->neval_called++;
97
98   if ( ptree->save_eval[ply] != INT_MAX )
99     {
100       return (int)ptree->save_eval[ply] / FV_SCALE;
101     }
102
103   if ( ehash_probe( HASH_KEY, HAND_B, &score ) )
104     {
105       score                 = turn ? -score : score;
106       ptree->save_eval[ply] = score;
107
108       return score / FV_SCALE;
109     }
110
111   list0[ 0] = f_hand_pawn   + I2HandPawn(HAND_B);
112   list0[ 1] = e_hand_pawn   + I2HandPawn(HAND_W);
113   list0[ 2] = f_hand_lance  + I2HandLance(HAND_B);
114   list0[ 3] = e_hand_lance  + I2HandLance(HAND_W);
115   list0[ 4] = f_hand_knight + I2HandKnight(HAND_B);
116   list0[ 5] = e_hand_knight + I2HandKnight(HAND_W);
117   list0[ 6] = f_hand_silver + I2HandSilver(HAND_B);
118   list0[ 7] = e_hand_silver + I2HandSilver(HAND_W);
119   list0[ 8] = f_hand_gold   + I2HandGold(HAND_B);
120   list0[ 9] = e_hand_gold   + I2HandGold(HAND_W);
121   list0[10] = f_hand_bishop + I2HandBishop(HAND_B);
122   list0[11] = e_hand_bishop + I2HandBishop(HAND_W);
123   list0[12] = f_hand_rook   + I2HandRook(HAND_B);
124   list0[13] = e_hand_rook   + I2HandRook(HAND_W);
125
126   list1[ 0] = f_hand_pawn   + I2HandPawn(HAND_W);
127   list1[ 1] = e_hand_pawn   + I2HandPawn(HAND_B);
128   list1[ 2] = f_hand_lance  + I2HandLance(HAND_W);
129   list1[ 3] = e_hand_lance  + I2HandLance(HAND_B);
130   list1[ 4] = f_hand_knight + I2HandKnight(HAND_W);
131   list1[ 5] = e_hand_knight + I2HandKnight(HAND_B);
132   list1[ 6] = f_hand_silver + I2HandSilver(HAND_W);
133   list1[ 7] = e_hand_silver + I2HandSilver(HAND_B);
134   list1[ 8] = f_hand_gold   + I2HandGold(HAND_W);
135   list1[ 9] = e_hand_gold   + I2HandGold(HAND_B);
136   list1[10] = f_hand_bishop + I2HandBishop(HAND_W);
137   list1[11] = e_hand_bishop + I2HandBishop(HAND_B);
138   list1[12] = f_hand_rook   + I2HandRook(HAND_W);
139   list1[13] = e_hand_rook   + I2HandRook(HAND_B);
140
141   if ( calc_difference( ptree, ply, turn, list0, list1, &score ) )
142     {
143       ehash_store( HASH_KEY, HAND_B, score );
144       score                 = turn ? -score : score;
145       ptree->save_eval[ply] = score;
146
147       return score / FV_SCALE;
148     }
149
150   nlist = make_list( ptree, &score, list0, list1 );
151   sq_bk = SQ_BKING;
152   sq_wk = Inv( SQ_WKING );
153
154   sum = 0;
155   for ( i = 0; i < nlist; i++ )
156     {
157       k0 = list0[i];
158       k1 = list1[i];
159       for ( j = 0; j <= i; j++ )
160         {
161           l0 = list0[j];
162           l1 = list1[j];
163           assert( k0 >= l0 && k1 >= l1 );
164           sum += PcPcOnSq( sq_bk, k0, l0 );
165           sum -= PcPcOnSq( sq_wk, k1, l1 );
166         }
167     }
168   
169   score += sum;
170   score += MATERIAL * FV_SCALE;
171 #if defined(INANIWA_SHIFT)
172   score += inaniwa_score( ptree );
173 #endif
174
175   ehash_store( HASH_KEY, HAND_B, score );
176
177   score = turn ? -score : score;
178
179   ptree->save_eval[ply] = score;
180
181   score /= FV_SCALE;
182
183 #if ! defined(MINIMUM)
184   if ( abs(score) > score_max_eval )
185     {
186       out_warning( "A score at evaluate() is out of bounce." );
187     }
188 #endif
189
190   return score;
191
192 }
193
194
195 void CONV ehash_clear( void ) { memset( ehash_tbl, 0, sizeof(ehash_tbl) ); }
196
197
198 static int CONV ehash_probe( uint64_t current_key, unsigned int hand_b,
199                              int * restrict pscore )
200 {
201   uint64_t hash_word, hash_key;
202
203   hash_word = ehash_tbl[ (unsigned int)current_key & EHASH_MASK ];
204
205 #if ! defined(__x86_64__)
206   hash_word ^= hash_word << 32;
207 #endif
208
209   current_key ^= (uint64_t)hand_b << 21;
210   current_key &= ~(uint64_t)0x1fffffU;
211
212   hash_key  = hash_word;
213   hash_key &= ~(uint64_t)0x1fffffU;
214
215   if ( hash_key != current_key ) { return 0; }
216
217   *pscore = (int)( (unsigned int)hash_word & 0x1fffffU ) - 0x100000;
218
219   return 1;
220 }
221
222
223 static void CONV ehash_store( uint64_t key, unsigned int hand_b, int score )
224 {
225   uint64_t hash_word;
226
227   hash_word  = key;
228   hash_word ^= (uint64_t)hand_b << 21;
229   hash_word &= ~(uint64_t)0x1fffffU;
230   hash_word |= (uint64_t)( score + 0x100000 );
231
232 #if ! defined(__x86_64__)
233   hash_word ^= hash_word << 32;
234 #endif
235
236   ehash_tbl[ (unsigned int)key & EHASH_MASK ] = hash_word;
237 }
238
239
240 static int CONV
241 calc_difference( const tree_t * restrict ptree, int ply, int turn,
242                  int list0[52], int list1[52], int * restrict pscore )
243 {
244   bitboard_t bb;
245   int nlist, diff, from, to, sq, pc;
246
247 #if defined(INANIWA_SHIFT)
248   if ( inaniwa_flag ) { return 0; }
249 #endif
250
251   if ( ptree->save_eval[ply-1] == INT_MAX ) { return 0; }
252   if ( I2PieceMove(MOVE_LAST)  == king )    { return 0; }
253
254   assert( MOVE_LAST != MOVE_PASS );
255
256   nlist = 14;
257   diff  = 0;
258   from  = I2From(MOVE_LAST);
259   to    = I2To(MOVE_LAST);
260
261   BBOr( bb, BB_BOCCUPY, BB_WOCCUPY );
262   Xor( SQ_BKING, bb );
263   Xor( SQ_WKING, bb );
264   Xor( to,       bb );
265     
266   while ( BBTest(bb) )
267     {
268       sq = FirstOne(bb);
269       Xor( sq, bb );
270       
271       pc = BOARD[sq];
272       list0[nlist  ] = aikpp[15+pc] + sq;
273       list1[nlist++] = aikpp[15-pc] + Inv(sq);
274     }
275
276   pc = BOARD[to];
277   list0[nlist  ] = aikpp[15+pc] + to;
278   list1[nlist++] = aikpp[15-pc] + Inv(to);
279
280   diff = doapc( ptree, pc, to, list0, list1, nlist );
281   nlist -= 1;
282
283   if ( from >= nsquare )
284     {
285       unsigned int hand;
286       int hand_index;
287
288       pc   = From2Drop(from);
289       hand = turn ? HAND_B : HAND_W;
290
291       switch ( pc )
292         {
293         case pawn:   hand_index = I2HandPawn(hand);   break;
294         case lance:  hand_index = I2HandLance(hand);  break;
295         case knight: hand_index = I2HandKnight(hand); break;
296         case silver: hand_index = I2HandSilver(hand); break;
297         case gold:   hand_index = I2HandGold(hand);   break;
298         case bishop: hand_index = I2HandBishop(hand); break;
299         default:     hand_index = I2HandRook(hand);   break;
300         }
301
302       diff += doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
303
304       list0[ 2*(pc-1) + 1 - turn ] += 1;
305       list1[ 2*(pc-1) + turn     ] += 1;
306       hand_index                   += 1;
307
308       diff -= doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
309     }
310   else {
311     int pc_cap = UToCap(MOVE_LAST);
312     if ( pc_cap )
313       {
314         unsigned int hand;
315         int hand_index;
316
317         pc     = pc_cap & ~promote;
318         hand   = turn ? HAND_B : HAND_W;
319         pc_cap = turn ? -pc_cap : pc_cap;
320         diff  += turn ?  p_value_ex[15+pc_cap] * FV_SCALE
321                       : -p_value_ex[15+pc_cap] * FV_SCALE;
322
323         switch ( pc )
324           {
325           case pawn:   hand_index = I2HandPawn(hand);   break;
326           case lance:  hand_index = I2HandLance(hand);  break;
327           case knight: hand_index = I2HandKnight(hand); break;
328           case silver: hand_index = I2HandSilver(hand); break;
329           case gold:   hand_index = I2HandGold(hand);   break;
330           case bishop: hand_index = I2HandBishop(hand); break;
331           default:     hand_index = I2HandRook(hand);   break;
332           }
333
334         diff += doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
335         
336         list0[ 2*(pc-1) + 1 - turn ] -= 1;
337         list1[ 2*(pc-1) + turn     ] -= 1;
338         hand_index                   -= 1;
339         
340         diff -= doacapt( ptree, pc, turn, hand_index, list0, list1, nlist );
341
342         list0[nlist  ] = aikpp[15+pc_cap] + to;
343         list1[nlist++] = aikpp[15-pc_cap] + Inv(to);
344
345         diff -= doapc( ptree, pc_cap, to, list0, list1, nlist );
346     }
347
348     pc = I2PieceMove(MOVE_LAST);
349     if ( I2IsPromote(MOVE_LAST) )
350       {
351         diff += ( turn ? p_value_pm[7+pc] : -p_value_pm[7+pc] ) * FV_SCALE;
352       }
353     
354     pc = turn ? pc : -pc;
355
356     list0[nlist  ] = aikpp[15+pc] + from;
357     list1[nlist++] = aikpp[15-pc] + Inv(from);
358
359     diff -= doapc( ptree, pc, from, list0, list1, nlist );
360   
361   }
362   
363   diff += turn ? ptree->save_eval[ply-1] : - ptree->save_eval[ply-1];
364
365   *pscore = diff;
366
367   return 1;
368 }
369
370
371 static int CONV
372 make_list( const tree_t * restrict ptree, int * restrict pscore,
373            int list0[52], int list1[52] )
374 {
375   bitboard_t bb;
376   int list2[34];
377   int nlist, sq, n2, i, score, sq_bk0, sq_wk0, sq_bk1, sq_wk1;
378
379   nlist  = 14;
380   score  = 0;
381   sq_bk0 = SQ_BKING;
382   sq_wk0 = SQ_WKING;
383   sq_bk1 = Inv(SQ_WKING);
384   sq_wk1 = Inv(SQ_BKING);
385
386   score += kkp[sq_bk0][sq_wk0][ kkp_hand_pawn   + I2HandPawn(HAND_B) ];
387   score += kkp[sq_bk0][sq_wk0][ kkp_hand_lance  + I2HandLance(HAND_B) ];
388   score += kkp[sq_bk0][sq_wk0][ kkp_hand_knight + I2HandKnight(HAND_B) ];
389   score += kkp[sq_bk0][sq_wk0][ kkp_hand_silver + I2HandSilver(HAND_B) ];
390   score += kkp[sq_bk0][sq_wk0][ kkp_hand_gold   + I2HandGold(HAND_B) ];
391   score += kkp[sq_bk0][sq_wk0][ kkp_hand_bishop + I2HandBishop(HAND_B) ];
392   score += kkp[sq_bk0][sq_wk0][ kkp_hand_rook   + I2HandRook(HAND_B) ];
393
394   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_pawn   + I2HandPawn(HAND_W) ];
395   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_lance  + I2HandLance(HAND_W) ];
396   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_knight + I2HandKnight(HAND_W) ];
397   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_silver + I2HandSilver(HAND_W) ];
398   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_gold   + I2HandGold(HAND_W) ];
399   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_bishop + I2HandBishop(HAND_W) ];
400   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_rook   + I2HandRook(HAND_W) ];
401
402   n2 = 0;
403   bb = BB_BPAWN;
404   while ( BBTest(bb) ) {
405     sq = FirstOne( bb );
406     Xor( sq, bb );
407
408     list0[nlist] = f_pawn + sq;
409     list2[n2]    = e_pawn + Inv(sq);
410     score += kkp[sq_bk0][sq_wk0][ kkp_pawn + sq ];
411     nlist += 1;
412     n2    += 1;
413   }
414
415   bb = BB_WPAWN;
416   while ( BBTest(bb) ) {
417     sq = FirstOne( bb );
418     Xor( sq, bb );
419
420     list0[nlist] = e_pawn + sq;
421     list2[n2]    = f_pawn + Inv(sq);
422     score -= kkp[sq_bk1][sq_wk1][ kkp_pawn + Inv(sq) ];
423     nlist += 1;
424     n2    += 1;
425   }
426   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
427
428   n2 = 0;
429   bb = BB_BLANCE;
430   while ( BBTest(bb) ) {
431     sq = FirstOne( bb );
432     Xor( sq, bb );
433
434     list0[nlist] = f_lance + sq;
435     list2[n2]    = e_lance + Inv(sq);
436     score += kkp[sq_bk0][sq_wk0][ kkp_lance + sq ];
437     nlist += 1;
438     n2    += 1;
439   }
440
441   bb = BB_WLANCE;
442   while ( BBTest(bb) ) {
443     sq = FirstOne( bb );
444     Xor( sq, bb );
445
446     list0[nlist] = e_lance + sq;
447     list2[n2]    = f_lance + Inv(sq);
448     score -= kkp[sq_bk1][sq_wk1][ kkp_lance + Inv(sq) ];
449     nlist += 1;
450     n2    += 1;
451   }
452   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
453
454
455   n2 = 0;
456   bb = BB_BKNIGHT;
457   while ( BBTest(bb) ) {
458     sq = FirstOne( bb );
459     Xor( sq, bb );
460
461     list0[nlist] = f_knight + sq;
462     list2[n2]    = e_knight + Inv(sq);
463     score += kkp[sq_bk0][sq_wk0][ kkp_knight + sq ];
464     nlist += 1;
465     n2    += 1;
466   }
467
468   bb = BB_WKNIGHT;
469   while ( BBTest(bb) ) {
470     sq = FirstOne( bb );
471     Xor( sq, bb );
472
473     list0[nlist] = e_knight + sq;
474     list2[n2]    = f_knight + Inv(sq);
475     score -= kkp[sq_bk1][sq_wk1][ kkp_knight + Inv(sq) ];
476     nlist += 1;
477     n2    += 1;
478   }
479   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
480
481
482   n2 = 0;
483   bb = BB_BSILVER;
484   while ( BBTest(bb) ) {
485     sq = FirstOne( bb );
486     Xor( sq, bb );
487
488     list0[nlist] = f_silver + sq;
489     list2[n2]    = e_silver + Inv(sq);
490     score += kkp[sq_bk0][sq_wk0][ kkp_silver + sq ];
491     nlist += 1;
492     n2    += 1;
493   }
494
495   bb = BB_WSILVER;
496   while ( BBTest(bb) ) {
497     sq = FirstOne( bb );
498     Xor( sq, bb );
499
500     list0[nlist] = e_silver + sq;
501     list2[n2]    = f_silver + Inv(sq);
502     score -= kkp[sq_bk1][sq_wk1][ kkp_silver + Inv(sq) ];
503     nlist += 1;
504     n2    += 1;
505   }
506   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
507
508
509   n2 = 0;
510   bb = BB_BTGOLD;
511   while ( BBTest(bb) ) {
512     sq = FirstOne( bb );
513     Xor( sq, bb );
514
515     list0[nlist] = f_gold + sq;
516     list2[n2]    = e_gold + Inv(sq);
517     score += kkp[sq_bk0][sq_wk0][ kkp_gold + sq ];
518     nlist += 1;
519     n2    += 1;
520   }
521
522   bb = BB_WTGOLD;
523   while ( BBTest(bb) ) {
524     sq = FirstOne( bb );
525     Xor( sq, bb );
526
527     list0[nlist] = e_gold + sq;
528     list2[n2]    = f_gold + Inv(sq);
529     score -= kkp[sq_bk1][sq_wk1][ kkp_gold + Inv(sq) ];
530     nlist += 1;
531     n2    += 1;
532   }
533   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
534
535
536   n2 = 0;
537   bb = BB_BBISHOP;
538   while ( BBTest(bb) ) {
539     sq = FirstOne( bb );
540     Xor( sq, bb );
541
542     list0[nlist] = f_bishop + sq;
543     list2[n2]    = e_bishop + Inv(sq);
544     score += kkp[sq_bk0][sq_wk0][ kkp_bishop + sq ];
545     nlist += 1;
546     n2    += 1;
547   }
548
549   bb = BB_WBISHOP;
550   while ( BBTest(bb) ) {
551     sq = FirstOne( bb );
552     Xor( sq, bb );
553
554     list0[nlist] = e_bishop + sq;
555     list2[n2]    = f_bishop + Inv(sq);
556     score -= kkp[sq_bk1][sq_wk1][ kkp_bishop + Inv(sq) ];
557     nlist += 1;
558     n2    += 1;
559   }
560   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
561
562
563   n2 = 0;
564   bb = BB_BHORSE;
565   while ( BBTest(bb) ) {
566     sq = FirstOne( bb );
567     Xor( sq, bb );
568
569     list0[nlist] = f_horse + sq;
570     list2[n2]    = e_horse + Inv(sq);
571     score += kkp[sq_bk0][sq_wk0][ kkp_horse + sq ];
572     nlist += 1;
573     n2    += 1;
574   }
575
576   bb = BB_WHORSE;
577   while ( BBTest(bb) ) {
578     sq = FirstOne( bb );
579     Xor( sq, bb );
580
581     list0[nlist] = e_horse + sq;
582     list2[n2]    = f_horse + Inv(sq);
583     score -= kkp[sq_bk1][sq_wk1][ kkp_horse + Inv(sq) ];
584     nlist += 1;
585     n2    += 1;
586   }
587   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
588
589
590   n2 = 0;
591   bb = BB_BROOK;
592   while ( BBTest(bb) ) {
593     sq = FirstOne( bb );
594     Xor( sq, bb );
595
596     list0[nlist] = f_rook + sq;
597     list2[n2]    = e_rook + Inv(sq);
598     score += kkp[sq_bk0][sq_wk0][ kkp_rook + sq ];
599     nlist += 1;
600     n2    += 1;
601   }
602
603   bb = BB_WROOK;
604   while ( BBTest(bb) ) {
605     sq = FirstOne( bb );
606     Xor( sq, bb );
607
608     list0[nlist] = e_rook + sq;
609     list2[n2]    = f_rook + Inv(sq);
610     score -= kkp[sq_bk1][sq_wk1][ kkp_rook + Inv(sq) ];
611     nlist += 1;
612     n2    += 1;
613   }
614   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
615
616
617   n2 = 0;
618   bb = BB_BDRAGON;
619   while ( BBTest(bb) ) {
620     sq = FirstOne( bb );
621     Xor( sq, bb );
622
623     list0[nlist] = f_dragon + sq;
624     list2[n2]    = e_dragon + Inv(sq);
625     score += kkp[sq_bk0][sq_wk0][ kkp_dragon + sq ];
626     nlist += 1;
627     n2    += 1;
628   }
629
630   bb = BB_WDRAGON;
631   while ( BBTest(bb) ) {
632     sq = FirstOne( bb );
633     Xor( sq, bb );
634
635     list0[nlist] = e_dragon + sq;
636     list2[n2]    = f_dragon + Inv(sq);
637     score -= kkp[sq_bk1][sq_wk1][ kkp_dragon + Inv(sq) ];
638     nlist += 1;
639     n2    += 1;
640   }
641   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
642
643   assert( nlist <= 52 );
644
645   *pscore = score;
646   return nlist;
647 }
648
649
650 static int CONV doapc( const tree_t * restrict ptree, int pc, int sq,
651                        const int list0[52], const int list1[52], int nlist )
652 {
653   int i, sum;
654   int index_b = aikpp[15+pc] + sq;
655   int index_w = aikpp[15-pc] + Inv(sq);
656   int sq_bk   = SQ_BKING;
657   int sq_wk   = Inv(SQ_WKING);
658   
659   sum = 0;
660   for( i = 0; i < 14; i++ )
661     {
662       sum += PcPcOnSq( sq_bk, index_b, list0[i] );
663       sum -= PcPcOnSq( sq_wk, index_w, list1[i] );
664     }
665   
666   for( i = 14; i < nlist; i++ )
667     {
668       sum += PcPcOnSqAny( sq_bk, index_b, list0[i] );
669       sum -= PcPcOnSqAny( sq_wk, index_w, list1[i] );
670     }
671   
672   if ( pc > 0 )
673     {
674       sq_bk  = SQ_BKING;
675       sq_wk  = SQ_WKING;
676       sum   += kkp[sq_bk][sq_wk][ aikkp[pc] + sq ];
677     }
678   else {
679     sq_bk  = Inv(SQ_WKING);
680     sq_wk  = Inv(SQ_BKING);
681     sum   -= kkp[sq_bk][sq_wk][ aikkp[-pc] + Inv(sq) ];
682   }
683   
684   return sum;
685 }
686
687
688 static int CONV
689 doacapt( const tree_t * restrict ptree, int pc, int turn, int hand_index,
690          const int list0[52], const int list1[52], int nlist )
691 {
692   int i, sum, sq_bk, sq_wk, index_b, index_w;
693   
694   index_b = 2*(pc-1) + 1 - turn;
695   index_w = 2*(pc-1) + turn;
696   sq_bk   = SQ_BKING;
697   sq_wk   = Inv(SQ_WKING);
698   
699   sum = 0;
700   for( i = 14; i < nlist; i++ )
701     {
702       sum += PcPcOnSq( sq_bk, list0[i], list0[index_b] );
703       sum -= PcPcOnSq( sq_wk, list1[i], list1[index_w] );
704     }
705
706   for( i = 0; i <= 2*(pc-1); i++ )
707     {
708       sum += PcPcOnSq( sq_bk, list0[index_b], list0[i] );
709       sum -= PcPcOnSq( sq_wk, list1[index_w], list1[i] );
710     }
711
712   for( i += 1; i < 14; i++ )
713     {
714       sum += PcPcOnSq( sq_bk, list0[i], list0[index_b] );
715       sum -= PcPcOnSq( sq_wk, list1[i], list1[index_w] );
716     }
717
718   if ( turn )
719     {
720       sum += PcPcOnSq( sq_bk, list0[index_w], list0[index_b] );
721       sum -= PcPcOnSq( sq_wk, list1[index_w], list1[index_w] );
722       sq_bk = SQ_BKING;
723       sq_wk = SQ_WKING;
724       sum  += kkp[sq_bk][sq_wk][ aikkp_hand[pc] + hand_index ];
725     }
726   else {
727     sum += PcPcOnSq( sq_bk, list0[index_b], list0[index_b] );
728     sum -= PcPcOnSq( sq_wk, list1[index_b], list1[index_w] );
729     sq_bk = Inv(SQ_WKING);
730     sq_wk = Inv(SQ_BKING);
731     sum  -= kkp[sq_bk][sq_wk][ aikkp_hand[pc] + hand_index ];
732   }
733   
734   return sum;
735 }
736
737
738 #if defined(INANIWA_SHIFT)
739 static int
740 inaniwa_score( const tree_t * restrict ptree )
741 {
742   int score;
743
744   if ( ! inaniwa_flag ) { return 0; }
745
746   score = 0;
747   if ( inaniwa_flag == 2 ) {
748
749     if ( BOARD[B9] == -knight ) { score += 700 * FV_SCALE; }
750     if ( BOARD[H9] == -knight ) { score += 700 * FV_SCALE; }
751     
752     if ( BOARD[A7] == -knight ) { score += 700 * FV_SCALE; }
753     if ( BOARD[C7] == -knight ) { score += 400 * FV_SCALE; }
754     if ( BOARD[G7] == -knight ) { score += 400 * FV_SCALE; }
755     if ( BOARD[I7] == -knight ) { score += 700 * FV_SCALE; }
756     
757     if ( BOARD[B5] == -knight ) { score += 700 * FV_SCALE; }
758     if ( BOARD[D5] == -knight ) { score += 100 * FV_SCALE; }
759     if ( BOARD[F5] == -knight ) { score += 100 * FV_SCALE; }
760     if ( BOARD[H5] == -knight ) { score += 700 * FV_SCALE; }
761
762     if ( BOARD[E3] ==  pawn )   { score += 200 * FV_SCALE; }
763     if ( BOARD[E4] ==  pawn )   { score += 200 * FV_SCALE; }
764     if ( BOARD[E5] ==  pawn )   { score += 200 * FV_SCALE; }
765
766   } else {
767
768     if ( BOARD[B1] ==  knight ) { score -= 700 * FV_SCALE; }
769     if ( BOARD[H1] ==  knight ) { score -= 700 * FV_SCALE; }
770     
771     if ( BOARD[A3] ==  knight ) { score -= 700 * FV_SCALE; }
772     if ( BOARD[C3] ==  knight ) { score -= 400 * FV_SCALE; }
773     if ( BOARD[G3] ==  knight ) { score -= 400 * FV_SCALE; }
774     if ( BOARD[I3] ==  knight ) { score -= 700 * FV_SCALE; }
775     
776     if ( BOARD[B5] ==  knight ) { score -= 700 * FV_SCALE; }
777     if ( BOARD[D5] ==  knight ) { score -= 100 * FV_SCALE; }
778     if ( BOARD[F5] ==  knight ) { score -= 100 * FV_SCALE; }
779     if ( BOARD[H5] ==  knight ) { score -= 700 * FV_SCALE; }
780
781     if ( BOARD[E7] == -pawn )   { score -= 200 * FV_SCALE; }
782     if ( BOARD[E6] == -pawn )   { score -= 200 * FV_SCALE; }
783     if ( BOARD[E5] == -pawn )   { score -= 200 * FV_SCALE; }
784   }
785
786   return score;
787 }
788 #endif