Force iteration to start at 1 in analyze mode
[bonanza.git] / evaluate.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <assert.h>
4 #include "shogi.h"
5
6 static int ehash_probe( uint64_t current_key, unsigned int hand_b,
7                         int *pscore );
8 static void ehash_store( uint64_t key, unsigned int hand_b, int score );
9 static int make_list( const tree_t * restrict ptree, int * restrict pscore,
10                       int list0[52], int list1[52] );
11
12 int
13 eval_material( const tree_t * restrict ptree )
14 {
15   int material, itemp;
16
17   itemp     = PopuCount( BB_BPAWN )   + (int)I2HandPawn( HAND_B );
18   itemp    -= PopuCount( BB_WPAWN )   + (int)I2HandPawn( HAND_W );
19   material  = itemp * p_value[15+pawn];
20
21   itemp     = PopuCount( BB_BLANCE )  + (int)I2HandLance( HAND_B );
22   itemp    -= PopuCount( BB_WLANCE )  + (int)I2HandLance( HAND_W );
23   material += itemp * p_value[15+lance];
24
25   itemp     = PopuCount( BB_BKNIGHT ) + (int)I2HandKnight( HAND_B );
26   itemp    -= PopuCount( BB_WKNIGHT ) + (int)I2HandKnight( HAND_W );
27   material += itemp * p_value[15+knight];
28
29   itemp     = PopuCount( BB_BSILVER ) + (int)I2HandSilver( HAND_B );
30   itemp    -= PopuCount( BB_WSILVER ) + (int)I2HandSilver( HAND_W );
31   material += itemp * p_value[15+silver];
32
33   itemp     = PopuCount( BB_BGOLD )   + (int)I2HandGold( HAND_B );
34   itemp    -= PopuCount( BB_WGOLD )   + (int)I2HandGold( HAND_W );
35   material += itemp * p_value[15+gold];
36
37   itemp     = PopuCount( BB_BBISHOP ) + (int)I2HandBishop( HAND_B );
38   itemp    -= PopuCount( BB_WBISHOP ) + (int)I2HandBishop( HAND_W );
39   material += itemp * p_value[15+bishop];
40
41   itemp     = PopuCount( BB_BROOK )   + (int)I2HandRook( HAND_B );
42   itemp    -= PopuCount( BB_WROOK )   + (int)I2HandRook( HAND_W );
43   material += itemp * p_value[15+rook];
44
45   itemp     = PopuCount( BB_BPRO_PAWN );
46   itemp    -= PopuCount( BB_WPRO_PAWN );
47   material += itemp * p_value[15+pro_pawn];
48
49   itemp     = PopuCount( BB_BPRO_LANCE );
50   itemp    -= PopuCount( BB_WPRO_LANCE );
51   material += itemp * p_value[15+pro_lance];
52
53   itemp     = PopuCount( BB_BPRO_KNIGHT );
54   itemp    -= PopuCount( BB_WPRO_KNIGHT );
55   material += itemp * p_value[15+pro_knight];
56
57   itemp     = PopuCount( BB_BPRO_SILVER );
58   itemp    -= PopuCount( BB_WPRO_SILVER );
59   material += itemp * p_value[15+pro_silver];
60
61   itemp     = PopuCount( BB_BHORSE );
62   itemp    -= PopuCount( BB_WHORSE );
63   material += itemp * p_value[15+horse];
64
65   itemp     = PopuCount( BB_BDRAGON );
66   itemp    -= PopuCount( BB_WDRAGON );
67   material += itemp * p_value[15+dragon];
68
69   return material;
70 }
71
72
73 int
74 evaluate( tree_t * restrict ptree, int ply, int turn )
75 {
76   int list0[52], list1[52];
77   int nlist, score, sq_bk, sq_wk, k0, k1, l0, l1, i, j, sum;
78
79   ptree->neval_called++;
80
81   if ( ptree->stand_pat[ply] != score_bound )
82     {
83       return (int)ptree->stand_pat[ply];
84     }
85
86   if ( ehash_probe( HASH_KEY, HAND_B, &score ) )
87     {
88       score                 = turn ? -score : score;
89       ptree->stand_pat[ply] = (short)score;
90
91       return score;
92     }
93
94
95   score = 0;
96   nlist = make_list( ptree, &score, list0, list1 );
97   sq_bk = SQ_BKING;
98   sq_wk = Inv( SQ_WKING );
99
100   sum = 0;
101   for ( i = 0; i < nlist; i++ )
102     {
103       k0 = list0[i];
104       k1 = list1[i];
105       for ( j = 0; j <= i; j++ )
106         {
107           l0 = list0[j];
108           l1 = list1[j];
109           assert( k0 >= l0 && k1 >= l1 );
110           sum += PcPcOnSq( sq_bk, k0, l0 );
111           sum -= PcPcOnSq( sq_wk, k1, l1 );
112         }
113     }
114   
115   score += sum;
116   score /= FV_SCALE;
117
118   score += MATERIAL;
119
120 #if defined(MNJ_LAN)
121   if ( sckt_mnj != SCKT_NULL ) { score += mnj_tbl[ HASH_KEY & MNJ_MASK ]; }
122 #endif
123
124 #if ! defined(MINIMUM)
125   if ( abs(score) > score_max_eval )
126     {
127       out_warning( "A score at evaluate() is out of bounce." );
128     }
129 #endif
130
131   ehash_store( HASH_KEY, HAND_B, score );
132
133   score = turn ? -score : score;
134   ptree->stand_pat[ply] = (short)score;
135
136   return score;
137
138 }
139
140
141 void ehash_clear( void )
142 {
143   memset( ehash_tbl, 0, sizeof(ehash_tbl) );
144 }
145
146
147 static int ehash_probe( uint64_t current_key, unsigned int hand_b,
148                         int *pscore )
149 {
150   uint64_t hash_word, hash_key;
151
152   hash_word = ehash_tbl[ (unsigned int)current_key & EHASH_MASK ];
153
154 #if ! defined(__x86_64__)
155   hash_word ^= hash_word << 32;
156 #endif
157
158   current_key ^= (uint64_t)hand_b << 16;
159   current_key &= ~(uint64_t)0xffffU;
160
161   hash_key  = hash_word;
162   hash_key &= ~(uint64_t)0xffffU;
163
164   if ( hash_key != current_key ) { return 0; }
165
166   *pscore = (int)( (unsigned int)hash_word & 0xffffU ) - 32768;
167
168   return 1;
169 }
170
171
172 static void ehash_store( uint64_t key, unsigned int hand_b, int score )
173 {
174   uint64_t hash_word;
175
176   hash_word  = key;
177   hash_word ^= (uint64_t)hand_b << 16;
178   hash_word &= ~(uint64_t)0xffffU;
179   hash_word |= (uint64_t)( score + 32768 );
180
181 #if ! defined(__x86_64__)
182   hash_word ^= hash_word << 32;
183 #endif
184
185   ehash_tbl[ (unsigned int)key & EHASH_MASK ] = hash_word;
186 }
187
188
189 static int
190 make_list( const tree_t * restrict ptree, int * restrict pscore,
191            int list0[52], int list1[52] )
192 {
193   bitboard_t bb;
194   int list2[34];
195   int nlist, sq, n2, i, score, sq_bk0, sq_wk0, sq_bk1, sq_wk1;
196
197   nlist  = 14;
198   score  = 0;
199   sq_bk0 = SQ_BKING;
200   sq_wk0 = SQ_WKING;
201   sq_bk1 = Inv(SQ_WKING);
202   sq_wk1 = Inv(SQ_BKING);
203
204   list0[ 0] = f_hand_pawn   + I2HandPawn(HAND_B);
205   list0[ 1] = e_hand_pawn   + I2HandPawn(HAND_W);
206   list0[ 2] = f_hand_lance  + I2HandLance(HAND_B);
207   list0[ 3] = e_hand_lance  + I2HandLance(HAND_W);
208   list0[ 4] = f_hand_knight + I2HandKnight(HAND_B);
209   list0[ 5] = e_hand_knight + I2HandKnight(HAND_W);
210   list0[ 6] = f_hand_silver + I2HandSilver(HAND_B);
211   list0[ 7] = e_hand_silver + I2HandSilver(HAND_W);
212   list0[ 8] = f_hand_gold   + I2HandGold(HAND_B);
213   list0[ 9] = e_hand_gold   + I2HandGold(HAND_W);
214   list0[10] = f_hand_bishop + I2HandBishop(HAND_B);
215   list0[11] = e_hand_bishop + I2HandBishop(HAND_W);
216   list0[12] = f_hand_rook   + I2HandRook(HAND_B);
217   list0[13] = e_hand_rook   + I2HandRook(HAND_W);
218
219   list1[ 0] = f_hand_pawn   + I2HandPawn(HAND_W);
220   list1[ 1] = e_hand_pawn   + I2HandPawn(HAND_B);
221   list1[ 2] = f_hand_lance  + I2HandLance(HAND_W);
222   list1[ 3] = e_hand_lance  + I2HandLance(HAND_B);
223   list1[ 4] = f_hand_knight + I2HandKnight(HAND_W);
224   list1[ 5] = e_hand_knight + I2HandKnight(HAND_B);
225   list1[ 6] = f_hand_silver + I2HandSilver(HAND_W);
226   list1[ 7] = e_hand_silver + I2HandSilver(HAND_B);
227   list1[ 8] = f_hand_gold   + I2HandGold(HAND_W);
228   list1[ 9] = e_hand_gold   + I2HandGold(HAND_B);
229   list1[10] = f_hand_bishop + I2HandBishop(HAND_W);
230   list1[11] = e_hand_bishop + I2HandBishop(HAND_B);
231   list1[12] = f_hand_rook   + I2HandRook(HAND_W);
232   list1[13] = e_hand_rook   + I2HandRook(HAND_B);
233
234   score += kkp[sq_bk0][sq_wk0][ kkp_hand_pawn   + I2HandPawn(HAND_B) ];
235   score += kkp[sq_bk0][sq_wk0][ kkp_hand_lance  + I2HandLance(HAND_B) ];
236   score += kkp[sq_bk0][sq_wk0][ kkp_hand_knight + I2HandKnight(HAND_B) ];
237   score += kkp[sq_bk0][sq_wk0][ kkp_hand_silver + I2HandSilver(HAND_B) ];
238   score += kkp[sq_bk0][sq_wk0][ kkp_hand_gold   + I2HandGold(HAND_B) ];
239   score += kkp[sq_bk0][sq_wk0][ kkp_hand_bishop + I2HandBishop(HAND_B) ];
240   score += kkp[sq_bk0][sq_wk0][ kkp_hand_rook   + I2HandRook(HAND_B) ];
241
242   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_pawn   + I2HandPawn(HAND_W) ];
243   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_lance  + I2HandLance(HAND_W) ];
244   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_knight + I2HandKnight(HAND_W) ];
245   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_silver + I2HandSilver(HAND_W) ];
246   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_gold   + I2HandGold(HAND_W) ];
247   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_bishop + I2HandBishop(HAND_W) ];
248   score -= kkp[sq_bk1][sq_wk1][ kkp_hand_rook   + I2HandRook(HAND_W) ];
249
250   n2 = 0;
251   bb = BB_BPAWN;
252   while ( BBToU(bb) ) {
253     sq = FirstOne( bb );
254     Xor( sq, bb );
255
256     list0[nlist] = f_pawn + sq;
257     list2[n2]    = e_pawn + Inv(sq);
258     score += kkp[sq_bk0][sq_wk0][ kkp_pawn + sq ];
259     nlist += 1;
260     n2    += 1;
261   }
262
263   bb = BB_WPAWN;
264   while ( BBToU(bb) ) {
265     sq = FirstOne( bb );
266     Xor( sq, bb );
267
268     list0[nlist] = e_pawn + sq;
269     list2[n2]    = f_pawn + Inv(sq);
270     score -= kkp[sq_bk1][sq_wk1][ kkp_pawn + Inv(sq) ];
271     nlist += 1;
272     n2    += 1;
273   }
274   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
275
276   n2 = 0;
277   bb = BB_BLANCE;
278   while ( BBToU(bb) ) {
279     sq = FirstOne( bb );
280     Xor( sq, bb );
281
282     list0[nlist] = f_lance + sq;
283     list2[n2]    = e_lance + Inv(sq);
284     score += kkp[sq_bk0][sq_wk0][ kkp_lance + sq ];
285     nlist += 1;
286     n2    += 1;
287   }
288
289   bb = BB_WLANCE;
290   while ( BBToU(bb) ) {
291     sq = FirstOne( bb );
292     Xor( sq, bb );
293
294     list0[nlist] = e_lance + sq;
295     list2[n2]    = f_lance + Inv(sq);
296     score -= kkp[sq_bk1][sq_wk1][ kkp_lance + Inv(sq) ];
297     nlist += 1;
298     n2    += 1;
299   }
300   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
301
302
303   n2 = 0;
304   bb = BB_BKNIGHT;
305   while ( BBToU(bb) ) {
306     sq = FirstOne( bb );
307     Xor( sq, bb );
308
309     list0[nlist] = f_knight + sq;
310     list2[n2]    = e_knight + Inv(sq);
311     score += kkp[sq_bk0][sq_wk0][ kkp_knight + sq ];
312     nlist += 1;
313     n2    += 1;
314   }
315
316   bb = BB_WKNIGHT;
317   while ( BBToU(bb) ) {
318     sq = FirstOne( bb );
319     Xor( sq, bb );
320
321     list0[nlist] = e_knight + sq;
322     list2[n2]    = f_knight + Inv(sq);
323     score -= kkp[sq_bk1][sq_wk1][ kkp_knight + Inv(sq) ];
324     nlist += 1;
325     n2    += 1;
326   }
327   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
328
329
330   n2 = 0;
331   bb = BB_BSILVER;
332   while ( BBToU(bb) ) {
333     sq = FirstOne( bb );
334     Xor( sq, bb );
335
336     list0[nlist] = f_silver + sq;
337     list2[n2]    = e_silver + Inv(sq);
338     score += kkp[sq_bk0][sq_wk0][ kkp_silver + sq ];
339     nlist += 1;
340     n2    += 1;
341   }
342
343   bb = BB_WSILVER;
344   while ( BBToU(bb) ) {
345     sq = FirstOne( bb );
346     Xor( sq, bb );
347
348     list0[nlist] = e_silver + sq;
349     list2[n2]    = f_silver + Inv(sq);
350     score -= kkp[sq_bk1][sq_wk1][ kkp_silver + Inv(sq) ];
351     nlist += 1;
352     n2    += 1;
353   }
354   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
355
356
357   n2 = 0;
358   bb = BB_BTGOLD;
359   while ( BBToU(bb) ) {
360     sq = FirstOne( bb );
361     Xor( sq, bb );
362
363     list0[nlist] = f_gold + sq;
364     list2[n2]    = e_gold + Inv(sq);
365     score += kkp[sq_bk0][sq_wk0][ kkp_gold + sq ];
366     nlist += 1;
367     n2    += 1;
368   }
369
370   bb = BB_WTGOLD;
371   while ( BBToU(bb) ) {
372     sq = FirstOne( bb );
373     Xor( sq, bb );
374
375     list0[nlist] = e_gold + sq;
376     list2[n2]    = f_gold + Inv(sq);
377     score -= kkp[sq_bk1][sq_wk1][ kkp_gold + Inv(sq) ];
378     nlist += 1;
379     n2    += 1;
380   }
381   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
382
383
384   n2 = 0;
385   bb = BB_BBISHOP;
386   while ( BBToU(bb) ) {
387     sq = FirstOne( bb );
388     Xor( sq, bb );
389
390     list0[nlist] = f_bishop + sq;
391     list2[n2]    = e_bishop + Inv(sq);
392     score += kkp[sq_bk0][sq_wk0][ kkp_bishop + sq ];
393     nlist += 1;
394     n2    += 1;
395   }
396
397   bb = BB_WBISHOP;
398   while ( BBToU(bb) ) {
399     sq = FirstOne( bb );
400     Xor( sq, bb );
401
402     list0[nlist] = e_bishop + sq;
403     list2[n2]    = f_bishop + Inv(sq);
404     score -= kkp[sq_bk1][sq_wk1][ kkp_bishop + Inv(sq) ];
405     nlist += 1;
406     n2    += 1;
407   }
408   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
409
410
411   n2 = 0;
412   bb = BB_BHORSE;
413   while ( BBToU(bb) ) {
414     sq = FirstOne( bb );
415     Xor( sq, bb );
416
417     list0[nlist] = f_horse + sq;
418     list2[n2]    = e_horse + Inv(sq);
419     score += kkp[sq_bk0][sq_wk0][ kkp_horse + sq ];
420     nlist += 1;
421     n2    += 1;
422   }
423
424   bb = BB_WHORSE;
425   while ( BBToU(bb) ) {
426     sq = FirstOne( bb );
427     Xor( sq, bb );
428
429     list0[nlist] = e_horse + sq;
430     list2[n2]    = f_horse + Inv(sq);
431     score -= kkp[sq_bk1][sq_wk1][ kkp_horse + Inv(sq) ];
432     nlist += 1;
433     n2    += 1;
434   }
435   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
436
437
438   n2 = 0;
439   bb = BB_BROOK;
440   while ( BBToU(bb) ) {
441     sq = FirstOne( bb );
442     Xor( sq, bb );
443
444     list0[nlist] = f_rook + sq;
445     list2[n2]    = e_rook + Inv(sq);
446     score += kkp[sq_bk0][sq_wk0][ kkp_rook + sq ];
447     nlist += 1;
448     n2    += 1;
449   }
450
451   bb = BB_WROOK;
452   while ( BBToU(bb) ) {
453     sq = FirstOne( bb );
454     Xor( sq, bb );
455
456     list0[nlist] = e_rook + sq;
457     list2[n2]    = f_rook + Inv(sq);
458     score -= kkp[sq_bk1][sq_wk1][ kkp_rook + Inv(sq) ];
459     nlist += 1;
460     n2    += 1;
461   }
462   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
463
464
465   n2 = 0;
466   bb = BB_BDRAGON;
467   while ( BBToU(bb) ) {
468     sq = FirstOne( bb );
469     Xor( sq, bb );
470
471     list0[nlist] = f_dragon + sq;
472     list2[n2]    = e_dragon + Inv(sq);
473     score += kkp[sq_bk0][sq_wk0][ kkp_dragon + sq ];
474     nlist += 1;
475     n2    += 1;
476   }
477
478   bb = BB_WDRAGON;
479   while ( BBToU(bb) ) {
480     sq = FirstOne( bb );
481     Xor( sq, bb );
482
483     list0[nlist] = e_dragon + sq;
484     list2[n2]    = f_dragon + Inv(sq);
485     score -= kkp[sq_bk1][sq_wk1][ kkp_dragon + Inv(sq) ];
486     nlist += 1;
487     n2    += 1;
488   }
489   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
490
491   assert( nlist <= 52 );
492   *pscore += score;
493   return nlist;
494 }