Implement undo command
[bonanza.git] / learn2.c
1 #include <stdlib.h>
2 #include <limits.h>
3 #include <float.h>
4 #include <math.h>
5 #include <assert.h>
6 #include "shogi.h"
7
8 #if ! defined(MINIMUM)
9
10 #define GO_THROUGH_ALL_PARAMETERS_BY_FOO                                  \
11   for ( i=0; i < nsquare*pos_n; i++ )           { Foo( pc_on_sq[0][i] ) } \
12   for ( i=0; i < nsquare*nsquare*kkp_end; i++ ) { Foo( kkp[0][0][i] ) }
13
14
15 static void rmt( const double avalue[16], int pc );
16 static void rparam( short *pv, float dv );
17 static void fv_sym( void );
18 static int brand( void );
19 static int make_list( const tree_t * restrict ptree, int list0[52],
20                       int list1[52], int anpiece[16], param_t * restrict pd,
21                       float f );
22
23
24 void
25 ini_param( param_t *p )
26 {
27   int i;
28
29   p->pawn       = p->lance      = p->knight     = p->silver     = 0.0;
30   p->gold       = p->bishop     = p->rook       = p->pro_pawn   = 0.0;
31   p->pro_lance  = p->pro_knight = p->pro_silver = p->horse      = 0.0;
32   p->dragon     = 0.0;
33
34 #define Foo(x) p->x = 0;
35   GO_THROUGH_ALL_PARAMETERS_BY_FOO;
36 #undef Foo
37 }
38
39
40 void
41 add_param( param_t *p1, const param_t *p2 )
42 {
43   int i;
44
45   p1->pawn       += p2->pawn;
46   p1->lance      += p2->lance;
47   p1->knight     += p2->knight;
48   p1->silver     += p2->silver;
49   p1->gold       += p2->gold;
50   p1->bishop     += p2->bishop;
51   p1->rook       += p2->rook;
52   p1->pro_pawn   += p2->pro_pawn;
53   p1->pro_lance  += p2->pro_lance;
54   p1->pro_knight += p2->pro_knight;
55   p1->pro_silver += p2->pro_silver;
56   p1->horse      += p2->horse;
57   p1->dragon     += p2->dragon;
58
59 #define Foo(x) p1->x += p2->x;
60   GO_THROUGH_ALL_PARAMETERS_BY_FOO;
61 #undef Foo
62 }
63
64
65 void
66 fill_param_zero( void )
67 {
68   int i;
69
70   p_value[15+pawn]       = 100;
71   p_value[15+lance]      = 300;
72   p_value[15+knight]     = 300;
73   p_value[15+silver]     = 400;
74   p_value[15+gold]       = 500;
75   p_value[15+bishop]     = 600;
76   p_value[15+rook]       = 700;
77   p_value[15+pro_pawn]   = 400;
78   p_value[15+pro_lance]  = 400;
79   p_value[15+pro_knight] = 400;
80   p_value[15+pro_silver] = 500;
81   p_value[15+horse]      = 800;
82   p_value[15+dragon]     = 1000;
83
84 #define Foo(x) x = 0;
85   GO_THROUGH_ALL_PARAMETERS_BY_FOO;
86 #undef Foo
87
88   set_derivative_param();
89 }
90
91
92 void
93 param_sym( param_t *p )
94 {
95   int q, r, il, ir, ir0, jl, jr, k0l, k0r, k1l, k1r;
96
97   for ( k0l = 0; k0l < nsquare; k0l++ ) {
98     q = k0l / nfile;
99     r = k0l % nfile;
100     k0r = q*nfile + nfile-1-r;
101     if ( k0l > k0r ) { continue; }
102
103     for ( il = 0; il < fe_end; il++ ) {
104       if ( il < fe_hand_end ) { ir0 = il; }
105       else {
106         q = ( il- fe_hand_end ) / nfile;
107         r = ( il- fe_hand_end ) % nfile;
108         ir0 = q*nfile + nfile-1-r + fe_hand_end;
109       }
110
111       for ( jl = 0; jl <= il; jl++ ) {
112         if ( jl < fe_hand_end )
113           {
114             ir = ir0;
115             jr = jl;
116           }
117         else {
118           q = ( jl - fe_hand_end ) / nfile;
119           r = ( jl - fe_hand_end ) % nfile;
120           jr = q*nfile + nfile-1-r + fe_hand_end;
121           if ( jr > ir0 )
122             {
123               ir = jr;
124               jr = ir0;
125             }
126           else { ir = ir0; }
127         }
128         if ( k0l == k0r && il*(il+1)/2+jl >= ir*(ir+1)/2+jr ) { continue; }
129
130         p->PcPcOnSq(k0l,il,jl)
131           = p->PcPcOnSq(k0r,ir,jr)
132           = p->PcPcOnSq(k0l,il,jl) + p->PcPcOnSq(k0r,ir,jr);
133       }
134     }
135   }
136
137   for ( k0l = 0; k0l < nsquare; k0l++ ) {
138     q = k0l / nfile;
139     r = k0l % nfile;
140     k0r = q*nfile + nfile-1-r;
141     if ( k0l > k0r ) { continue; }
142
143     for ( k1l = 0; k1l < nsquare; k1l++ ) {
144       q = k1l / nfile;
145       r = k1l % nfile;
146       k1r = q*nfile + nfile-1-r;
147       if ( k0l == k0r && k1l > k1r ) { continue; }
148
149       for ( il = 0; il < kkp_end; il++ ) {
150         if ( il < kkp_hand_end ) { ir = il; }
151         else {
152           q  = ( il- kkp_hand_end ) / nfile;
153           r  = ( il- kkp_hand_end ) % nfile;
154           ir = q*nfile + nfile-1-r + kkp_hand_end;
155         }
156         if ( k0l == k0r && k1l == k1r && il >= ir ) { continue; }
157
158         p->kkp[k0l][k1l][il]
159           = p->kkp[k0r][k1r][ir]
160           = p->kkp[k0l][k1l][il] + p->kkp[k0r][k1r][ir];
161       }
162     }
163   }
164 }
165
166
167 static void fv_sym( void )
168 {
169   int q, r, il, ir, ir0, jl, jr, k0l, k0r, k1l, k1r;
170
171   for ( k0l = 0; k0l < nsquare; k0l++ ) {
172     q = k0l / nfile;
173     r = k0l % nfile;
174     k0r = q*nfile + nfile-1-r;
175     if ( k0l > k0r ) { continue; }
176
177     for ( il = 0; il < fe_end; il++ ) {
178       if ( il < fe_hand_end ) { ir0 = il; }
179       else {
180         q = ( il- fe_hand_end ) / nfile;
181         r = ( il- fe_hand_end ) % nfile;
182         ir0 = q*nfile + nfile-1-r + fe_hand_end;
183       }
184
185       for ( jl = 0; jl <= il; jl++ ) {
186         if ( jl < fe_hand_end )
187           {
188             ir = ir0;
189             jr = jl;
190           }
191         else {
192           q = ( jl - fe_hand_end ) / nfile;
193           r = ( jl - fe_hand_end ) % nfile;
194           jr = q*nfile + nfile-1-r + fe_hand_end;
195           if ( jr > ir0 )
196             {
197               ir = jr;
198               jr = ir0;
199             }
200           else { ir = ir0; }
201         }
202         if ( k0l == k0r && il*(il+1)/2+jl >= ir*(ir+1)/2+jr ) { continue; }
203
204         PcPcOnSq(k0l,il,jl) = PcPcOnSq(k0r,ir,jr);
205       }
206     }
207   }
208
209   for ( k0l = 0; k0l < nsquare; k0l++ ) {
210     q = k0l / nfile;
211     r = k0l % nfile;
212     k0r = q*nfile + nfile-1-r;
213     if ( k0l > k0r ) { continue; }
214
215     for ( k1l = 0; k1l < nsquare; k1l++ ) {
216       q = k1l / nfile;
217       r = k1l % nfile;
218       k1r = q*nfile + nfile-1-r;
219       if ( k0l == k0r && k1l > k1r ) { continue; }
220
221       for ( il = 0; il < kkp_end; il++ ) {
222         if ( il < kkp_hand_end ) { ir = il; }
223         else {
224           q  = ( il- kkp_hand_end ) / nfile;
225           r  = ( il- kkp_hand_end ) % nfile;
226           ir = q*nfile + nfile-1-r + kkp_hand_end;
227         }
228         if ( k0l == k0r && k1l == k1r && il >= ir ) { continue; }
229
230         kkp[k0l][k1l][il] = kkp[k0r][k1r][ir];
231       }
232     }
233   }
234 }
235
236
237 double
238 calc_penalty( void )
239 {
240   uint64_t u64sum;
241   int i;
242
243   u64sum = 0;
244
245 #define Foo(x) u64sum += (uint64_t)abs((int)x);
246   GO_THROUGH_ALL_PARAMETERS_BY_FOO;
247 #undef Foo
248
249   return (double)u64sum * FV_PENALTY;
250 }
251
252
253 void
254 renovate_param( const param_t *pd )
255 {
256   double *pv[14], *p;
257   double v[16];
258   unsigned int u32rand, u;
259   int i, j;
260
261   v[pawn]       = pd->pawn;         v[lance]      = pd->lance;
262   v[knight]     = pd->knight;       v[silver]     = pd->silver;
263   v[gold]       = pd->gold;         v[bishop]     = pd->bishop;
264   v[rook]       = pd->rook;         v[pro_pawn]   = pd->pro_pawn;
265   v[pro_lance]  = pd->pro_lance;    v[pro_knight] = pd->pro_knight;
266   v[pro_silver] = pd->pro_silver;   v[horse]      = pd->horse;
267   v[dragon]     = pd->dragon;       v[king]       = FLT_MAX;
268
269   pv[ 0] = v + pawn;         pv[ 1] = v + lance;
270   pv[ 2] = v + knight;       pv[ 3] = v + silver;
271   pv[ 4] = v + gold;         pv[ 5] = v + bishop;
272   pv[ 6] = v + rook;         pv[ 7] = v + pro_pawn;
273   pv[ 8] = v + pro_lance;    pv[ 9] = v + pro_knight;
274   pv[10] = v + pro_silver;   pv[11] = v + horse;
275   pv[12] = v + dragon;       pv[13] = v + king;
276
277   /* insertion sort */
278   for ( i = 13 - 2; i >= 0; i-- )
279     {
280       p = pv[i];
281       for ( j = i+1; *pv[j] < *p; j++ ) { pv[j-1] = pv[j]; }
282       pv[j-1] = p;
283     }
284
285   u32rand = rand32();
286   u       = u32rand % 7U;
287   u32rand = u32rand / 7U;
288   p = pv[u+6];  pv[u+6] = pv[12];  pv[12] = p;
289   for ( i = 5; i > 0; i-- )
290     {
291       u       = u32rand % (i+1);
292       u32rand = u32rand / (i+1);
293       p = pv[u];  pv[u] = pv[i];  pv[i] = p;
294
295       u       = u32rand % (i+1);
296       u32rand = u32rand / (i+1);
297       p = pv[u+6];  pv[u+6] = pv[i+6];  pv[i+6] = p;
298     }
299
300   *pv[ 0] = *pv[ 1] = -2.0;
301   *pv[ 2] = *pv[ 3] = *pv[ 4] = -1.0;
302   *pv[ 5] = *pv[ 6] = *pv[ 7] =  0.0;
303   *pv[ 8] = *pv[ 9] = *pv[10] =  1.0;
304   *pv[11] = *pv[12] =  2.0;
305
306   rmt( v, pawn );        rmt( v, lance );       rmt( v, knight );
307   rmt( v, silver );      rmt( v, gold );        rmt( v, bishop );
308   rmt( v, rook );        rmt( v, pro_pawn );    rmt( v, pro_lance );
309   rmt( v, pro_knight );  rmt( v, pro_silver );  rmt( v, horse );
310   rmt( v, dragon );
311
312 #define Foo(v) rparam( &v, pd->v );
313   GO_THROUGH_ALL_PARAMETERS_BY_FOO;
314 #undef Foo
315
316   fv_sym();
317   set_derivative_param();
318   ehash_clear();
319 }
320
321
322 int
323 out_param( void )
324 {
325   size_t size;
326   FILE *pf;
327   int apc[17], apv[17];
328   int iret, i, j, pc, pv;
329
330   for ( i = 0; i < 17; i++ ) { apc[i] = i;  apv[i] = INT_MAX; }
331   apv[pawn]       = p_value_ex[15+pawn];
332   apv[lance]      = p_value_ex[15+lance];
333   apv[knight]     = p_value_ex[15+knight];
334   apv[silver]     = p_value_ex[15+silver];
335   apv[gold]       = p_value_ex[15+gold];
336   apv[bishop]     = p_value_ex[15+bishop];
337   apv[rook]       = p_value_ex[15+rook];
338   apv[pro_pawn]   = p_value_ex[15+pro_pawn];
339   apv[pro_lance]  = p_value_ex[15+pro_lance];
340   apv[pro_knight] = p_value_ex[15+pro_knight];
341   apv[pro_silver] = p_value_ex[15+pro_silver];
342   apv[horse]      = p_value_ex[15+horse];
343   apv[dragon]     = p_value_ex[15+dragon];
344
345   /* insertion sort */
346   for ( i = dragon-1; i >= 0; i-- )
347     {
348       pv = apv[i];  pc = apc[i];
349       for ( j = i+1; apv[j] < pv; j++ )
350         {
351           apv[j-1] = apv[j];
352           apc[j-1] = apc[j];
353         }
354       apv[j-1] = pv;  apc[j-1] = pc;
355     }
356       
357   pf = file_open( "param.h_", "w" );
358   if ( pf == NULL ) { return -2; }
359   
360   for ( i = 0; i < 13; i++ )
361     {
362       fprintf( pf, "#define " );
363       switch ( apc[i] )
364         {
365         case pawn:        fprintf( pf, "DPawn     " );  break;
366         case lance:       fprintf( pf, "DLance    " );  break;
367         case knight:      fprintf( pf, "DKnight   " );  break;
368         case silver:      fprintf( pf, "DSilver   " );  break;
369         case gold:        fprintf( pf, "DGold     " );  break;
370         case bishop:      fprintf( pf, "DBishop   " );  break;
371         case rook:        fprintf( pf, "DRook     " );  break;
372         case pro_pawn:    fprintf( pf, "DProPawn  " );  break;
373         case pro_lance:   fprintf( pf, "DProLance " );  break;
374         case pro_knight:  fprintf( pf, "DProKnight" );  break;
375         case pro_silver:  fprintf( pf, "DProSilver" );  break;
376         case horse:       fprintf( pf, "DHorse    " );  break;
377         case dragon:      fprintf( pf, "DDragon   " );  break;
378         }
379       fprintf( pf, "     %4d /* %4d */\n", p_value[15+apc[i]], apv[i] );
380     }
381   fprintf( pf, "#define DKing         15000\n\n" );
382
383   iret = file_close( pf );
384   if ( iret < 0 ) { return -2; }
385
386   pf = file_open( "fv.bin", "wb" );
387   if ( pf == NULL ) { return -2; }
388
389   size = nsquare * pos_n;
390   if ( fwrite( pc_on_sq, sizeof(short), size, pf ) != size )
391     {
392       str_error = str_io_error;
393       return -2;
394     }
395
396   size = nsquare * nsquare * kkp_end;
397   if ( fwrite( kkp, sizeof(short), size, pf ) != size )
398     {
399       str_error = str_io_error;
400       return -2;
401     }
402   
403   return file_close( pf );
404 }
405
406
407 void
408 inc_param( const tree_t * restrict ptree, param_t * restrict pd, double dinc )
409 {
410   float f;
411   int anpiece[16], list0[52], list1[52];
412   int nlist, sq_bk, sq_wk, k0, k1, l0, l1, i, j;
413
414   f     = (float)( dinc / (double)FV_SCALE );
415   nlist = make_list( ptree, list0, list1, anpiece, pd, f );
416   sq_bk = SQ_BKING;
417   sq_wk = Inv( SQ_WKING );
418
419   pd->pawn       += dinc * (double)anpiece[pawn];
420   pd->lance      += dinc * (double)anpiece[lance];
421   pd->knight     += dinc * (double)anpiece[knight];
422   pd->silver     += dinc * (double)anpiece[silver];
423   pd->gold       += dinc * (double)anpiece[gold];
424   pd->bishop     += dinc * (double)anpiece[bishop];
425   pd->rook       += dinc * (double)anpiece[rook];
426   pd->pro_pawn   += dinc * (double)anpiece[pro_pawn];
427   pd->pro_lance  += dinc * (double)anpiece[pro_lance];
428   pd->pro_knight += dinc * (double)anpiece[pro_knight];
429   pd->pro_silver += dinc * (double)anpiece[pro_silver];
430   pd->horse      += dinc * (double)anpiece[horse];
431   pd->dragon     += dinc * (double)anpiece[dragon];
432
433   for ( i = 0; i < nlist; i++ )
434     {
435       k0 = list0[i];
436       k1 = list1[i];
437       for ( j = 0; j <= i; j++ )
438         {
439           l0 = list0[j];
440           l1 = list1[j];
441           assert( k0 >= l0 && k1 >= l1 );
442           pd->PcPcOnSq( sq_bk, k0, l0 ) += f;
443           pd->PcPcOnSq( sq_wk, k1, l1 ) -= f;
444         }
445     }
446 }
447
448
449 static int
450 make_list( const tree_t * restrict ptree, int list0[52], int list1[52],
451            int anpiece[16], param_t * restrict pd, float f )
452 {
453   bitboard_t bb;
454   int list2[34];
455   int nlist, sq, sq_bk0, sq_bk1, sq_wk0, sq_wk1, n2, i, itemp1, itemp2;
456
457   itemp1          = (int)I2HandPawn(HAND_B);
458   itemp2          = (int)I2HandPawn(HAND_W);
459   anpiece[pawn]   = itemp1 - itemp2;
460
461   itemp1          = (int)I2HandLance(HAND_B);
462   itemp2          = (int)I2HandLance(HAND_W);
463   anpiece[lance]  = itemp1 - itemp2;
464
465   itemp1          = (int)I2HandKnight(HAND_B);
466   itemp2          = (int)I2HandKnight(HAND_W);
467   anpiece[knight] = itemp1 - itemp2;
468
469   itemp1          = (int)I2HandSilver(HAND_B);
470   itemp2          = (int)I2HandSilver(HAND_W);
471   anpiece[silver] = itemp1 - itemp2;
472
473   itemp1          = (int)I2HandGold(HAND_B);
474   itemp2          = (int)I2HandGold(HAND_W);
475   anpiece[gold]   = itemp1 - itemp2;
476
477   itemp1          = (int)I2HandBishop(HAND_B);
478   itemp2          = (int)I2HandBishop(HAND_W);
479   anpiece[bishop] = itemp1 - itemp2;
480
481   itemp1          = (int)I2HandRook(HAND_B);
482   itemp2          = (int)I2HandRook(HAND_W);
483   anpiece[rook]   = itemp1 - itemp2;
484
485   anpiece[pro_pawn]   = anpiece[pro_lance]  = anpiece[pro_knight] = 0;
486   anpiece[pro_silver] = anpiece[horse]      = anpiece[dragon]     = 0;
487   nlist  = 14;
488   sq_bk0 = SQ_BKING;
489   sq_wk0 = SQ_WKING;
490   sq_bk1 = Inv(SQ_WKING);
491   sq_wk1 = Inv(SQ_BKING);
492
493   list0[ 0] = f_hand_pawn   + I2HandPawn(HAND_B);
494   list0[ 1] = e_hand_pawn   + I2HandPawn(HAND_W);
495   list0[ 2] = f_hand_lance  + I2HandLance(HAND_B);
496   list0[ 3] = e_hand_lance  + I2HandLance(HAND_W);
497   list0[ 4] = f_hand_knight + I2HandKnight(HAND_B);
498   list0[ 5] = e_hand_knight + I2HandKnight(HAND_W);
499   list0[ 6] = f_hand_silver + I2HandSilver(HAND_B);
500   list0[ 7] = e_hand_silver + I2HandSilver(HAND_W);
501   list0[ 8] = f_hand_gold   + I2HandGold(HAND_B);
502   list0[ 9] = e_hand_gold   + I2HandGold(HAND_W);
503   list0[10] = f_hand_bishop + I2HandBishop(HAND_B);
504   list0[11] = e_hand_bishop + I2HandBishop(HAND_W);
505   list0[12] = f_hand_rook   + I2HandRook(HAND_B);
506   list0[13] = e_hand_rook   + I2HandRook(HAND_W);
507
508   list1[ 0] = f_hand_pawn   + I2HandPawn(HAND_W);
509   list1[ 1] = e_hand_pawn   + I2HandPawn(HAND_B);
510   list1[ 2] = f_hand_lance  + I2HandLance(HAND_W);
511   list1[ 3] = e_hand_lance  + I2HandLance(HAND_B);
512   list1[ 4] = f_hand_knight + I2HandKnight(HAND_W);
513   list1[ 5] = e_hand_knight + I2HandKnight(HAND_B);
514   list1[ 6] = f_hand_silver + I2HandSilver(HAND_W);
515   list1[ 7] = e_hand_silver + I2HandSilver(HAND_B);
516   list1[ 8] = f_hand_gold   + I2HandGold(HAND_W);
517   list1[ 9] = e_hand_gold   + I2HandGold(HAND_B);
518   list1[10] = f_hand_bishop + I2HandBishop(HAND_W);
519   list1[11] = e_hand_bishop + I2HandBishop(HAND_B);
520   list1[12] = f_hand_rook   + I2HandRook(HAND_W);
521   list1[13] = e_hand_rook   + I2HandRook(HAND_B);
522
523   pd->kkp[sq_bk0][sq_wk0][kkp_hand_pawn  +I2HandPawn(HAND_B)  ] += f;
524   pd->kkp[sq_bk0][sq_wk0][kkp_hand_lance +I2HandLance(HAND_B) ] += f;
525   pd->kkp[sq_bk0][sq_wk0][kkp_hand_knight+I2HandKnight(HAND_B)] += f;
526   pd->kkp[sq_bk0][sq_wk0][kkp_hand_silver+I2HandSilver(HAND_B)] += f;
527   pd->kkp[sq_bk0][sq_wk0][kkp_hand_gold  +I2HandGold(HAND_B)  ] += f;
528   pd->kkp[sq_bk0][sq_wk0][kkp_hand_bishop+I2HandBishop(HAND_B)] += f;
529   pd->kkp[sq_bk0][sq_wk0][kkp_hand_rook  +I2HandRook(HAND_B)  ] += f;
530
531   pd->kkp[sq_bk1][sq_wk1][kkp_hand_pawn  +I2HandPawn(HAND_W)  ] -= f;
532   pd->kkp[sq_bk1][sq_wk1][kkp_hand_lance +I2HandLance(HAND_W) ] -= f;
533   pd->kkp[sq_bk1][sq_wk1][kkp_hand_knight+I2HandKnight(HAND_W)] -= f;
534   pd->kkp[sq_bk1][sq_wk1][kkp_hand_silver+I2HandSilver(HAND_W)] -= f;
535   pd->kkp[sq_bk1][sq_wk1][kkp_hand_gold  +I2HandGold(HAND_W)  ] -= f;
536   pd->kkp[sq_bk1][sq_wk1][kkp_hand_bishop+I2HandBishop(HAND_W)] -= f;
537   pd->kkp[sq_bk1][sq_wk1][kkp_hand_rook  +I2HandRook(HAND_W)  ] -= f;
538
539   n2 = 0;
540   bb = BB_BPAWN;
541   while ( BBToU(bb) ) {
542     sq = FirstOne( bb );
543     Xor( sq, bb );
544
545     pd->kkp[sq_bk0][sq_wk0][kkp_pawn+sq] += f;
546     anpiece[pawn] += 1;
547     list0[nlist] = f_pawn + sq;
548     list2[n2]    = e_pawn + Inv(sq);
549     nlist += 1;
550     n2    += 1;
551   }
552
553   bb = BB_WPAWN;
554   while ( BBToU(bb) ) {
555     sq = FirstOne( bb );
556     Xor( sq, bb );
557
558     pd->kkp[sq_bk1][sq_wk1][kkp_pawn+Inv(sq)] -= f;
559     anpiece[pawn] -= 1;
560     list0[nlist] = e_pawn + sq;
561     list2[n2]    = f_pawn + Inv(sq);
562     nlist += 1;
563     n2    += 1;
564   }
565   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
566
567   n2 = 0;
568   bb = BB_BLANCE;
569   while ( BBToU(bb) ) {
570     sq = FirstOne( bb );
571     Xor( sq, bb );
572
573     pd->kkp[sq_bk0][sq_wk0][kkp_lance+sq] += f;
574     anpiece[lance] += 1;
575     list0[nlist] = f_lance + sq;
576     list2[n2]    = e_lance + Inv(sq);
577     nlist += 1;
578     n2    += 1;
579   }
580
581   bb = BB_WLANCE;
582   while ( BBToU(bb) ) {
583     sq = FirstOne( bb );
584     Xor( sq, bb );
585
586     pd->kkp[sq_bk1][sq_wk1][kkp_lance+Inv(sq)] -= f;
587     anpiece[lance] -= 1;
588     list0[nlist] = e_lance + sq;
589     list2[n2]    = f_lance + Inv(sq);
590     nlist += 1;
591     n2    += 1;
592   }
593   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
594
595
596   n2 = 0;
597   bb = BB_BKNIGHT;
598   while ( BBToU(bb) ) {
599     sq = FirstOne( bb );
600     Xor( sq, bb );
601
602     pd->kkp[sq_bk0][sq_wk0][kkp_knight+sq] += f;
603     anpiece[knight] += 1;
604     list0[nlist] = f_knight + sq;
605     list2[n2]    = e_knight + Inv(sq);
606     nlist += 1;
607     n2    += 1;
608   }
609
610   bb = BB_WKNIGHT;
611   while ( BBToU(bb) ) {
612     sq = FirstOne( bb );
613     Xor( sq, bb );
614
615     pd->kkp[sq_bk1][sq_wk1][kkp_knight+Inv(sq)] -= f;
616     anpiece[knight] -= 1;
617     list0[nlist] = e_knight + sq;
618     list2[n2]    = f_knight + Inv(sq);
619     nlist += 1;
620     n2    += 1;
621   }
622   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
623
624
625   n2 = 0;
626   bb = BB_BSILVER;
627   while ( BBToU(bb) ) {
628     sq = FirstOne( bb );
629     Xor( sq, bb );
630
631     pd->kkp[sq_bk0][sq_wk0][kkp_silver+sq] += f;
632     anpiece[silver] += 1;
633     list0[nlist] = f_silver + sq;
634     list2[n2]    = e_silver + Inv(sq);
635     nlist += 1;
636     n2    += 1;
637   }
638
639   bb = BB_WSILVER;
640   while ( BBToU(bb) ) {
641     sq = FirstOne( bb );
642     Xor( sq, bb );
643
644     pd->kkp[sq_bk1][sq_wk1][kkp_silver+Inv(sq)] -= f;
645     anpiece[silver] -= 1;
646     list0[nlist] = e_silver + sq;
647     list2[n2]    = f_silver + Inv(sq);
648     nlist += 1;
649     n2    += 1;
650   }
651   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
652
653
654   n2 = 0;
655   bb = BB_BTGOLD;
656   while ( BBToU(bb) ) {
657     sq = FirstOne( bb );
658     Xor( sq, bb );
659
660     pd->kkp[sq_bk0][sq_wk0][kkp_gold+sq] += f;
661     anpiece[BOARD[sq]] += 1;
662     list0[nlist] = f_gold + sq;
663     list2[n2]    = e_gold + Inv(sq);
664     nlist += 1;
665     n2    += 1;
666   }
667
668   bb = BB_WTGOLD;
669   while ( BBToU(bb) ) {
670     sq = FirstOne( bb );
671     Xor( sq, bb );
672
673     pd->kkp[sq_bk1][sq_wk1][kkp_gold+Inv(sq)] -= f;
674     anpiece[-BOARD[sq]] -= 1;
675     list0[nlist] = e_gold + sq;
676     list2[n2]    = f_gold + Inv(sq);
677     nlist += 1;
678     n2    += 1;
679   }
680   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
681
682
683   n2 = 0;
684   bb = BB_BBISHOP;
685   while ( BBToU(bb) ) {
686     sq = FirstOne( bb );
687     Xor( sq, bb );
688
689     pd->kkp[sq_bk0][sq_wk0][kkp_bishop+sq] += f;
690     anpiece[bishop] += 1;
691     list0[nlist] = f_bishop + sq;
692     list2[n2]    = e_bishop + Inv(sq);
693     nlist += 1;
694     n2    += 1;
695   }
696
697   bb = BB_WBISHOP;
698   while ( BBToU(bb) ) {
699     sq = FirstOne( bb );
700     Xor( sq, bb );
701
702     pd->kkp[sq_bk1][sq_wk1][kkp_bishop+Inv(sq)] -= f;
703     anpiece[bishop] -= 1;
704     list0[nlist] = e_bishop + sq;
705     list2[n2]    = f_bishop + Inv(sq);
706     nlist += 1;
707     n2    += 1;
708   }
709   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
710
711
712   n2 = 0;
713   bb = BB_BHORSE;
714   while ( BBToU(bb) ) {
715     sq = FirstOne( bb );
716     Xor( sq, bb );
717
718     pd->kkp[sq_bk0][sq_wk0][kkp_horse+sq] += f;
719     anpiece[horse] += 1;
720     list0[nlist] = f_horse + sq;
721     list2[n2]    = e_horse + Inv(sq);
722     nlist += 1;
723     n2    += 1;
724   }
725
726   bb = BB_WHORSE;
727   while ( BBToU(bb) ) {
728     sq = FirstOne( bb );
729     Xor( sq, bb );
730
731     pd->kkp[sq_bk1][sq_wk1][kkp_horse+Inv(sq)] -= f;
732     anpiece[horse] -= 1;
733     list0[nlist] = e_horse + sq;
734     list2[n2]    = f_horse + Inv(sq);
735     nlist += 1;
736     n2    += 1;
737   }
738   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
739
740
741   n2 = 0;
742   bb = BB_BROOK;
743   while ( BBToU(bb) ) {
744     sq = FirstOne( bb );
745     Xor( sq, bb );
746
747     pd->kkp[sq_bk0][sq_wk0][kkp_rook+sq] += f;
748     anpiece[rook] += 1;
749     list0[nlist] = f_rook + sq;
750     list2[n2]    = e_rook + Inv(sq);
751     nlist += 1;
752     n2    += 1;
753   }
754
755   bb = BB_WROOK;
756   while ( BBToU(bb) ) {
757     sq = FirstOne( bb );
758     Xor( sq, bb );
759
760     pd->kkp[sq_bk1][sq_wk1][kkp_rook+Inv(sq)] -= f;
761     anpiece[rook] -= 1;
762     list0[nlist] = e_rook + sq;
763     list2[n2]    = f_rook + Inv(sq);
764     nlist += 1;
765     n2    += 1;
766   }
767   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
768
769
770   n2 = 0;
771   bb = BB_BDRAGON;
772   while ( BBToU(bb) ) {
773     sq = FirstOne( bb );
774     Xor( sq, bb );
775
776     pd->kkp[sq_bk0][sq_wk0][kkp_dragon+sq] += f;
777     anpiece[dragon] += 1;
778     list0[nlist] = f_dragon + sq;
779     list2[n2]    = e_dragon + Inv(sq);
780     nlist += 1;
781     n2    += 1;
782   }
783
784   bb = BB_WDRAGON;
785   while ( BBToU(bb) ) {
786     sq = FirstOne( bb );
787     Xor( sq, bb );
788
789     pd->kkp[sq_bk1][sq_wk1][kkp_dragon+Inv(sq)] -= f;
790     anpiece[dragon] -= 1;
791     list0[nlist] = e_dragon + sq;
792     list2[n2]    = f_dragon + Inv(sq);
793     nlist += 1;
794     n2    += 1;
795   }
796   for ( i = 0; i < n2; i++ ) { list1[nlist-i-1] = list2[i]; }
797
798   assert( nlist <= 52 );
799   return nlist;
800 }
801
802
803 static void
804 rmt( const double avalue[16], int pc )
805 {
806   int pc_v;
807
808   pc_v  = (int)p_value[15+pc] + (int)avalue[pc];
809
810   if ( 0 < pc_v && pc_v <= SHRT_MAX ) { p_value[15+pc] = (short)pc_v; }
811   else {
812     out_warning( "A material value is out of bounce. (%s=%d)\n",
813                  astr_table_piece[pc], pc_v );
814   }
815 }
816
817
818 static void
819 rparam( short *pv, float dv )
820 {
821   int v, istep;
822
823   istep  = brand();
824   istep += brand();
825   v      = *pv;
826
827   if      ( v > 0 ) { dv -= (float)FV_PENALTY; }
828   else if ( v < 0 ) { dv += (float)FV_PENALTY; }
829
830   if      ( dv >= 0.0 && v <= SHRT_MAX - istep ) { v += istep; }
831   else if ( dv <= 0.0 && v >= SHRT_MIN + istep ) { v -= istep; }
832   else { out_warning( "A fvcoef parameter is out of bounce.\n" ); }
833
834   *pv = (short)v;
835 }
836
837
838 static int
839 brand( void )
840 {
841   static unsigned int urand = 0;
842   static unsigned int uc    = 31;
843   unsigned int uret;
844
845   if ( uc == 31 )
846     {
847       urand = rand32();
848       uc    = 0;
849     }
850   else { uc += 1; }
851   uret    = urand & 1U;
852   urand >>= 1;
853   return uret;
854 }
855
856 #endif /* MINIMUM */