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 ( flag & flag_history )
20 iret = open_history( str_name1, str_name2 );
21 if ( iret < 0 ) { return iret; }
24 if ( ! ( flag & flag_nofmargin ) )
30 fmg_misc_king = FMG_MISC_KING;
31 fmg_cap_king = FMG_CAP_KING;
34 memcpy( ptree->posi.asquare, pmin_posi->asquare, nsquare );
35 ptree->move_last[0] = ptree->amove;
36 ptree->nsuc_check[0] = 0;
37 ptree->nsuc_check[1] = 0;
39 root_turn = pmin_posi->turn_to_move;
40 HAND_B = pmin_posi->hand_black;
41 HAND_W = pmin_posi->hand_white;
52 BBIni( BB_BPRO_PAWN );
53 BBIni( BB_BPRO_LANCE );
54 BBIni( BB_BPRO_KNIGHT );
55 BBIni( BB_BPRO_SILVER );
67 BBIni( BB_WPRO_PAWN );
68 BBIni( BB_WPRO_LANCE );
69 BBIni( BB_WPRO_KNIGHT );
70 BBIni( BB_WPRO_SILVER );
74 BBIni( OCCUPIED_FILE );
75 BBIni( OCCUPIED_DIAG1 );
76 BBIni( OCCUPIED_DIAG2 );
78 for ( sq = 0; sq < nsquare; sq++ ) {
81 Xor( sq, BB_BOCCUPY );
82 XorFile( sq, OCCUPIED_FILE );
83 XorDiag1( sq, OCCUPIED_DIAG1 );
84 XorDiag2( sq, OCCUPIED_DIAG2 );
87 case pawn: Xor( sq, BB_BPAWN ); break;
88 case lance: Xor( sq, BB_BLANCE ); break;
89 case knight: Xor( sq, BB_BKNIGHT ); break;
90 case silver: Xor( sq, BB_BSILVER ); break;
91 case rook: Xor( sq, BB_BROOK ); break;
92 case bishop: Xor( sq, BB_BBISHOP ); break;
93 case king: SQ_BKING = (char)sq; break;
94 case dragon: Xor( sq, BB_BDRAGON ); break;
95 case horse: Xor( sq, BB_BHORSE ); break;
96 case gold: Xor( sq, BB_BGOLD ); break;
97 case pro_pawn: Xor( sq, BB_BPRO_PAWN ); break;
98 case pro_lance: Xor( sq, BB_BPRO_LANCE ); break;
99 case pro_knight: Xor( sq, BB_BPRO_KNIGHT ); break;
100 case pro_silver: Xor( sq, BB_BPRO_SILVER ); break;
103 else if ( piece < 0 ) {
104 Xor( sq, BB_WOCCUPY );
105 XorFile( sq, OCCUPIED_FILE );
106 XorDiag1( sq, OCCUPIED_DIAG1 );
107 XorDiag2( sq, OCCUPIED_DIAG2 );
110 case pawn: Xor( sq, BB_WPAWN ); break;
111 case lance: Xor( sq, BB_WLANCE ); break;
112 case knight: Xor( sq, BB_WKNIGHT ); break;
113 case silver: Xor( sq, BB_WSILVER ); break;
114 case rook: Xor( sq, BB_WROOK ); break;
115 case bishop: Xor( sq, BB_WBISHOP ); break;
116 case king: SQ_WKING = (char)sq; break;
117 case dragon: Xor( sq, BB_WDRAGON ); break;
118 case horse: Xor( sq, BB_WHORSE ); break;
119 case gold: Xor( sq, BB_WGOLD ); break;
120 case pro_pawn: Xor( sq, BB_WPRO_PAWN ); break;
121 case pro_lance: Xor( sq, BB_WPRO_LANCE ); break;
122 case pro_knight: Xor( sq, BB_WPRO_KNIGHT ); break;
123 case pro_silver: Xor( sq, BB_WPRO_SILVER ); break;
128 BBOr( BB_BTGOLD, BB_BPRO_PAWN, BB_BGOLD );
129 BBOr( BB_BTGOLD, BB_BPRO_LANCE, BB_BTGOLD );
130 BBOr( BB_BTGOLD, BB_BPRO_KNIGHT, BB_BTGOLD );
131 BBOr( BB_BTGOLD, BB_BPRO_SILVER, BB_BTGOLD );
132 BBOr( BB_B_HDK, BB_BHORSE, BB_BDRAGON );
133 BBOr( BB_B_HDK, BB_BKING, BB_B_HDK );
134 BBOr( BB_B_BH, BB_BBISHOP, BB_BHORSE );
135 BBOr( BB_B_RD, BB_BROOK, BB_BDRAGON );
137 BBOr( BB_WTGOLD, BB_WPRO_PAWN, BB_WGOLD );
138 BBOr( BB_WTGOLD, BB_WPRO_LANCE, BB_WTGOLD );
139 BBOr( BB_WTGOLD, BB_WPRO_KNIGHT, BB_WTGOLD );
140 BBOr( BB_WTGOLD, BB_WPRO_SILVER, BB_WTGOLD );
141 BBOr( BB_W_HDK, BB_WHORSE, BB_WDRAGON );
142 BBOr( BB_W_HDK, BB_WKING, BB_W_HDK );
143 BBOr( BB_W_BH, BB_WBISHOP, BB_WHORSE );
144 BBOr( BB_W_RD, BB_WROOK, BB_WDRAGON );
146 BB_BPAWN_ATK.p[0] = ( BB_BPAWN.p[0] << 9 ) & 0x7ffffffU;
147 BB_BPAWN_ATK.p[0] |= ( BB_BPAWN.p[1] >> 18 ) & 0x00001ffU;
148 BB_BPAWN_ATK.p[1] = ( BB_BPAWN.p[1] << 9 ) & 0x7ffffffU;
149 BB_BPAWN_ATK.p[1] |= ( BB_BPAWN.p[2] >> 18 ) & 0x00001ffU;
150 BB_BPAWN_ATK.p[2] = ( BB_BPAWN.p[2] << 9 ) & 0x7ffffffU;
152 BB_WPAWN_ATK.p[2] = ( BB_WPAWN.p[2] >> 9 );
153 BB_WPAWN_ATK.p[2] |= ( BB_WPAWN.p[1] << 18 ) & 0x7fc0000U;
154 BB_WPAWN_ATK.p[1] = ( BB_WPAWN.p[1] >> 9 );
155 BB_WPAWN_ATK.p[1] |= ( BB_WPAWN.p[0] << 18 ) & 0x7fc0000U;
156 BB_WPAWN_ATK.p[0] = ( BB_WPAWN.p[0] >> 9 );
158 MATERIAL = eval_material( ptree );
159 HASH_KEY = hash_func( ptree );
161 memset( ptree->hist_good, 0, sizeof(ptree->hist_good) );
162 memset( ptree->hist_tried, 0, sizeof(ptree->hist_tried) );
163 memset( hash_rejections_parent, 0, sizeof(hash_rejections_parent) );
164 memset( hash_rejections, 0, sizeof(hash_rejections) );
166 game_status &= ( flag_quiet | flag_reverse | flag_narrow_book
167 | flag_time_extendable | flag_learning
168 | flag_nobeep | flag_nostress | flag_nopeek
169 | flag_noponder | flag_noprompt );
181 if ( InCheck( root_turn ) )
183 ptree->nsuc_check[1] = 1U;
184 if ( is_mate( ptree, 1 ) ) { game_status |= flag_mated; }
187 BBOr( bb, BB_BPAWN, BB_WPAWN );
188 BBOr( bb, bb, BB_BPRO_PAWN );
189 BBOr( bb, bb, BB_WPRO_PAWN );
190 npawn_box = npawn_max;
191 npawn_box -= PopuCount( bb );
192 npawn_box -= (int)I2HandPawn(HAND_B);
193 npawn_box -= (int)I2HandPawn(HAND_W);
195 BBOr( bb, BB_BLANCE, BB_WLANCE );
196 BBOr( bb, bb, BB_BPRO_LANCE );
197 BBOr( bb, bb, BB_WPRO_LANCE );
198 nlance_box = nlance_max;
199 nlance_box -= PopuCount( bb );
200 nlance_box -= (int)I2HandLance(HAND_B);
201 nlance_box -= (int)I2HandLance(HAND_W);
203 BBOr( bb, BB_BKNIGHT, BB_WKNIGHT );
204 BBOr( bb, bb, BB_BPRO_KNIGHT );
205 BBOr( bb, bb, BB_WPRO_KNIGHT );
206 nknight_box = nknight_max;
207 nknight_box -= PopuCount( bb );
208 nknight_box -= (int)I2HandKnight(HAND_B);
209 nknight_box -= (int)I2HandKnight(HAND_W);
211 BBOr( bb, BB_BSILVER, BB_WSILVER );
212 BBOr( bb, bb, BB_BPRO_SILVER );
213 BBOr( bb, bb, BB_WPRO_SILVER );
214 nsilver_box = nsilver_max;
215 nsilver_box -= PopuCount( bb );
216 nsilver_box -= (int)I2HandSilver(HAND_B);
217 nsilver_box -= (int)I2HandSilver(HAND_W);
219 BBOr( bb, BB_BGOLD, BB_WGOLD );
220 ngold_box = ngold_max;
221 ngold_box -= PopuCount( bb );
222 ngold_box -= (int)I2HandGold(HAND_B);
223 ngold_box -= (int)I2HandGold(HAND_W);
225 BBOr( bb, BB_BBISHOP, BB_WBISHOP );
226 BBOr( bb, bb, BB_BHORSE );
227 BBOr( bb, bb, BB_WHORSE );
228 nbishop_box = nbishop_max;
229 nbishop_box -= PopuCount( bb );
230 nbishop_box -= (int)I2HandBishop(HAND_B);
231 nbishop_box -= (int)I2HandBishop(HAND_W);
233 BBOr( bb, BB_BROOK, BB_WROOK );
234 BBOr( bb, bb, BB_BDRAGON );
235 BBOr( bb, bb, BB_WDRAGON );
236 nrook_box = nrook_max;
237 nrook_box -= PopuCount( bb );
238 nrook_box -= (int)I2HandRook(HAND_B);
239 nrook_box -= (int)I2HandRook(HAND_W);
241 iret = exam_tree( ptree );
244 ini_game( ptree, &min_posi_no_handicap, 0, NULL, NULL );
253 gen_legal_moves( tree_t * restrict ptree, unsigned int *p0 )
258 p1 = GenCaptures( root_turn, p0 );
259 p1 = GenNoCaptures( root_turn, p1 );
260 p1 = GenCapNoProEx2( root_turn, p1 );
261 p1 = GenNoCapNoProEx2( root_turn, p1 );
262 p1 = GenDrop( root_turn, p1 );
263 n = (int)( p1 - p0 );
265 for ( i = 0; i < n; i++ )
267 MakeMove( root_turn, p0[i], 1 );
268 if ( InCheck( root_turn ) )
270 UnMakeMove( root_turn, p0[i], 1 );
274 if ( InCheck(Flip(root_turn)) )
276 ptree->nsuc_check[2] = (unsigned char)( ptree->nsuc_check[0] + 1U );
277 if ( ptree->nsuc_check[2] >= 6U
278 && ( detect_repetition( ptree, 2, Flip(root_turn), 3 )
279 == perpetual_check ) )
281 UnMakeMove( root_turn, p0[i], 1 );
286 UnMakeMove( root_turn, p0[i], 1 );
289 for ( i = 0; i < n; )
293 for ( j = i+1; j < n; j++ ) { p0[j-1] = p0[j]; }
304 - detection of perpetual check is omitted.
305 - weak moves are omitted.
308 is_mate( tree_t * restrict ptree, int ply )
312 assert( InCheck(root_turn) );
314 ptree->move_last[ply] = GenEvasion( root_turn, ptree->move_last[ply-1] );
315 if ( ptree->move_last[ply] == ptree->move_last[ply-1] ) { iret = 1; }
322 is_hand_eq_supe( unsigned int u, unsigned int uref )
325 /* aggressive superior correspondences are applied, that is:
326 * pawn <= lance, silver, gold, rook
331 if ( IsHandKnight(u) < IsHandKnight(uref)
332 || IsHandSilver(u) < IsHandSilver(uref)
333 || IsHandGold(u) < IsHandGold(uref)
334 || IsHandBishop(u) < IsHandBishop(uref)
335 || IsHandRook(u) < IsHandRook(uref) ) { return 0; }
337 nsupe = (int)I2HandRook(u) - (int)I2HandRook(uref);
338 nsupe += (int)I2HandLance(u) - (int)I2HandLance(uref);
339 if ( nsupe < 0 ) { return 0; }
341 nsupe += (int)I2HandSilver(u) - (int)I2HandSilver(uref);
342 nsupe += (int)I2HandGold(u) - (int)I2HandGold(uref);
343 nsupe += (int)I2HandPawn(u) - (int)I2HandPawn(uref);
344 if ( nsupe < 0 ) { return 0; }
348 if ( IsHandPawn(u) >= IsHandPawn(uref)
349 && IsHandLance(u) >= IsHandLance(uref)
350 && IsHandKnight(u) >= IsHandKnight(uref)
351 && IsHandSilver(u) >= IsHandSilver(uref)
352 && IsHandGold(u) >= IsHandGold(uref)
353 && IsHandBishop(u) >= IsHandBishop(uref)
354 && IsHandRook(u) >= IsHandRook(uref) ) { return 1; }
361 /* weak moves are omitted. */
363 detect_repetition( tree_t * restrict ptree, int ply, int turn, int nth )
365 const unsigned int *p;
366 unsigned int hand1, hand2;
367 int n, i, imin, counter, irep, ncheck;
369 ncheck = (int)ptree->nsuc_check[ply];
370 n = root_nrep + ply - 1;
372 /*if ( ncheck >= 6 )*/
373 if ( ncheck >= nth * 2 )
375 /* imin = n - ncheck*2; */
376 imin = n - ncheck*2 + 1;
377 if ( imin < 0 ) { imin = 0; }
379 ptree->move_last[ply] = GenEvasion( turn, ptree->move_last[ply-1] );
380 for ( p = ptree->move_last[ply-1]; p < ptree->move_last[ply]; p++ )
382 MakeMove( turn, *p, ply );
384 /* for ( i = n-1, counter = 0; i >= imin; i -= 2 ) */
385 for ( i = n-3, counter = 0; i >= imin; i -= 2 )
387 if ( ptree->rep_board_list[i] == HASH_KEY
388 && ptree->rep_hand_list[i] == HAND_B
389 && ++counter == nth )
390 /* && ncheck*2 - 1 >= n - i )*/
392 UnMakeMove( turn, *p, ply );
393 move_evasion_pchk = *p;
394 return perpetual_check;
397 UnMakeMove( turn, *p, ply );
402 for ( i = n-4, counter = 0; i >= 0; i-- )
404 if ( ptree->rep_board_list[i] == HASH_KEY )
407 hand2 = ptree->rep_hand_list[i];
411 if ( irep == no_rep )
415 if ( is_hand_eq_supe( hand2, hand1 ) )
417 irep = white_superi_rep;
420 else if ( is_hand_eq_supe( hand1, hand2 ) )
422 irep = black_superi_rep;
426 else if ( hand1 == hand2 )
428 if ( ++counter == nth )
430 if ( (ncheck-1)*2 >= n - i ) { return perpetual_check; }
431 else { return four_fold_rep; }
434 else if ( irep == no_rep )
436 if ( is_hand_eq_supe( hand1, hand2 ) )
438 irep = black_superi_rep;
440 else if ( is_hand_eq_supe( hand2, hand1 ) )
442 irep = white_superi_rep;
453 com_turn_start( tree_t * restrict ptree, int flag )
455 const char *str_move;
456 unsigned int move, sec_total;
457 int iret, is_resign, value, ply;
459 if ( ! ( flag & flag_from_ponder ) )
461 assert( ! ( game_status & mask_game_end ) );
463 time_start = time_turn_start;
465 game_status |= flag_thinking;
466 iret = iterate( ptree, flag );
467 game_status &= ~flag_thinking;
468 if ( iret < 0 ) { return iret; }
470 if ( game_status & flag_suspend ) { return 1; }
473 value = root_turn ? -last_root_value : last_root_value;
474 str_move = str_CSA_move( move );
476 if ( value < -resign_threshold && last_pv.type != pv_fail_high )
478 #if defined(DEKUNOBOU)
482 Out( "Bonanza lost against Dekunobou\n" );
490 #if defined(DEKUNOBOU)
491 if ( dek_ngame && ! is_resign
492 && value > ( MT_CAP_DRAGON * 3 ) / 2
493 && value > resign_threshold
494 && value != score_inferior )
498 Out( "Bonanza won against Dekunobou.\n" );
500 if ( dek_ngame && ! is_resign && value == -score_draw )
502 iret = make_move_root( ptree, move, ( flag_rep | flag_nomake_move ) );
505 Out( "%s\n\n", str_move );
508 else if ( iret == 2 )
511 Out( "The game with Dekunobou is drawn.\n" );
514 if ( dek_ngame && ! is_resign && record_game.moves > 255 )
517 Out( "The game with Dekunobou is interrupted...\n" );
522 #if defined(DBG_EASY)
523 if ( easy_move && easy_move != move )
525 out_warning( "EASY MOVE DITECTION FAILED." );
529 /* send urgent outputs */
533 if ( sckt_csa != SCKT_NULL )
535 iret = sckt_out( sckt_csa, "%%TORYO\n" );
536 if ( iret < 0 ) { return iret; }
539 OutCsaShogi( "resign\n" );
540 OutDek( "%%TORYO\n" );
544 if ( sckt_csa != SCKT_NULL )
546 iret = sckt_out( sckt_csa, "%c%s\n", ach_turn[root_turn], str_move );
547 if ( iret < 0 ) { return iret; }
551 OutCsaShogi( "move%s\n", str_move );
552 OutDek( "%c%s\n", ach_turn[root_turn], str_move );
556 /* learning and stuff */;
557 ply = record_game.moves;
558 if ( ply < HASH_REG_HIST_LEN )
560 history_book_learn[ply].data &= ~( (1U<<31) | 0xffffU );
561 history_book_learn[ply].data |= (unsigned int)(value+32768);
562 history_book_learn[ply].move_responsible = move;
563 history_book_learn[ply].key_responsible = (unsigned int)HASH_KEY;
564 history_book_learn[ply].hand_responsible = (unsigned int)HAND_B;
567 iret = hash_learn( ptree, move, value, iteration_depth - 1 );
568 if ( iret < 0 ) { return iret; }
570 /* show search result and make a move */
574 game_status |= flag_resigned;
575 renovate_time( root_turn );
576 out_CSA( ptree, &record_game, MOVE_RESIGN );
577 sec_total = root_turn ? sec_w_total : sec_b_total;
582 iret = make_move_root( ptree, move,
583 ( flag_rep | flag_time | flag_history
584 | flag_rejections ) );
587 Out( "%s\n\n", str_move );
590 sec_total = root_turn ? sec_b_total : sec_w_total;
593 OutCsaShogi( "info tt %03u:%02u\n", sec_total / 60U, sec_total % 60U );
594 Out( "%s '(%d%s) %03u:%02u/%03u:%02u elapsed: b%u, w%u\n",
596 ( last_pv.type == pv_fail_high ) ? "!" : "",
597 sec_elapsed / 60U, sec_elapsed % 60U,
598 sec_total / 60U, sec_total % 60U,
599 sec_b_total, sec_w_total );
603 #if ! defined(NO_STDOUT)
604 iret = out_board( ptree, stdout, move, 0 );
605 if ( iret < 0 ) { return iret; }
614 int mnj_reset_tbl( int sd, unsigned int seed )
616 double average, deviation, d;
620 if ( clear_trans_table() < 0 ) { return -1; }
625 for ( i = 0; i < MNJ_MASK + 1; i++ ) { mnj_tbl[i] = 0; }
631 for( i = 0; i < MNJ_MASK + 1; i++ )
635 for ( j = 0; j < 12; j++ ) { d += (double)rand32() / (double)UINT_MAX; }
636 mnj_tbl[i] = (short)( (double)sd * d );
640 for ( i = 0; i < MNJ_MASK + 1; i++ ) { average += (double)mnj_tbl[i]; }
641 average /= (double)( MNJ_MASK + 1 );
644 for ( i = 0; i < MNJ_MASK + 1; i++ )
646 d = (double)mnj_tbl[i] - average;
649 deviation = sqrt( deviation / (double)( MNJ_MASK + 1 ) );
651 if ( get_elapsed( &u ) < 0 ) { return -1; }
654 Out( "\nThe normal distribution N(0,sd^2) is generated.\n" );
655 Out( " actual average: % .3f\n", average );
656 Out( " actual standard deviation: % .3f\n", deviation );
657 Out( "rand seed = %x\n", u );
665 memory_alloc( size_t nbytes )
668 void *p = VirtualAlloc( NULL, nbytes, MEM_COMMIT, PAGE_READWRITE );
669 if ( p == NULL ) { str_error = "VirturlAlloc() faild"; }
671 void *p = malloc( nbytes );
672 if ( p == NULL ) { str_error = "malloc() faild"; }
679 memory_free( void *p )
682 if ( VirtualFree( p, 0, MEM_RELEASE ) ) { return 1; }
683 str_error = "VirtualFree() faild";