Fix force mode after setboard
[bonanza.git] / utility.c
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 #include <limits.h>
7 #include "shogi.h"
8
9
10 int CONV
11 ini_game( tree_t * restrict ptree, const min_posi_t *pmin_posi, int flag,
12           const char *str_name1, const char *str_name2 )
13 {
14   bitboard_t bb;
15   int piece;
16   int sq, iret;
17
18 #if defined(INANIWA_SHIFT)
19   if ( inaniwa_flag )
20     {
21       inaniwa_flag = 0;
22       ehash_clear();
23       iret = ini_trans_table();
24       if ( iret < 0 ) { return iret; }
25     }
26 #endif
27
28   if ( flag & flag_history )
29     {
30       iret = open_history( str_name1, str_name2 );
31       if ( iret < 0 ) { return iret; }
32     }
33
34   if ( ! ( flag & flag_nofmargin ) )
35     {
36       fmg_misc      = FMG_MISC;
37       fmg_cap       = FMG_CAP;
38       fmg_drop      = FMG_DROP;
39       fmg_mt        = FMG_MT;
40       fmg_misc_king = FMG_MISC_KING;
41       fmg_cap_king  = FMG_CAP_KING;
42     }
43
44   memcpy( ptree->posi.asquare, pmin_posi->asquare, nsquare );
45   ptree->move_last[0]  = ptree->amove;
46   ptree->nsuc_check[0] = 0;
47   ptree->nsuc_check[1] = 0;
48   ptree->nrep          = 0;
49   root_turn            = pmin_posi->turn_to_move;
50   HAND_B               = pmin_posi->hand_black;
51   HAND_W               = pmin_posi->hand_white;
52   MATERIAL             = 0;
53
54   BBIni( BB_BOCCUPY );
55   BBIni( BB_BPAWN );
56   BBIni( BB_BLANCE );
57   BBIni( BB_BKNIGHT );
58   BBIni( BB_BSILVER );
59   BBIni( BB_BGOLD );
60   BBIni( BB_BBISHOP );
61   BBIni( BB_BROOK );
62   BBIni( BB_BPRO_PAWN );
63   BBIni( BB_BPRO_LANCE );
64   BBIni( BB_BPRO_KNIGHT );
65   BBIni( BB_BPRO_SILVER );
66   BBIni( BB_BHORSE );
67   BBIni( BB_BDRAGON );
68   BBIni( BB_BTGOLD );
69   BBIni( BB_WOCCUPY );
70   BBIni( BB_WPAWN );
71   BBIni( BB_WLANCE );
72   BBIni( BB_WKNIGHT );
73   BBIni( BB_WSILVER );
74   BBIni( BB_WGOLD );
75   BBIni( BB_WBISHOP );
76   BBIni( BB_WROOK );
77   BBIni( BB_WPRO_PAWN );
78   BBIni( BB_WPRO_LANCE );
79   BBIni( BB_WPRO_KNIGHT );
80   BBIni( BB_WPRO_SILVER );
81   BBIni( BB_WHORSE );
82   BBIni( BB_WDRAGON );
83   BBIni( BB_WTGOLD );
84   BBIni( OCCUPIED_FILE );
85   BBIni( OCCUPIED_DIAG1 );
86   BBIni( OCCUPIED_DIAG2 );
87
88   for ( sq = 0; sq < nsquare; sq++ ) {
89     piece = BOARD[sq];
90     if ( piece > 0 ) {
91       Xor( sq, BB_BOCCUPY );
92       XorFile( sq, OCCUPIED_FILE );
93       XorDiag1( sq, OCCUPIED_DIAG1 );
94       XorDiag2( sq, OCCUPIED_DIAG2 );
95       switch ( piece )
96         {
97         case pawn:        Xor( sq, BB_BPAWN );        break;
98         case lance:       Xor( sq, BB_BLANCE );       break;
99         case knight:      Xor( sq, BB_BKNIGHT );      break;
100         case silver:      Xor( sq, BB_BSILVER );      break;
101         case rook:        Xor( sq, BB_BROOK );        break;
102         case bishop:      Xor( sq, BB_BBISHOP );      break;
103         case king:        SQ_BKING = (char)sq;        break;
104         case dragon:      Xor( sq, BB_BDRAGON );      break;
105         case horse:       Xor( sq, BB_BHORSE );       break;
106         case gold:        Xor( sq, BB_BGOLD );        break;
107         case pro_pawn:    Xor( sq, BB_BPRO_PAWN );    break;
108         case pro_lance:   Xor( sq, BB_BPRO_LANCE );   break;
109         case pro_knight:  Xor( sq, BB_BPRO_KNIGHT );  break;
110         case pro_silver:  Xor( sq, BB_BPRO_SILVER );  break;
111         }
112     }
113     else if ( piece < 0 ) {
114       Xor( sq, BB_WOCCUPY );
115       XorFile( sq, OCCUPIED_FILE );
116       XorDiag1( sq, OCCUPIED_DIAG1 );
117       XorDiag2( sq, OCCUPIED_DIAG2 );
118       switch ( - piece )
119         {
120         case pawn:        Xor( sq, BB_WPAWN );        break;
121         case lance:       Xor( sq, BB_WLANCE );       break;
122         case knight:      Xor( sq, BB_WKNIGHT );      break;
123         case silver:      Xor( sq, BB_WSILVER );      break;
124         case rook:        Xor( sq, BB_WROOK );        break;
125         case bishop:      Xor( sq, BB_WBISHOP );      break;
126         case king:        SQ_WKING = (char)sq;        break;
127         case dragon:      Xor( sq, BB_WDRAGON );      break;
128         case horse:       Xor( sq, BB_WHORSE );       break;
129         case gold:        Xor( sq, BB_WGOLD );        break;
130         case pro_pawn:    Xor( sq, BB_WPRO_PAWN );    break;
131         case pro_lance:   Xor( sq, BB_WPRO_LANCE );   break;
132         case pro_knight:  Xor( sq, BB_WPRO_KNIGHT );  break;
133         case pro_silver:  Xor( sq, BB_WPRO_SILVER );  break;
134         }
135     }
136   }
137
138   BBOr( BB_BTGOLD, BB_BPRO_PAWN,   BB_BGOLD );
139   BBOr( BB_BTGOLD, BB_BPRO_LANCE,  BB_BTGOLD );
140   BBOr( BB_BTGOLD, BB_BPRO_KNIGHT, BB_BTGOLD );
141   BBOr( BB_BTGOLD, BB_BPRO_SILVER, BB_BTGOLD );
142   BBOr( BB_B_HDK,  BB_BHORSE,      BB_BDRAGON );
143   BBOr( BB_B_HDK,  BB_BKING,       BB_B_HDK );
144   BBOr( BB_B_BH,   BB_BBISHOP,     BB_BHORSE );
145   BBOr( BB_B_RD,   BB_BROOK,       BB_BDRAGON );
146
147   BBOr( BB_WTGOLD, BB_WPRO_PAWN,   BB_WGOLD );
148   BBOr( BB_WTGOLD, BB_WPRO_LANCE,  BB_WTGOLD );
149   BBOr( BB_WTGOLD, BB_WPRO_KNIGHT, BB_WTGOLD );
150   BBOr( BB_WTGOLD, BB_WPRO_SILVER, BB_WTGOLD );
151   BBOr( BB_W_HDK,  BB_WHORSE,      BB_WDRAGON );
152   BBOr( BB_W_HDK,  BB_WKING,       BB_W_HDK );
153   BBOr( BB_W_BH,   BB_WBISHOP,     BB_WHORSE );
154   BBOr( BB_W_RD,   BB_WROOK,       BB_WDRAGON );
155
156   BB_BPAWN_ATK.p[0]  = ( BB_BPAWN.p[0] <<  9 ) & 0x7ffffffU;
157   BB_BPAWN_ATK.p[0] |= ( BB_BPAWN.p[1] >> 18 ) & 0x00001ffU;
158   BB_BPAWN_ATK.p[1]  = ( BB_BPAWN.p[1] <<  9 ) & 0x7ffffffU;
159   BB_BPAWN_ATK.p[1] |= ( BB_BPAWN.p[2] >> 18 ) & 0x00001ffU;
160   BB_BPAWN_ATK.p[2]  = ( BB_BPAWN.p[2] <<  9 ) & 0x7ffffffU;
161
162   BB_WPAWN_ATK.p[2]  = ( BB_WPAWN.p[2] >>  9 );
163   BB_WPAWN_ATK.p[2] |= ( BB_WPAWN.p[1] << 18 ) & 0x7fc0000U;
164   BB_WPAWN_ATK.p[1]  = ( BB_WPAWN.p[1] >>  9 );
165   BB_WPAWN_ATK.p[1] |= ( BB_WPAWN.p[0] << 18 ) & 0x7fc0000U;
166   BB_WPAWN_ATK.p[0]  = ( BB_WPAWN.p[0] >>  9 );
167
168   MATERIAL = eval_material( ptree );
169   HASH_KEY = hash_func( ptree );
170
171   memset( ptree->hist_good,       0, sizeof(ptree->hist_good) );
172   memset( ptree->hist_tried,      0, sizeof(ptree->hist_tried) );
173
174   game_status &= ( flag_reverse | flag_narrow_book
175                    | flag_time_extendable | flag_learning
176                    | flag_nobeep | flag_nostress | flag_nopeek
177                    | flag_noponder | flag_noprompt | flag_sendpv
178                    | flag_nostdout | flag_nonewlog );
179
180   sec_b_total     = 0;
181   sec_w_total     = 0;
182   sec_elapsed     = 0;
183   last_root_value = 0;
184   last_pv.depth   = 0;
185   last_pv.length  = 0;
186   last_pv.a[0]    = 0;
187   last_pv.a[1]    = 0;
188
189   if ( InCheck( root_turn ) )
190     {
191       ptree->nsuc_check[1] = 1U;
192       if ( is_mate( ptree, 1 ) ) { game_status |= flag_mated; }
193     }
194
195   BBOr( bb, BB_BPAWN, BB_WPAWN );
196   BBOr( bb, bb, BB_BPRO_PAWN );
197   BBOr( bb, bb, BB_WPRO_PAWN );
198   npawn_box  = npawn_max;
199   npawn_box -= PopuCount( bb );
200   npawn_box -= (int)I2HandPawn(HAND_B);
201   npawn_box -= (int)I2HandPawn(HAND_W);
202
203   BBOr( bb, BB_BLANCE, BB_WLANCE );
204   BBOr( bb, bb, BB_BPRO_LANCE );
205   BBOr( bb, bb, BB_WPRO_LANCE );
206   nlance_box  = nlance_max;
207   nlance_box -= PopuCount( bb );
208   nlance_box -= (int)I2HandLance(HAND_B);
209   nlance_box -= (int)I2HandLance(HAND_W);
210   
211   BBOr( bb, BB_BKNIGHT, BB_WKNIGHT );
212   BBOr( bb, bb, BB_BPRO_KNIGHT );
213   BBOr( bb, bb, BB_WPRO_KNIGHT );
214   nknight_box  = nknight_max;
215   nknight_box -= PopuCount( bb );
216   nknight_box -= (int)I2HandKnight(HAND_B);
217   nknight_box -= (int)I2HandKnight(HAND_W);
218
219   BBOr( bb, BB_BSILVER, BB_WSILVER );
220   BBOr( bb, bb, BB_BPRO_SILVER );
221   BBOr( bb, bb, BB_WPRO_SILVER );
222   nsilver_box  = nsilver_max;
223   nsilver_box -= PopuCount( bb );
224   nsilver_box -= (int)I2HandSilver(HAND_B);
225   nsilver_box -= (int)I2HandSilver(HAND_W);
226
227   BBOr( bb, BB_BGOLD, BB_WGOLD );
228   ngold_box  = ngold_max;
229   ngold_box -= PopuCount( bb );
230   ngold_box -= (int)I2HandGold(HAND_B);
231   ngold_box -= (int)I2HandGold(HAND_W);
232
233   BBOr( bb, BB_BBISHOP, BB_WBISHOP );
234   BBOr( bb, bb, BB_BHORSE );
235   BBOr( bb, bb, BB_WHORSE );
236   nbishop_box  = nbishop_max;
237   nbishop_box -= PopuCount( bb );
238   nbishop_box -= (int)I2HandBishop(HAND_B);
239   nbishop_box -= (int)I2HandBishop(HAND_W);
240
241   BBOr( bb, BB_BROOK, BB_WROOK );
242   BBOr( bb, bb, BB_BDRAGON );
243   BBOr( bb, bb, BB_WDRAGON );
244   nrook_box  = nrook_max;
245   nrook_box -= PopuCount( bb );
246   nrook_box -= (int)I2HandRook(HAND_B);
247   nrook_box -= (int)I2HandRook(HAND_W);
248
249   iret = exam_tree( ptree );
250   if ( iret < 0 )
251     {
252       ini_game( ptree, &min_posi_no_handicap, 0, NULL, NULL );
253       return iret;
254     }
255
256   /* connect to Tsumeshogi server */
257 #if defined(DFPN_CLIENT)
258   lock( &dfpn_client_lock );
259   dfpn_client_start( ptree );
260   snprintf( (char *)dfpn_client_signature, DFPN_CLIENT_SIZE_SIGNATURE,
261             "%" PRIx64 "_%x_%x_%x", HASH_KEY, HAND_B, HAND_W, root_turn );
262   dfpn_client_signature[DFPN_CLIENT_SIZE_SIGNATURE-1] = '\0';
263   dfpn_client_rresult       = dfpn_client_na;
264   dfpn_client_num_cresult   = 0;
265   dfpn_client_flag_read     = 0;
266   dfpn_client_out( "new %s\n", dfpn_client_signature );
267   unlock( &dfpn_client_lock );
268 #endif
269
270   return 1;
271 }
272
273
274 int CONV gen_legal_moves( tree_t * restrict ptree, unsigned int *p0, int flag )
275 {
276   unsigned int *p1;
277   int i, j, n;
278
279   p1 = GenCaptures( root_turn, p0 );
280   p1 = GenNoCaptures( root_turn, p1 );
281   if ( flag )
282     {
283       p1 = GenCapNoProEx2( root_turn, p1 );
284       p1 = GenNoCapNoProEx2( root_turn, p1 );
285     }
286   p1 = GenDrop( root_turn, p1 );
287   n  = (int)( p1 - p0 );
288
289   for ( i = 0; i < n; i++ )
290     {
291       MakeMove( root_turn, p0[i], 1 );
292       if ( InCheck( root_turn ) )
293         {
294           UnMakeMove( root_turn, p0[i], 1 );
295           p0[i] = 0;
296           continue;
297         }
298       if ( InCheck(Flip(root_turn)) )
299         {
300           ptree->nsuc_check[2] = (unsigned char)( ptree->nsuc_check[0] + 1U );
301           if ( ptree->nsuc_check[2] >= 6U
302                && ( detect_repetition( ptree, 2, Flip(root_turn), 3 )
303                     == perpetual_check ) )
304             {
305               UnMakeMove( root_turn, p0[i], 1 );
306               p0[i] = 0;
307               continue;
308             }
309         }
310       UnMakeMove( root_turn, p0[i], 1 );
311     }
312
313   for ( i = 0; i < n; )
314     {
315       if ( ! p0[i] )
316         {
317           for ( j = i+1; j < n; j++ ) { p0[j-1] = p0[j]; }
318           n -= 1;
319         }
320       else { i++; }
321     }
322
323   return n;
324 }
325
326
327 /*
328   - detection of perpetual check is omitted.
329   - weak moves are omitted.
330 */
331 int CONV
332 is_mate( tree_t * restrict ptree, int ply )
333 {
334   int iret = 0;
335
336   assert( InCheck(root_turn) );
337
338   ptree->move_last[ply] = GenEvasion( root_turn, ptree->move_last[ply-1] );
339   if ( ptree->move_last[ply] == ptree->move_last[ply-1] ) { iret = 1; }
340
341   return iret;
342 }
343
344
345 int CONV
346 is_hand_eq_supe( unsigned int u, unsigned int uref )
347 {
348 #if 1
349 /* aggressive superior correspondences are applied, that is:
350  *   pawn  <= lance, silver, gold, rook
351  *   lance <= rook.
352  */
353   int nsupe;
354
355   if ( IsHandKnight(u) < IsHandKnight(uref)
356        || IsHandSilver(u) < IsHandSilver(uref)
357        || IsHandGold(u)   < IsHandGold(uref)
358        || IsHandBishop(u) < IsHandBishop(uref)
359        || IsHandRook(u)   < IsHandRook(uref) ) { return 0; }
360
361   nsupe  = (int)I2HandRook(u)  - (int)I2HandRook(uref);
362   nsupe += (int)I2HandLance(u) - (int)I2HandLance(uref);
363   if ( nsupe < 0 ) { return 0; }
364
365   nsupe += (int)I2HandSilver(u) - (int)I2HandSilver(uref);
366   nsupe += (int)I2HandGold(u)   - (int)I2HandGold(uref);
367   nsupe += (int)I2HandPawn(u)   - (int)I2HandPawn(uref);
368   if ( nsupe < 0 ) { return 0; }
369
370   return 1;
371 #else
372   if ( IsHandPawn(u) >= IsHandPawn(uref)
373        && IsHandLance(u)  >= IsHandLance(uref)
374        && IsHandKnight(u) >= IsHandKnight(uref)
375        && IsHandSilver(u) >= IsHandSilver(uref)
376        && IsHandGold(u)   >= IsHandGold(uref)
377        && IsHandBishop(u) >= IsHandBishop(uref)
378        && IsHandRook(u)   >= IsHandRook(uref) ) { return 1; }
379   
380   return 0;
381 #endif
382 }
383
384
385 /* weak moves are omitted. */
386 int CONV
387 detect_repetition( tree_t * restrict ptree, int ply, int turn, int nth )
388 {
389   const unsigned int *p;
390   unsigned int hand1, hand2;
391   int n, i, imin, counter, irep, ncheck;
392
393   ncheck = (int)ptree->nsuc_check[ply];
394   n      = ptree->nrep + ply - 1;
395
396   /*if ( ncheck >= 6 )*/
397   if ( ncheck >= nth * 2 )
398     {
399       /* imin = n - ncheck*2; */
400       imin = n - ncheck*2 + 1;
401       if ( imin < 0 ) { imin = 0; }
402
403       ptree->move_last[ply] = GenEvasion( turn, ptree->move_last[ply-1] );
404       for ( p = ptree->move_last[ply-1]; p < ptree->move_last[ply]; p++ )
405         {
406           MakeMove( turn, *p, ply );
407
408           /* for ( i = n-1, counter = 0; i >= imin; i -= 2 ) */
409           for ( i = n-3, counter = 0; i >= imin; i -= 2 )
410             {
411               if ( ptree->rep_board_list[i] == HASH_KEY
412                    && ptree->rep_hand_list[i] == HAND_B
413                    && ++counter == nth )
414                    /* && ncheck*2 - 1 >= n - i )*/
415                 {
416                   UnMakeMove( turn, *p, ply );
417                   move_evasion_pchk = *p;
418                   return perpetual_check;
419                 }
420             }
421           UnMakeMove( turn, *p, ply );
422         }
423     }
424
425   irep = no_rep;
426   for ( i = n-4, counter = 0; i >= 0; i-- )
427     {
428       if ( ptree->rep_board_list[i] == HASH_KEY )
429         {
430           hand1 = HAND_B;
431           hand2 = ptree->rep_hand_list[i];
432
433           if ( (n-i) & 1 )
434             {
435               if ( irep == no_rep )
436                 {
437                   if ( turn )
438                     {
439                       if ( is_hand_eq_supe( hand2, hand1 ) )
440                         {
441                           irep = white_superi_rep;
442                         }
443                     }
444                   else if ( is_hand_eq_supe( hand1, hand2 ) )
445                     {
446                       irep = black_superi_rep;
447                     }
448                 }
449             }
450           else if ( hand1 == hand2 )
451             {
452               if ( ++counter == nth )
453                 {
454                   if ( (ncheck-1)*2 >= n - i ) { return perpetual_check; }
455                   else                         { return four_fold_rep; }
456                 }
457             }
458           else if ( irep == no_rep )
459             {
460               if ( is_hand_eq_supe( hand1, hand2 ) )
461                 {
462                   irep = black_superi_rep;
463                 }
464               else if ( is_hand_eq_supe( hand2, hand1 ) )
465                 {
466                   irep = white_superi_rep;
467                 }
468             }
469         }
470     }
471
472   return irep;
473 }
474
475
476 int CONV
477 com_turn_start( tree_t * restrict ptree, int flag )
478 {
479   const char *str_move;
480   unsigned int move, sec_total;
481   int iret, is_resign, value;
482
483   if ( ! ( flag & flag_from_ponder ) )
484     {
485       assert( ! ( game_status & mask_game_end ) );
486       
487       time_start = time_turn_start;
488       
489       game_status |=  flag_thinking;
490       iret         = iterate( ptree );
491       game_status &= ~flag_thinking;
492       if ( iret < 0 ) { return iret; }
493     }
494   if ( game_status & flag_suspend ) { return 1; }
495
496   move     = last_pv.a[1];
497   value    = root_turn ? -last_root_value : last_root_value;
498
499   if ( value < -resign_threshold && last_pv.type != pv_fail_high )
500     {
501       is_resign = 1;
502     }
503   else { is_resign = 0; }
504
505 #if defined(DBG_EASY)
506   if ( easy_move && easy_move != move )
507     {
508       out_warning( "EASY MOVE DITECTION FAILED." );
509     }
510 #endif
511
512   /* send urgent outputs */
513   if ( is_resign )
514     {
515 #if defined(CSA_LAN)
516       if ( sckt_csa != SCKT_NULL )
517         {
518           iret = sckt_out( sckt_csa, "%%TORYO\n" );
519           if ( iret < 0 ) { return iret; }
520         }
521 #endif
522       OutCsaShogi( "resign\n" );
523     }
524   else {
525 #if defined(USI)
526     if ( usi_mode != usi_off )
527       {
528         char buf[6];
529         csa2usi( ptree, str_CSA_move(move), buf );
530         USIOut( "bestmove %s\n", buf );
531       }
532 #endif
533
534     OutCsaShogi( "move%s\n", str_CSA_move( move ) );
535
536 #if defined(CSA_LAN)
537     if ( sckt_csa != SCKT_NULL ) {
538       
539       if ( game_status & flag_sendpv ) {
540         int i, turn, byte;
541         char buf[256];
542         
543         byte = snprintf( buf, 256, "%c%s,\'* %d",
544                          ach_turn[root_turn], str_CSA_move( move ),
545                          last_root_value );
546         
547         turn = root_turn;
548         for( i = 2; i <= last_pv.length && i < 5; i++ )
549           {
550             turn = Flip(turn);
551             byte += snprintf( buf+byte, 256-byte, " %c%s",
552                               ach_turn[turn], str_CSA_move(last_pv.a[i]) );
553           }
554         
555         iret = sckt_out( sckt_csa, "%s\n", buf );
556         if ( iret < 0 ) { return iret; }
557         
558       } else {
559         
560         iret = sckt_out( sckt_csa, "%c%s\n", ach_turn[root_turn],
561                          str_CSA_move( move ) );
562         if ( iret < 0 ) { return iret; }
563       }
564     }
565 #endif
566   }
567   OutBeep();
568   
569   /* show search result and make a move */
570   if ( is_resign )
571     {
572       show_prompt();
573       game_status |= flag_resigned;
574       update_time( root_turn );
575       out_CSA( ptree, &record_game, MOVE_RESIGN );
576       sec_total = root_turn ? sec_w_total : sec_b_total;
577       str_move  = "resign";
578     }
579   else {
580     show_prompt();
581     iret = make_move_root( ptree, move,
582                            ( flag_rep | flag_time | flag_history ) );
583     if ( iret < 0 ) { return iret; }
584     sec_total = root_turn ? sec_b_total : sec_w_total;
585     str_move  = str_CSA_move( move );
586   }
587
588   OutCsaShogi( "info tt %03u:%02u\n", sec_total / 60U, sec_total % 60U );
589 #ifdef XBOARD
590   { extern char xboard_mode;
591     if(xboard_mode) { // print move in WB format and defuse next line
592       if(str_move[0] < '0' || str_move[0] > '9') Out("\n%s\n# ", str_move); // only resign?
593       else if(str_move[0] == '0')
594         Out("\nmove %c@%c%c\n# ", // drop
595                "PLNSGBR"[(move>>7&127)-nsquare],
596                '9'+'a'-str_move[2], '1'+'9'-str_move[3]);
597       else Out("\n#t=%d tm=%d\nmove %c%c%c%c%s\n# ", time_limit, time_max_limit,
598                '9'+'a'-str_move[0], '1'+'9'-str_move[1],
599                '9'+'a'-str_move[2], '1'+'9'-str_move[3], (move & FLAG_PROMO ? "+" : "="));
600     }
601   }
602 #endif
603   Out( "%s '(%d%s) %03u:%02u/%03u:%02u  elapsed: b%u, w%u\n",
604        str_move, value,
605        ( last_pv.type == pv_fail_high ) ? "!" : "",
606        sec_elapsed / 60U, sec_elapsed % 60U,
607        sec_total   / 60U, sec_total   % 60U,
608        sec_b_total, sec_w_total );
609  
610   if ( ! is_resign )
611     {
612 #if ! defined(NO_STDOUT)
613       iret = out_board( ptree, stdout, move, 0 );
614       if ( iret < 0 ) { return iret; }
615 #endif
616     }
617
618   return 1;
619 }
620
621 #if defined(MNJ_LAN)
622 int CONV mnj_reset_tbl( int sd, unsigned int seed )
623 {
624   double average, deviation, d;
625   unsigned int u;
626   int i, j;
627
628   if ( sd <= 0 ) { return load_fv(); }
629
630   if ( load_fv()           < 0 ) { return -1; }
631   if ( clear_trans_table() < 0 ) { return -1; }
632   ehash_clear();
633
634
635   ini_rand( seed );
636   average   = 0.0;
637   deviation = 0.0;
638
639   for( i = 0; i < nsquare * pos_n; i++ )
640     {
641       d = -6.0;
642
643       for ( j = 0; j < 12; j++ ) { d += (double)rand32() / (double)UINT_MAX; }
644       d             *= (double)sd;
645       average       += d;
646       deviation     += d * d;
647       pc_on_sq[0][i] = (short)( (int)pc_on_sq[0][i] + (int)d );
648     }
649
650   for( i = 0; i < nsquare * nsquare * kkp_end; i++ )
651     {
652       d = -6.0;
653
654       for ( j = 0; j < 12; j++ ) { d += (double)rand32() / (double)UINT_MAX; }
655       d           *= (double)sd;
656       average     += d;
657       deviation   += d * d;
658       kkp[0][0][i] = (short)( (int)kkp[0][0][i] + (int)d );
659     }
660
661   average   /= (double)( nsquare * pos_n + nsquare * nsquare * kkp_end );
662   deviation /= (double)( nsquare * pos_n + nsquare * nsquare * kkp_end );
663   deviation  = sqrt( deviation );
664
665   if ( get_elapsed( &u ) < 0 ) { return -1; }
666   ini_rand( u );
667
668   Out( "\nThe normal distribution N(0,sd^2) is generated.\n" );
669   Out( "  actual average:            % .7f\n", average );
670   Out( "  actual standard deviation: % .7f\n", deviation );
671   Out( "rand seed = %x\n", u );
672
673   return 1;
674 }
675 #endif
676
677 void * CONV memory_alloc( size_t nbytes )
678 {
679 #if defined(_WIN32)
680   void *p = VirtualAlloc( NULL, nbytes, MEM_COMMIT, PAGE_READWRITE );
681   if ( p == NULL ) { str_error = "VirturlAlloc() faild"; }
682 #else
683   void *p = malloc( nbytes );
684   if ( p == NULL ) { str_error = "malloc() faild"; }
685 #endif
686   return p;
687 }
688
689
690 int CONV memory_free( void *p )
691 {
692 #if defined(_WIN32)
693   if ( VirtualFree( p, 0, MEM_RELEASE ) ) { return 1; }
694   str_error = "VirtualFree() faild";
695   return -2;
696 #else
697   free( p );
698   return 1;
699 #endif
700 }