11 ini_game( tree_t * restrict ptree, const min_posi_t *pmin_posi, int flag,
12 const char *str_name1, const char *str_name2 )
18 #if defined(INANIWA_SHIFT)
23 iret = ini_trans_table();
24 if ( iret < 0 ) { return iret; }
28 if ( flag & flag_history )
30 iret = open_history( str_name1, str_name2 );
31 if ( iret < 0 ) { return iret; }
34 if ( ! ( flag & flag_nofmargin ) )
40 fmg_misc_king = FMG_MISC_KING;
41 fmg_cap_king = FMG_CAP_KING;
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;
49 root_turn = pmin_posi->turn_to_move;
50 HAND_B = pmin_posi->hand_black;
51 HAND_W = pmin_posi->hand_white;
62 BBIni( BB_BPRO_PAWN );
63 BBIni( BB_BPRO_LANCE );
64 BBIni( BB_BPRO_KNIGHT );
65 BBIni( BB_BPRO_SILVER );
77 BBIni( BB_WPRO_PAWN );
78 BBIni( BB_WPRO_LANCE );
79 BBIni( BB_WPRO_KNIGHT );
80 BBIni( BB_WPRO_SILVER );
84 BBIni( OCCUPIED_FILE );
85 BBIni( OCCUPIED_DIAG1 );
86 BBIni( OCCUPIED_DIAG2 );
88 for ( sq = 0; sq < nsquare; sq++ ) {
91 Xor( sq, BB_BOCCUPY );
92 XorFile( sq, OCCUPIED_FILE );
93 XorDiag1( sq, OCCUPIED_DIAG1 );
94 XorDiag2( sq, OCCUPIED_DIAG2 );
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;
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 );
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;
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 );
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 );
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;
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 );
168 MATERIAL = eval_material( ptree );
169 HASH_KEY = hash_func( ptree );
171 memset( ptree->hist_good, 0, sizeof(ptree->hist_good) );
172 memset( ptree->hist_tried, 0, sizeof(ptree->hist_tried) );
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 );
189 if ( InCheck( root_turn ) )
191 ptree->nsuc_check[1] = 1U;
192 if ( is_mate( ptree, 1 ) ) { game_status |= flag_mated; }
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);
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);
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);
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);
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);
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);
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);
249 iret = exam_tree( ptree );
252 ini_game( ptree, &min_posi_no_handicap, 0, NULL, NULL );
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 );
274 int CONV gen_legal_moves( tree_t * restrict ptree, unsigned int *p0, int flag )
279 p1 = GenCaptures( root_turn, p0 );
280 p1 = GenNoCaptures( root_turn, p1 );
283 p1 = GenCapNoProEx2( root_turn, p1 );
284 p1 = GenNoCapNoProEx2( root_turn, p1 );
286 p1 = GenDrop( root_turn, p1 );
287 n = (int)( p1 - p0 );
289 for ( i = 0; i < n; i++ )
291 MakeMove( root_turn, p0[i], 1 );
292 if ( InCheck( root_turn ) )
294 UnMakeMove( root_turn, p0[i], 1 );
298 if ( InCheck(Flip(root_turn)) )
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 ) )
305 UnMakeMove( root_turn, p0[i], 1 );
310 UnMakeMove( root_turn, p0[i], 1 );
313 for ( i = 0; i < n; )
317 for ( j = i+1; j < n; j++ ) { p0[j-1] = p0[j]; }
328 - detection of perpetual check is omitted.
329 - weak moves are omitted.
332 is_mate( tree_t * restrict ptree, int ply )
336 assert( InCheck(root_turn) );
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; }
346 is_hand_eq_supe( unsigned int u, unsigned int uref )
349 /* aggressive superior correspondences are applied, that is:
350 * pawn <= lance, silver, gold, rook
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; }
361 nsupe = (int)I2HandRook(u) - (int)I2HandRook(uref);
362 nsupe += (int)I2HandLance(u) - (int)I2HandLance(uref);
363 if ( nsupe < 0 ) { return 0; }
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; }
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; }
385 /* weak moves are omitted. */
387 detect_repetition( tree_t * restrict ptree, int ply, int turn, int nth )
389 const unsigned int *p;
390 unsigned int hand1, hand2;
391 int n, i, imin, counter, irep, ncheck;
393 ncheck = (int)ptree->nsuc_check[ply];
394 n = ptree->nrep + ply - 1;
396 /*if ( ncheck >= 6 )*/
397 if ( ncheck >= nth * 2 )
399 /* imin = n - ncheck*2; */
400 imin = n - ncheck*2 + 1;
401 if ( imin < 0 ) { imin = 0; }
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++ )
406 MakeMove( turn, *p, ply );
408 /* for ( i = n-1, counter = 0; i >= imin; i -= 2 ) */
409 for ( i = n-3, counter = 0; i >= imin; i -= 2 )
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 )*/
416 UnMakeMove( turn, *p, ply );
417 move_evasion_pchk = *p;
418 return perpetual_check;
421 UnMakeMove( turn, *p, ply );
426 for ( i = n-4, counter = 0; i >= 0; i-- )
428 if ( ptree->rep_board_list[i] == HASH_KEY )
431 hand2 = ptree->rep_hand_list[i];
435 if ( irep == no_rep )
439 if ( is_hand_eq_supe( hand2, hand1 ) )
441 irep = white_superi_rep;
444 else if ( is_hand_eq_supe( hand1, hand2 ) )
446 irep = black_superi_rep;
450 else if ( hand1 == hand2 )
452 if ( ++counter == nth )
454 if ( (ncheck-1)*2 >= n - i ) { return perpetual_check; }
455 else { return four_fold_rep; }
458 else if ( irep == no_rep )
460 if ( is_hand_eq_supe( hand1, hand2 ) )
462 irep = black_superi_rep;
464 else if ( is_hand_eq_supe( hand2, hand1 ) )
466 irep = white_superi_rep;
477 com_turn_start( tree_t * restrict ptree, int flag )
479 const char *str_move;
480 unsigned int move, sec_total;
481 int iret, is_resign, value;
483 if ( ! ( flag & flag_from_ponder ) )
485 assert( ! ( game_status & mask_game_end ) );
487 time_start = time_turn_start;
489 game_status |= flag_thinking;
490 iret = iterate( ptree );
491 game_status &= ~flag_thinking;
492 if ( iret < 0 ) { return iret; }
494 if ( game_status & flag_suspend ) { return 1; }
497 value = root_turn ? -last_root_value : last_root_value;
499 if ( value < -resign_threshold && last_pv.type != pv_fail_high )
503 else { is_resign = 0; }
505 #if defined(DBG_EASY)
506 if ( easy_move && easy_move != move )
508 out_warning( "EASY MOVE DITECTION FAILED." );
512 /* send urgent outputs */
516 if ( sckt_csa != SCKT_NULL )
518 iret = sckt_out( sckt_csa, "%%TORYO\n" );
519 if ( iret < 0 ) { return iret; }
522 OutCsaShogi( "resign\n" );
526 if ( usi_mode != usi_off )
529 csa2usi( ptree, str_CSA_move(move), buf );
530 USIOut( "bestmove %s\n", buf );
534 OutCsaShogi( "move%s\n", str_CSA_move( move ) );
537 if ( sckt_csa != SCKT_NULL ) {
539 if ( game_status & flag_sendpv ) {
543 byte = snprintf( buf, 256, "%c%s,\'* %d",
544 ach_turn[root_turn], str_CSA_move( move ),
548 for( i = 2; i <= last_pv.length && i < 5; i++ )
551 byte += snprintf( buf+byte, 256-byte, " %c%s",
552 ach_turn[turn], str_CSA_move(last_pv.a[i]) );
555 iret = sckt_out( sckt_csa, "%s\n", buf );
556 if ( iret < 0 ) { return iret; }
560 iret = sckt_out( sckt_csa, "%c%s\n", ach_turn[root_turn],
561 str_CSA_move( move ) );
562 if ( iret < 0 ) { return iret; }
569 /* show search result and make a move */
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;
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 );
588 OutCsaShogi( "info tt %03u:%02u\n", sec_total / 60U, sec_total % 60U );
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 ? "+" : "="));
603 Out( "%s '(%d%s) %03u:%02u/%03u:%02u elapsed: b%u, w%u\n",
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 );
612 #if ! defined(NO_STDOUT)
613 iret = out_board( ptree, stdout, move, 0 );
614 if ( iret < 0 ) { return iret; }
622 int CONV mnj_reset_tbl( int sd, unsigned int seed )
624 double average, deviation, d;
628 if ( sd <= 0 ) { return load_fv(); }
630 if ( load_fv() < 0 ) { return -1; }
631 if ( clear_trans_table() < 0 ) { return -1; }
639 for( i = 0; i < nsquare * pos_n; i++ )
643 for ( j = 0; j < 12; j++ ) { d += (double)rand32() / (double)UINT_MAX; }
647 pc_on_sq[0][i] = (short)( (int)pc_on_sq[0][i] + (int)d );
650 for( i = 0; i < nsquare * nsquare * kkp_end; i++ )
654 for ( j = 0; j < 12; j++ ) { d += (double)rand32() / (double)UINT_MAX; }
658 kkp[0][0][i] = (short)( (int)kkp[0][0][i] + (int)d );
661 average /= (double)( nsquare * pos_n + nsquare * nsquare * kkp_end );
662 deviation /= (double)( nsquare * pos_n + nsquare * nsquare * kkp_end );
663 deviation = sqrt( deviation );
665 if ( get_elapsed( &u ) < 0 ) { return -1; }
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 );
677 void * CONV memory_alloc( size_t nbytes )
680 void *p = VirtualAlloc( NULL, nbytes, MEM_COMMIT, PAGE_READWRITE );
681 if ( p == NULL ) { str_error = "VirturlAlloc() faild"; }
683 void *p = malloc( nbytes );
684 if ( p == NULL ) { str_error = "malloc() faild"; }
690 int CONV memory_free( void *p )
693 if ( VirtualFree( p, 0, MEM_RELEASE ) ) { return 1; }
694 str_error = "VirtualFree() faild";