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