Implement undo command
[bonanza.git] / ini.c
1 #include <limits.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #if ! defined(_WIN32)
5 #  include <unistd.h>
6 #endif
7 #include "shogi.h"
8
9 #if   defined(_MSC_VER)
10 #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
11 #else
12 static int first_one00( int pcs );
13 static int last_one00( int pcs );
14 #endif
15
16
17 static void ini_check_table( void );
18 static bitboard_t bb_set_mask( int isquare );
19 static int load_fv( void );
20 static void set_attacks( int irank, int ifilea, bitboard_t *pbb );
21 static void ini_is_same( void );
22 static void ini_tables( void );
23 static void ini_attack_tables( void );
24 static void ini_random_table( void );
25
26
27 static int
28 load_fv( void )
29 {
30   FILE *pf;
31   size_t size;
32   int iret;
33
34   pf = file_open( str_fv, "rb" );
35   if ( pf == NULL ) { return -2; }
36
37   size = nsquare * pos_n;
38   if ( fread( pc_on_sq, sizeof(short), size, pf ) != size )
39     {
40       str_error = str_io_error;
41       return -2;
42     }
43
44   size = nsquare * nsquare * kkp_end;
45   if ( fread( kkp, sizeof(short), size, pf ) != size )
46     {
47       str_error = str_io_error;
48       return -2;
49     }
50
51   iret = file_close( pf );
52   if ( iret < 0 ) { return iret; }
53
54 #if 0
55 #  define X0 -10000
56 #  define X1 +10000
57   {
58     unsigned int a[X1-X0+1];
59     int i, n, iv;
60
61     for ( i = 0; i < X1-X0+1; i++ ) { a[i] = 0; }
62     n = nsquare * pos_n;
63     for ( i = 0; i < n; i++ )
64       {
65         iv = pc_on_sq[0][i];
66         if      ( iv < X0 ) { iv = X0; }
67         else if ( iv > X1 ) { iv = X1; }
68         a[ iv - X0 ] += 1;
69       }
70
71     pf = file_open( "dist.dat", "w" );
72     if ( pf == NULL ) { return -2; }
73
74     for ( i = X0; i <= X1; i++ ) { fprintf( pf, "%d %d\n", i, a[i-X0] ); }
75
76     iret = file_close( pf );
77     if ( iret < 0 ) { return iret; }
78   }
79 #  undef x0
80 #  undef x1
81 #endif
82
83   return 1;
84 }
85
86 /*
87 static int
88 ini_fv( void )
89 {
90   FILE *pf;
91   size_t size, i;
92
93   pf = file_open( str_fv, "wb" );
94   if ( pf == NULL ) { return -2; }
95
96   size = nsquare * pos_n;
97   for ( i = 0; i < size; i++ ) { pc_on_sq[0][i] = 0; }
98   if ( fwrite( pc_on_sq, sizeof(short), size, pf ) != size )
99     {
100       str_error = str_io_error;
101       return -2;
102     }
103
104   size = nsquare * nsquare * kkp_end;
105   for ( i = 0; i < size; i++ ) { kkp[0][0][i] = 0; }
106   if ( fwrite( kkp, sizeof(short), size, pf ) != size )
107     {
108       str_error = str_io_error;
109       return -2;
110     }
111
112   return file_close( pf );
113 }
114 */
115
116 int
117 ini( tree_t * restrict ptree )
118 {
119   int i;
120
121   /*if ( ini_fv() < 0 ) { return -1; }*/
122   if ( load_fv() < 0 ) { return -1; }
123
124   for ( i = 0; i < 31; i++ ) { p_value[i]       = 0; }
125   for ( i = 0; i < 31; i++ ) { p_value_ex[i]    = 0; }
126   for ( i = 0; i < 15; i++ ) { benefit2promo[i] = 0; }
127   p_value[15+pawn]       = DPawn;
128   p_value[15+lance]      = DLance;
129   p_value[15+knight]     = DKnight;
130   p_value[15+silver]     = DSilver;
131   p_value[15+gold]       = DGold;
132   p_value[15+bishop]     = DBishop;
133   p_value[15+rook]       = DRook;
134   p_value[15+king]       = DKing;
135   p_value[15+pro_pawn]   = DProPawn;
136   p_value[15+pro_lance]  = DProLance;
137   p_value[15+pro_knight] = DProKnight;
138   p_value[15+pro_silver] = DProSilver;
139   p_value[15+horse]      = DHorse;
140   p_value[15+dragon]     = DDragon;
141
142   game_status           = 0;
143   str_buffer_cmdline[0] = '\0';
144   ptrans_table_orig     = NULL;
145   record_game.pf        = NULL;
146   node_per_second       = TIME_CHECK_MIN_NODE;
147   node_limit            = UINT64_MAX;
148   time_response         = TIME_RESPONSE;
149   sec_limit             = 0;
150   sec_limit_up          = 10U;
151   sec_limit_depth       = UINT_MAX;
152   depth_limit           = PLY_MAX;
153   log2_ntrans_table     = 20;
154   
155   pf_book               = NULL;
156   pf_hash               = NULL;
157
158 #if defined(TLP)
159   tlp_max        = 1;
160   tlp_abort      = 0;
161   tlp_num        = 0;
162   tlp_idle       = 0;
163   tlp_atree_work[0].tlp_id           = 0;
164   tlp_atree_work[0].tlp_abort        = 0;
165   tlp_atree_work[0].tlp_used         = 1;
166   tlp_atree_work[0].tlp_slot         = 0;
167   tlp_atree_work[0].tlp_nsibling     = 0;
168   if ( lock_init( &tlp_atree_work[0].tlp_lock ) < 0 ) { return -1; }
169   if ( lock_init( &tlp_lock )                   < 0 ) { return -1; }
170   for ( i = 0; i < tlp_max; i++ )
171     {
172       tlp_atree_work->tlp_ptrees_sibling[i] = NULL;
173     }
174   for ( i = 1; i < TLP_NUM_WORK; i++ )
175     {
176       tlp_atree_work[i].tlp_slot = (unsigned short)i;
177       tlp_atree_work[i].tlp_used = 0;
178       if ( lock_init( &tlp_atree_work[i].tlp_lock ) < 0 ) { return -1; }
179     }
180 #  if defined(_WIN32)
181 #  else
182   if ( pthread_attr_init( &pthread_attr )
183        || pthread_attr_setdetachstate( &pthread_attr,
184                                        PTHREAD_CREATE_DETACHED ) )
185     {
186       str_error = "pthread_attr_init() failed.";
187       return -1;
188     }
189 #  endif
190 #endif
191
192 #if defined(CSA_LAN)
193   sckt_csa       = SCKT_NULL;
194   time_last_send = 0U;
195 #endif
196
197 #if defined(MNJ_LAN)
198   for ( i = 1; i < MNJ_MASK + 1; i++ ) { mnj_tbl[i] = 0; }
199   sckt_mnj       = SCKT_NULL;
200   mnj_posi_id    = 0;
201   mnj_move_last  = 0;
202   time_last_send = 0U;
203 #endif
204
205 #if defined(_WIN32)
206 #  if defined(DEKUNOBOU)
207   dek_ngame = 0;
208 #  endif
209 #else
210   clk_tck = (clock_t)sysconf(_SC_CLK_TCK);
211 #endif
212
213 #if ! defined(NO_LOGGING)
214   pf_log = NULL;
215 #endif
216
217 #if   defined(_MSC_VER)
218 #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
219 #else
220   for ( i = 0; i < 0x200; i++ )
221     {
222       aifirst_one[i] = (unsigned char)first_one00(i);
223       ailast_one[i]  = (unsigned char)last_one00(i);
224     }
225 #endif
226   
227   for ( i = 0; i < HASH_REG_HIST_LEN; i++ )
228     {
229       history_book_learn[i].move_responsible = 0;
230       history_book_learn[i].move_probed      = 0;
231       history_book_learn[i].move_played      = 0;
232     }
233
234   ini_rand( 5489U );
235   ini_is_same();
236   ini_tables();
237   ini_attack_tables();
238   ini_random_table();
239   ini_check_table();
240
241   set_derivative_param();
242
243   if ( ini_game( ptree, &min_posi_no_handicap, flag_history, NULL, NULL ) < 0 )
244     {
245       return -1;
246     }
247
248   OutCsaShogi( "%s\n", str_myname );
249   Out( "%s\n", str_myname );
250
251   if ( ini_trans_table() < 0 ) { return -1; }
252
253   if ( book_on() < 0 ) { out_warning( "%s", str_error );}
254   else                 { Out( "%s found\n", str_book );}
255
256   if ( hash_learn_on() < 0 ) { out_warning( "%s", str_error );}
257   else                       { Out( "%s found\n", str_hash );}
258
259   if ( get_elapsed( &time_turn_start ) < 0 ) { return -1; }
260
261   ini_rand( time_turn_start );
262   Out( "rand seed = %x\n", time_turn_start );
263
264   resign_threshold = RESIGN_THRESHOLD;
265
266 #if defined(MPV)
267   mpv_num   = 1;
268   mpv_width = 2 * MT_CAP_PAWN;
269 #endif
270
271   return 1;
272 }
273
274
275 int
276 fin( void )
277 {
278 #if defined(TLP)
279   int i;
280 #endif
281
282   memory_free( (void *)ptrans_table_orig );
283
284 #if defined(TLP)
285   tlp_abort = 1;
286   while ( tlp_num ) { tlp_yield(); }
287   if ( lock_free( &tlp_atree_work[0].tlp_lock ) < 0 ) { return -1; }
288   if ( lock_free( &tlp_lock )                   < 0 ) { return -1; }
289   for ( i = 1; i < TLP_NUM_WORK; i++ )
290     {
291       if ( lock_free( &tlp_atree_work[i].tlp_lock ) < 0 ) { return -1; }
292     }
293 #  if defined(_WIN32)
294 #  else
295   if ( pthread_attr_destroy( &pthread_attr ) )
296     {
297       str_error = "pthread_attr_destroy() failed.";
298       return -1;
299     }
300 #  endif
301 #endif
302
303   if ( book_off() < 0 ) { return -1; }
304   if ( record_close( &record_game ) < 0 ) { return -1; }
305 #if ! defined(NO_LOGGING)
306   if ( file_close( pf_log ) < 0 ) { return -1; }
307 #endif
308
309   return 1;
310 }
311
312
313 void
314 set_derivative_param( void )
315 {
316   p_value_ex[15+pawn]       = p_value[15+pawn]       + p_value[15+pawn];
317   p_value_ex[15+lance]      = p_value[15+lance]      + p_value[15+lance];
318   p_value_ex[15+knight]     = p_value[15+knight]     + p_value[15+knight];
319   p_value_ex[15+silver]     = p_value[15+silver]     + p_value[15+silver];
320   p_value_ex[15+gold]       = p_value[15+gold]       + p_value[15+gold];
321   p_value_ex[15+bishop]     = p_value[15+bishop]     + p_value[15+bishop];
322   p_value_ex[15+rook]       = p_value[15+rook]       + p_value[15+rook];
323   p_value_ex[15+king]       = p_value[15+king]       + p_value[15+king];
324   p_value_ex[15+pro_pawn]   = p_value[15+pro_pawn]   + p_value[15+pawn];
325   p_value_ex[15+pro_lance]  = p_value[15+pro_lance]  + p_value[15+lance];
326   p_value_ex[15+pro_knight] = p_value[15+pro_knight] + p_value[15+knight];
327   p_value_ex[15+pro_silver] = p_value[15+pro_silver] + p_value[15+silver];
328   p_value_ex[15+horse]      = p_value[15+horse]      + p_value[15+bishop];
329   p_value_ex[15+dragon]     = p_value[15+dragon]     + p_value[15+rook];
330
331   benefit2promo[7+pawn]     = p_value[15+pro_pawn]   - p_value[15+pawn];
332   benefit2promo[7+lance]    = p_value[15+pro_lance]  - p_value[15+lance];
333   benefit2promo[7+knight]   = p_value[15+pro_knight] - p_value[15+knight];
334   benefit2promo[7+silver]   = p_value[15+pro_silver] - p_value[15+silver];
335   benefit2promo[7+bishop]   = p_value[15+horse]      - p_value[15+bishop];
336   benefit2promo[7+rook]     = p_value[15+dragon]     - p_value[15+rook];
337
338   p_value[15-pawn]          = p_value[15+pawn];
339   p_value[15-lance]         = p_value[15+lance];
340   p_value[15-knight]        = p_value[15+knight];
341   p_value[15-silver]        = p_value[15+silver];
342   p_value[15-gold]          = p_value[15+gold];
343   p_value[15-bishop]        = p_value[15+bishop];
344   p_value[15-rook]          = p_value[15+rook];
345   p_value[15-king]          = p_value[15+king];
346   p_value[15-pro_pawn]      = p_value[15+pro_pawn];
347   p_value[15-pro_lance]     = p_value[15+pro_lance];
348   p_value[15-pro_knight]    = p_value[15+pro_knight];
349   p_value[15-pro_silver]    = p_value[15+pro_silver];
350   p_value[15-horse]         = p_value[15+horse];
351   p_value[15-dragon]        = p_value[15+dragon];
352
353   p_value_ex[15-pawn]       = p_value_ex[15+pawn];
354   p_value_ex[15-lance]      = p_value_ex[15+lance];
355   p_value_ex[15-knight]     = p_value_ex[15+knight];
356   p_value_ex[15-silver]     = p_value_ex[15+silver];
357   p_value_ex[15-gold]       = p_value_ex[15+gold];
358   p_value_ex[15-bishop]     = p_value_ex[15+bishop];
359   p_value_ex[15-rook]       = p_value_ex[15+rook];
360   p_value_ex[15-king]       = p_value_ex[15+king];
361   p_value_ex[15-pro_pawn]   = p_value_ex[15+pro_pawn];
362   p_value_ex[15-pro_lance]  = p_value_ex[15+pro_lance];
363   p_value_ex[15-pro_knight] = p_value_ex[15+pro_knight];
364   p_value_ex[15-pro_silver] = p_value_ex[15+pro_silver];
365   p_value_ex[15-horse]      = p_value_ex[15+horse];
366   p_value_ex[15-dragon]     = p_value_ex[15+dragon];
367
368   benefit2promo[7-pawn]     = benefit2promo[7+pawn];
369   benefit2promo[7-lance]    = benefit2promo[7+lance];
370   benefit2promo[7-knight]   = benefit2promo[7+knight];
371   benefit2promo[7-silver]   = benefit2promo[7+silver];
372   benefit2promo[7-bishop]   = benefit2promo[7+bishop];
373   benefit2promo[7-rook]     = benefit2promo[7+rook];
374 }
375
376
377 static void
378 ini_is_same( void )
379 {
380   int p[16], i, j;
381
382   for ( i = 0; i < 16; i++ ) { p[i] = 0; }
383
384   p[pawn]       =  1;
385   p[lance]      =  3;
386   p[pro_pawn]   =  3;
387   p[knight]     =  3;
388   p[pro_lance]  =  3;
389   p[pro_knight] =  3;
390   p[silver]     =  4;
391   p[pro_silver] =  4;
392   p[gold]       =  5;
393   p[bishop]     =  6;
394   p[horse]      =  7;
395   p[rook]       =  7;
396   p[dragon]     =  8;
397   p[king]       = 99;
398
399   for ( i = 0; i < 16; i++ )
400     for ( j = 0; j < 16; j++ )
401       {
402         if      ( p[i] < p[j]-1 ) { is_same[i][j] = 2U; }
403         else if ( p[i] > p[j]+1 ) { is_same[i][j] = 1U; }
404         else                      { is_same[i][j] = 0U; }
405       }
406 }
407
408
409 static void
410 ini_tables( void )
411 {
412   const unsigned char aini_rl90[] = { A1, A2, A3, A4, A5, A6, A7, A8, A9,
413                                       B1, B2, B3, B4, B5, B6, B7, B8, B9,
414                                       C1, C2, C3, C4, C5, C6, C7, C8, C9,
415                                       D1, D2, D3, D4, D5, D6, D7, D8, D9,
416                                       E1, E2, E3, E4, E5, E6, E7, E8, E9,
417                                       F1, F2, F3, F4, F5, F6, F7, F8, F9,
418                                       G1, G2, G3, G4, G5, G6, G7, G8, G9,
419                                       H1, H2, H3, H4, H5, H6, H7, H8, H9,
420                                       I1, I2, I3, I4, I5, I6, I7, I8, I9 };
421   
422   const unsigned char aini_rl45[] = { A9, B1, C2, D3, E4, F5, G6, H7, I8,
423                                       A8, B9, C1, D2, E3, F4, G5, H6, I7,
424                                       A7, B8, C9, D1, E2, F3, G4, H5, I6,
425                                       A6, B7, C8, D9, E1, F2, G3, H4, I5,
426                                       A5, B6, C7, D8, E9, F1, G2, H3, I4,
427                                       A4, B5, C6, D7, E8, F9, G1, H2, I3,
428                                       A3, B4, C5, D6, E7, F8, G9, H1, I2,
429                                       A2, B3, C4, D5, E6, F7, G8, H9, I1,
430                                       A1, B2, C3, D4, E5, F6, G7, H8, I9 };
431   
432   const unsigned char aini_rr45[] = { I8, I7, I6, I5, I4, I3, I2, I1, I9,
433                                       H7, H6, H5, H4, H3, H2, H1, H9, H8,
434                                       G6, G5, G4, G3, G2, G1, G9, G8, G7,
435                                       F5, F4, F3, F2, F1, F9, F8, F7, F6,
436                                       E4, E3, E2, E1, E9, E8, E7, E6, E5,
437                                       D3, D2, D1, D9, D8, D7, D6, D5, D4,
438                                       C2, C1, C9, C8, C7, C6, C5, C4, C3,
439                                       B1, B9, B8, B7, B6, B5, B4, B3, B2,
440                                       A9, A8, A7, A6, A5, A4, A3, A2, A1 };
441   bitboard_t abb_plus1dir[ nsquare ];
442   bitboard_t abb_plus8dir[ nsquare ];
443   bitboard_t abb_plus9dir[ nsquare ];
444   bitboard_t abb_plus10dir[ nsquare ];
445   bitboard_t abb_minus1dir[ nsquare ];
446   bitboard_t abb_minus8dir[ nsquare ];
447   bitboard_t abb_minus9dir[ nsquare ];
448   bitboard_t abb_minus10dir[ nsquare ];
449   bitboard_t bb;
450   int isquare, i, ito, ifrom, irank, ifile;
451   int isquare_rl90, isquare_rl45, isquare_rr45;
452
453   for ( isquare = 0; isquare < nsquare; isquare++ )
454     {
455       isquare_rl90 = aini_rl90[isquare];
456       isquare_rl45 = aini_rl45[isquare];
457       isquare_rr45 = aini_rr45[isquare];
458       abb_mask[isquare]      = bb_set_mask( isquare );
459       abb_mask_rl90[isquare] = bb_set_mask( isquare_rl90 );
460       abb_mask_rl45[isquare] = bb_set_mask( isquare_rl45 );
461       abb_mask_rr45[isquare] = bb_set_mask( isquare_rr45 );
462     }
463
464   for ( irank = 0; irank < nrank; irank++ )
465     for ( ifile = 0; ifile < nfile; ifile++ )
466       {
467         isquare = irank*nfile + ifile;
468         BBIni( abb_plus1dir[isquare] );
469         BBIni( abb_plus8dir[isquare] );
470         BBIni( abb_plus9dir[isquare] );
471         BBIni( abb_plus10dir[isquare] );
472         BBIni( abb_minus1dir[isquare] );
473         BBIni( abb_minus8dir[isquare] );
474         BBIni( abb_minus9dir[isquare] );
475         BBIni( abb_minus10dir[isquare] );
476         for ( i = 1; i < nfile; i++ )
477           {
478             set_attacks( irank,   ifile+i, abb_plus1dir   + isquare );
479             set_attacks( irank+i, ifile-i, abb_plus8dir   + isquare );
480             set_attacks( irank+i, ifile,   abb_plus9dir   + isquare );
481             set_attacks( irank+i, ifile+i, abb_plus10dir  + isquare );
482             set_attacks( irank,   ifile-i, abb_minus1dir  + isquare );
483             set_attacks( irank-i, ifile+i, abb_minus8dir  + isquare );
484             set_attacks( irank-i, ifile,   abb_minus9dir  + isquare );
485             set_attacks( irank-i, ifile-i, abb_minus10dir + isquare );
486           }
487       }
488
489
490   for ( isquare = 0; isquare < nsquare; isquare++ )
491     {
492       BBOr( abb_plus_rays[isquare],
493             abb_plus1dir[isquare],  abb_plus8dir[isquare] );
494       BBOr( abb_plus_rays[isquare],
495             abb_plus_rays[isquare], abb_plus9dir[isquare] );
496       BBOr( abb_plus_rays[isquare],
497             abb_plus_rays[isquare], abb_plus10dir[isquare] );
498       BBOr( abb_minus_rays[isquare],
499             abb_minus1dir[isquare],  abb_minus8dir[isquare] );
500       BBOr( abb_minus_rays[isquare],
501             abb_minus_rays[isquare], abb_minus9dir[isquare] );
502       BBOr( abb_minus_rays[isquare],
503             abb_minus_rays[isquare], abb_minus10dir[isquare] );
504     }
505
506
507   for ( ifrom = 0; ifrom < nsquare; ifrom++ )
508     {
509       for ( ito = 0; ito < nsquare; ito++ )
510         {
511           adirec[ifrom][ito] = (unsigned char)direc_misc;
512         }
513
514       BBOr( bb, abb_plus1dir[ifrom], abb_minus1dir[ifrom] );
515       while ( BBToU(bb) )
516         {
517           ito = FirstOne( bb );
518           adirec[ifrom][ito]  = (unsigned char)direc_rank;
519           Xor( ito, bb );
520         }
521       BBOr( bb, abb_plus8dir[ifrom], abb_minus8dir[ifrom] );
522       while ( BBToU(bb) )
523         {
524           ito = FirstOne( bb );
525           adirec[ifrom][ito]  = (unsigned char)direc_diag1;
526           Xor( ito, bb );
527         }
528       BBOr( bb, abb_plus9dir[ifrom], abb_minus9dir[ifrom] );
529       while ( BBToU(bb) )
530         {
531           ito = FirstOne( bb );
532           adirec[ifrom][ito]  = (unsigned char)direc_file;
533           Xor(ito,bb);
534         }
535       BBOr( bb, abb_plus10dir[ifrom], abb_minus10dir[ifrom] );
536       while ( BBToU(bb) )
537         {
538           ito = FirstOne( bb );
539           adirec[ifrom][ito]  = (unsigned char)direc_diag2;
540           Xor( ito, bb );
541         }
542     }
543
544   for ( ifrom = 0; ifrom < nsquare; ifrom++ )
545     for ( ito = 0; ito < nsquare; ito++ )
546       {
547         BBIni( abb_obstacle[ifrom][ito] );
548
549         if ( ifrom-ito > 0 ) switch ( adirec[ifrom][ito] )
550           {
551           case direc_rank:
552             BBXor( abb_obstacle[ifrom][ito],
553                    abb_minus1dir[ito+1], abb_minus1dir[ifrom] );
554             break;
555           case direc_file:
556             BBXor( abb_obstacle[ifrom][ito],
557                    abb_minus9dir[ito+9], abb_minus9dir[ifrom] );
558             break;
559           case direc_diag1:
560             BBXor( abb_obstacle[ifrom][ito],
561                    abb_minus8dir[ito+8], abb_minus8dir[ifrom] );
562             break;
563           case direc_diag2:
564             BBXor( abb_obstacle[ifrom][ito],
565                    abb_minus10dir[ito+10], abb_minus10dir[ifrom] );
566             break;
567           }
568         else switch ( adirec[ifrom][ito] )
569           {
570           case direc_rank:
571             BBXor( abb_obstacle[ifrom][ito],
572                    abb_plus1dir[ito-1], abb_plus1dir[ifrom] );
573             break;
574           case direc_file:
575             BBXor( abb_obstacle[ifrom][ito],
576                    abb_plus9dir[ito-9], abb_plus9dir[ifrom] );
577             break;
578           case direc_diag1:
579             BBXor( abb_obstacle[ifrom][ito],
580                    abb_plus8dir[ito-8], abb_plus8dir[ifrom] );
581             break;
582           case direc_diag2:
583             BBXor( abb_obstacle[ifrom][ito],
584                    abb_plus10dir[ito-10], abb_plus10dir[ifrom] );
585             break;
586           }
587       }
588 }
589
590
591 static void
592 ini_random_table( void )
593 {
594   int i;
595
596   for ( i = 0; i < nsquare; i++ )
597     {
598       b_pawn_rand[ i ]       = rand64();
599       b_lance_rand[ i ]      = rand64();
600       b_knight_rand[ i ]     = rand64();
601       b_silver_rand[ i ]     = rand64();
602       b_gold_rand[ i ]       = rand64();
603       b_bishop_rand[ i ]     = rand64();
604       b_rook_rand[ i ]       = rand64();
605       b_king_rand[ i ]       = rand64();
606       b_pro_pawn_rand[ i ]   = rand64();
607       b_pro_lance_rand[ i ]  = rand64();
608       b_pro_knight_rand[ i ] = rand64();
609       b_pro_silver_rand[ i ] = rand64();
610       b_horse_rand[ i ]      = rand64();
611       b_dragon_rand[ i ]     = rand64();
612       w_pawn_rand[ i ]       = rand64();
613       w_lance_rand[ i ]      = rand64();
614       w_knight_rand[ i ]     = rand64();
615       w_silver_rand[ i ]     = rand64();
616       w_gold_rand[ i ]       = rand64();
617       w_bishop_rand[ i ]     = rand64();
618       w_rook_rand[ i ]       = rand64();
619       w_king_rand[ i ]       = rand64();
620       w_pro_pawn_rand[ i ]   = rand64();
621       w_pro_lance_rand[ i ]  = rand64();
622       w_pro_knight_rand[ i ] = rand64();
623       w_pro_silver_rand[ i ] = rand64();
624       w_horse_rand[ i ]      = rand64();
625       w_dragon_rand[ i ]     = rand64();
626     }
627
628   for ( i = 0; i < npawn_max; i++ )
629     {
630       b_hand_pawn_rand[ i ]   = rand64();
631       w_hand_pawn_rand[ i ]   = rand64();
632     }
633
634   for ( i = 0; i < nlance_max; i++ )
635     {
636       b_hand_lance_rand[ i ]  = rand64();
637       b_hand_knight_rand[ i ] = rand64();
638       b_hand_silver_rand[ i ] = rand64();
639       b_hand_gold_rand[ i ]   = rand64();
640       w_hand_lance_rand[ i ]  = rand64();
641       w_hand_knight_rand[ i ] = rand64();
642       w_hand_silver_rand[ i ] = rand64();
643       w_hand_gold_rand[ i ]   = rand64();
644     }
645
646   for ( i = 0; i < nbishop_max; i++ )
647     {
648       b_hand_bishop_rand[ i ] = rand64();
649       b_hand_rook_rand[ i ]   = rand64();
650       w_hand_bishop_rand[ i ] = rand64();
651       w_hand_rook_rand[ i ]   = rand64();
652     }
653 }
654
655
656 static void
657 ini_attack_tables( void )
658 {
659   int irank, ifile, pcs, i;
660   bitboard_t bb;
661
662   for ( irank = 0; irank < nrank; irank++ )
663     for ( ifile = 0; ifile < nfile; ifile++ )
664       {
665         BBIni(bb);
666         set_attacks( irank-1, ifile-1, &bb );
667         set_attacks( irank-1, ifile+1, &bb );
668         set_attacks( irank+1, ifile-1, &bb );
669         set_attacks( irank+1, ifile+1, &bb );
670         set_attacks( irank-1, ifile, &bb );
671         abb_b_silver_attacks[ irank*nfile + ifile ] = bb;
672
673         BBIni(bb);
674         set_attacks( irank-1, ifile-1, &bb );
675         set_attacks( irank-1, ifile+1, &bb );
676         set_attacks( irank+1, ifile-1, &bb );
677         set_attacks( irank+1, ifile+1, &bb );
678         set_attacks( irank+1, ifile,   &bb );
679         abb_w_silver_attacks[ irank*nfile + ifile ] = bb;
680
681         BBIni(bb);
682         set_attacks( irank-1, ifile-1, &bb );
683         set_attacks( irank-1, ifile+1, &bb );
684         set_attacks( irank-1, ifile,   &bb );
685         set_attacks( irank+1, ifile,   &bb );
686         set_attacks( irank,   ifile-1, &bb );
687         set_attacks( irank,   ifile+1, &bb );
688         abb_b_gold_attacks[ irank*nfile + ifile ] = bb;
689
690         BBIni(bb);
691         set_attacks( irank+1, ifile-1, &bb );
692         set_attacks( irank+1, ifile+1, &bb );
693         set_attacks( irank+1, ifile,   &bb );
694         set_attacks( irank-1, ifile,   &bb );
695         set_attacks( irank,   ifile-1, &bb );
696         set_attacks( irank,   ifile+1, &bb );
697         abb_w_gold_attacks[ irank*nfile + ifile ] = bb;
698
699         BBIni(bb);
700         set_attacks( irank+1, ifile-1, &bb );
701         set_attacks( irank+1, ifile+1, &bb );
702         set_attacks( irank+1, ifile,   &bb );
703         set_attacks( irank-1, ifile-1, &bb );
704         set_attacks( irank-1, ifile+1, &bb );
705         set_attacks( irank-1, ifile,   &bb );
706         set_attacks( irank,   ifile-1, &bb );
707         set_attacks( irank,   ifile+1, &bb );
708         abb_king_attacks[ irank*nfile + ifile ] = bb;
709       }
710
711   for ( irank = 0; irank < nrank; irank++ )
712     for ( ifile = 0; ifile < nfile; ifile++ )
713       {
714         BBIni(bb);
715         set_attacks( irank-2, ifile-1, &bb );
716         set_attacks( irank-2, ifile+1, &bb );
717         abb_b_knight_attacks[ irank*nfile + ifile ] = bb;
718       }
719
720   for ( irank = 0; irank < nrank; irank++ )
721     for ( ifile = 0; ifile < nfile; ifile++ )
722       {
723         BBIni(bb);
724         set_attacks( irank+2, ifile-1, &bb );
725         set_attacks( irank+2, ifile+1, &bb );
726         abb_w_knight_attacks[ irank*nfile + ifile ] = bb;
727       }
728
729   for ( irank = 0; irank < nrank; irank++ )
730     for ( ifile = 0; ifile < nrank; ifile++ )
731       for ( pcs = 0; pcs < 128; pcs++ )
732         {
733           BBIni(bb);
734           for ( i = -1; irank+i >= 0; i-- )
735             {
736               set_attacks( irank+i, ifile, &bb );
737               if ( (pcs<<1) & (1 << (8-irank-i)) ) { break; }
738             }
739           for ( i = 1; irank+i <= 8; i++ )
740             {
741               set_attacks( irank+i, ifile, &bb );
742               if ( (pcs<<1) & (1 << (8-irank-i)) ) { break; }
743             }
744           abb_file_attacks[irank*nfile+ifile][pcs] = bb; 
745         }
746
747   for ( irank = 0; irank < nrank; irank++ )
748     for ( ifile = 0; ifile < nrank; ifile++ )
749       for ( pcs = 0; pcs < 128; pcs++ )
750         {
751           BBIni(bb);
752           for ( i = -1; ifile+i >= 0; i-- )
753             {
754               set_attacks( irank, ifile+i, &bb );
755               if ( (pcs<<1) & (1 << (8-ifile-i)) ) { break; }
756             }
757           for ( i = 1; ifile+i <= 8; i++ )
758             {
759               set_attacks( irank, ifile+i, &bb );
760               if ( (pcs<<1) & (1 << (8-ifile-i)) ) { break; }
761             }
762           ai_rook_attacks_r0[irank*nfile+ifile][pcs] = bb.p[irank/3]; 
763         }
764
765   for ( irank = 0; irank < nrank; irank++ )
766     for ( ifile = 0; ifile < nrank; ifile++ )
767       for ( pcs = 0; pcs < 128; pcs++ )
768         {
769           BBIni(bb);
770           if ( ifile <= irank )
771             {
772               for ( i = -1; ifile+i >= 0; i-- )
773                 {
774                   set_attacks( irank+i, ifile+i, &bb );
775                   if ( (pcs<<1) & (1 << (8-ifile-i)) ) { break; }
776                 }
777               for ( i = 1; irank+i <= 8; i++ )
778                 {
779                   set_attacks( irank+i, ifile+i, &bb );
780                   if ( (pcs<<1) & (1 << (8-ifile-i)) ) { break; }
781                 }
782             }  
783           else {
784             for ( i = -1; irank+i >= 0; i-- )
785               {
786                 set_attacks( irank+i, ifile+i, &bb );
787                 if ( (pcs<<1) & (1 << (8-ifile-i)) ) { break; }
788               }
789             for ( i = 1; ifile+i <= 8; i++ )
790               {
791                 set_attacks( irank+i, ifile+i, &bb );
792                 if ( (pcs<<1) & (1 << (8-ifile-i)) ) { break; }
793               }
794           }
795           abb_bishop_attacks_rl45[irank*nfile+ifile][pcs] = bb; 
796         }
797
798   for ( irank = 0; irank < nrank; irank++ )
799     for ( ifile = 0; ifile < nrank; ifile++ )
800       for ( pcs = 0; pcs < 128; pcs++ )
801         {
802           BBIni(bb);
803           if ( ifile+irank >= 8 )
804             {
805               for ( i = -1; irank-i <= 8; i-- )
806                 {
807                   set_attacks( irank-i, ifile+i, &bb );
808                   if ( (pcs<<1) & (1 << (irank-i)) ) { break; }
809                 }
810               for ( i = 1; ifile+i <= 8; i++ )
811                 {
812                   set_attacks( irank-i, ifile+i, &bb );
813                   if ( (pcs<<1) & (1 << (irank-i)) ) { break; }
814                 }
815             }  
816           else {
817             for ( i = -1; ifile+i >= 0; i-- )
818               {
819                 set_attacks( irank-i, ifile+i, &bb );
820                 if ( (pcs<<1) & (1 << (irank-i)) ) { break; }
821               }
822             for ( i = 1; irank-i >= 0; i++ )
823               {
824                 set_attacks( irank-i, ifile+i, &bb );
825                 if ( (pcs<<1) & (1 << (irank-i)) ) { break; }
826               }
827           }
828           abb_bishop_attacks_rr45[irank*nfile+ifile][pcs] = bb; 
829         }
830
831   for ( i = 0; i < nsquare; i++ )
832     {
833       aslide[i].ir0   = (unsigned char)(i/27);
834       aslide[i].sr0   = (unsigned char)((2-(i/9)%3)*9+1);
835       aslide[i].irl90 = (unsigned char)(2-(i%9)/3);
836       aslide[i].srl90 = (unsigned char)(((i%9)%3)*9+1);
837     }
838   
839   for ( irank = 0; irank < nrank; irank++ )
840     for ( ifile = 0; ifile < nfile; ifile++ )
841       {
842         if ( irank >= ifile )
843           {
844             aslide[ irank*nfile+ifile ].irl45
845               = (unsigned char)((irank-ifile)/3);
846             aslide[ irank*nfile+ifile ].srl45
847               = (unsigned char)((2-((irank-ifile)%3))*9+1);
848           }
849         else {
850           aslide[ irank*nfile+ifile ].irl45
851             = (unsigned char)((9+irank-ifile)/3);
852           aslide[ irank*nfile+ifile ].srl45
853             = (unsigned char)((2-((9+irank-ifile)%3))*9+1);
854         }
855       }
856
857   for ( irank = 0; irank < nrank; irank++ )
858     for ( ifile = 0; ifile < nfile; ifile++ )
859       {
860         if ( ifile+irank >= 8 )
861           {
862             aslide[ irank*nfile+ifile ].irr45
863               = (unsigned char)((irank+ifile-8)/3);
864             aslide[ irank*nfile+ifile ].srr45
865               = (unsigned char)((2-((irank+ifile-8)%3))*9+1);
866           }
867         else {
868           aslide[ irank*nfile+ifile ].irr45
869             = (unsigned char)((irank+ifile+1)/3);
870           aslide[ irank*nfile+ifile ].srr45
871             = (unsigned char)((2-((irank+ifile+1)%3))*9+1);
872         }
873       }
874 }
875
876
877 static void
878 set_attacks( int irank, int ifile, bitboard_t *pbb )
879 {
880   if ( irank >= rank1 && irank <= rank9 && ifile >= file1 && ifile <= file9 )
881     {
882       Xor( irank*nfile + ifile, *pbb );
883     }
884 }
885
886
887 static bitboard_t
888 bb_set_mask( int isquare )
889 {
890   bitboard_t bb;
891   
892   if ( isquare > 53 )
893     {
894       bb.p[0] = bb.p[1] = 0;
895       bb.p[2] = 1U << (80-isquare);
896     }
897   else if ( isquare > 26 )
898     {
899       bb.p[0] = bb.p[2] = 0;
900       bb.p[1] = 1U << (53-isquare);
901     }
902   else {
903       bb.p[1] = bb.p[2] = 0;
904       bb.p[0] = 1U << (26-isquare);
905   }
906
907   return bb;
908 }
909
910
911 static void
912 ini_check_table( void )
913 {
914   bitboard_t bb_check, bb;
915   int iking, icheck;
916
917   for ( iking = 0; iking < nsquare; iking++ )
918     {
919       /* black gold */
920       BBIni( b_chk_tbl[iking].gold );
921       bb_check = abb_w_gold_attacks[iking];
922       while ( BBToU(bb_check) )
923         {
924           icheck = LastOne( bb_check );
925           BBOr( b_chk_tbl[iking].gold, b_chk_tbl[iking].gold,
926                 abb_w_gold_attacks[icheck] );
927           Xor( icheck, bb_check );
928         }
929       BBOr( bb, abb_mask[iking], abb_w_gold_attacks[iking] );
930       BBNot( bb, bb );
931       BBAnd( b_chk_tbl[iking].gold, b_chk_tbl[iking].gold, bb );
932
933       /* black silver */
934       BBIni( b_chk_tbl[iking].silver );
935       bb_check = abb_w_silver_attacks[iking];
936       while ( BBToU(bb_check) )
937         {
938           icheck = LastOne( bb_check );
939           BBOr( b_chk_tbl[iking].silver, b_chk_tbl[iking].silver,
940                 abb_w_silver_attacks[icheck] );
941           Xor( icheck, bb_check );
942         }
943       bb_check.p[0] = abb_w_gold_attacks[iking].p[0];
944       while ( bb_check.p[0] )
945         {
946           icheck = last_one0( bb_check.p[0] );
947           BBOr( b_chk_tbl[iking].silver, b_chk_tbl[iking].silver,
948                 abb_w_silver_attacks[icheck] );
949           bb_check.p[0] ^= abb_mask[icheck].p[0];
950         }
951       bb_check.p[1] = abb_w_gold_attacks[iking].p[1];
952       while ( bb_check.p[1] )
953         {
954           icheck = last_one1( bb_check.p[1] );
955           b_chk_tbl[iking].silver.p[0]
956             |= abb_w_silver_attacks[icheck].p[0];
957           bb_check.p[1] ^= abb_mask[icheck].p[1];
958         }
959       BBOr( bb, abb_mask[iking], abb_w_silver_attacks[iking] );
960       BBNot( bb, bb );
961       BBAnd( b_chk_tbl[iking].silver, b_chk_tbl[iking].silver, bb );
962
963       /* black knight */
964       BBIni( b_chk_tbl[iking].knight );
965       bb_check = abb_w_knight_attacks[iking];
966       while ( BBToU(bb_check) )
967         {
968           icheck = LastOne( bb_check );
969           BBOr( b_chk_tbl[iking].knight, b_chk_tbl[iking].knight,
970                 abb_w_knight_attacks[icheck] );
971           Xor( icheck, bb_check );
972         }
973       bb_check.p[0] = abb_w_gold_attacks[iking].p[0];
974       while ( bb_check.p[0] )
975         {
976           icheck = last_one0( bb_check.p[0] );
977           BBOr( b_chk_tbl[iking].knight, b_chk_tbl[iking].knight,
978                 abb_w_knight_attacks[icheck] );
979           bb_check.p[0] ^= abb_mask[icheck].p[0];
980         }
981
982       /* black lance */
983       if ( iking <= I3 ) {
984         BBAnd( b_chk_tbl[iking].lance, abb_plus_rays[iking+nfile],
985                abb_file_attacks[iking][0] );
986         if ( iking <= I7 && iking != A9 && iking != A8 && iking != A7 ) {
987           BBAnd( bb, abb_plus_rays[iking-1], abb_file_attacks[iking-1][0] );
988           BBOr( b_chk_tbl[iking].lance, b_chk_tbl[iking].lance, bb );
989         }
990         if ( iking <= I7 && iking != I9 && iking != I8 && iking != I7 ) {
991             BBAnd( bb, abb_plus_rays[iking+1], abb_file_attacks[iking+1][0] );
992             BBOr( b_chk_tbl[iking].lance, b_chk_tbl[iking].lance, bb );
993         }
994       } else { BBIni( b_chk_tbl[iking].lance ); }
995
996       /* white gold */
997       BBIni( w_chk_tbl[iking].gold );
998       bb_check = abb_b_gold_attacks[iking];
999       while ( BBToU(bb_check) )
1000         {
1001           icheck = LastOne( bb_check );
1002           BBOr( w_chk_tbl[iking].gold, w_chk_tbl[iking].gold,
1003                 abb_b_gold_attacks[icheck] );
1004           Xor( icheck, bb_check );
1005         }
1006       BBOr( bb, abb_mask[iking], abb_b_gold_attacks[iking] );
1007       BBNot( bb, bb );
1008       BBAnd( w_chk_tbl[iking].gold, w_chk_tbl[iking].gold, bb );
1009
1010       /* white silver */
1011       BBIni( w_chk_tbl[iking].silver );
1012       bb_check = abb_b_silver_attacks[iking];
1013       while ( BBToU(bb_check) )
1014         {
1015           icheck = LastOne( bb_check );
1016           BBOr( w_chk_tbl[iking].silver, w_chk_tbl[iking].silver,
1017                 abb_b_silver_attacks[icheck] );
1018           Xor( icheck, bb_check );
1019         }
1020       bb_check.p[2] = abb_b_gold_attacks[iking].p[2];
1021       while ( bb_check.p[2] )
1022         {
1023           icheck = first_one2( bb_check.p[2] );
1024           BBOr( w_chk_tbl[iking].silver, w_chk_tbl[iking].silver,
1025                 abb_b_silver_attacks[icheck] );
1026           bb_check.p[2] ^= abb_mask[icheck].p[2];
1027         }
1028       bb_check.p[1] = abb_b_gold_attacks[iking].p[1];
1029       while ( bb_check.p[1] )
1030         {
1031           icheck = first_one1( bb_check.p[1] );
1032           w_chk_tbl[iking].silver.p[2]
1033             |= abb_b_silver_attacks[icheck].p[2];
1034           bb_check.p[1] ^= abb_mask[icheck].p[1];
1035         }
1036       BBOr( bb, abb_mask[iking], abb_b_silver_attacks[iking] );
1037       BBNot( bb, bb );
1038       BBAnd( w_chk_tbl[iking].silver, w_chk_tbl[iking].silver, bb );
1039
1040       /* white knight */
1041       BBIni( w_chk_tbl[iking].knight );
1042       bb_check = abb_b_knight_attacks[iking];
1043       while ( BBToU(bb_check) )
1044         {
1045           icheck = LastOne( bb_check );
1046           BBOr( w_chk_tbl[iking].knight, w_chk_tbl[iking].knight,
1047                 abb_b_knight_attacks[icheck] );
1048           Xor( icheck, bb_check );
1049         }
1050       bb_check.p[2] = abb_b_gold_attacks[iking].p[2];
1051       while ( bb_check.p[2] )
1052         {
1053           icheck = first_one2( bb_check.p[2] );
1054           BBOr( w_chk_tbl[iking].knight, w_chk_tbl[iking].knight,
1055                 abb_b_knight_attacks[icheck] );
1056           bb_check.p[2] ^= abb_mask[icheck].p[2];
1057         }
1058
1059       /* white lance */
1060       if ( iking >= A7 ) {
1061         BBAnd( w_chk_tbl[iking].lance, abb_minus_rays[iking-nfile],
1062                abb_file_attacks[iking][0] );
1063         if ( iking >= A3 && iking != A3 && iking != A2 && iking != A1 ) {
1064           BBAnd( bb, abb_minus_rays[iking-1], abb_file_attacks[iking-1][0] );
1065           BBOr( w_chk_tbl[iking].lance, w_chk_tbl[iking].lance, bb );
1066         }
1067         if ( iking >= A3 && iking != I3 && iking != I2 && iking != I1 ) {
1068           BBAnd( bb, abb_minus_rays[iking+1], abb_file_attacks[iking+1][0] );
1069           BBOr( w_chk_tbl[iking].lance, w_chk_tbl[iking].lance, bb );
1070         }
1071       } else { BBIni( w_chk_tbl[iking].lance ); }
1072     }
1073 }
1074
1075
1076 #if   defined(_MSC_VER)
1077 #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
1078 #else
1079 static int
1080 first_one00( int pcs )
1081 {
1082   int i;
1083
1084   for ( i = 0; i < 9; i++ ) { if ( pcs & (1<<(8-i)) ) { break; } }
1085   return i;
1086 }
1087
1088
1089 static int
1090 last_one00( int pcs )
1091 {
1092   int i;
1093
1094   for ( i = 8; i >= 0; i-- ) { if ( pcs & (1<<(8-i)) ) { break; } }
1095   return i;
1096 }
1097 #endif