7 static int eval_supe( unsigned int hand_current, unsigned int hand_hash,
8 int turn_current, int turn_hash,
9 int * restrict pvalue_hash, int * restrict ptype_hash );
12 ini_trans_table( void )
15 unsigned int ntrans_table;
17 ntrans_table = 1U << log2_ntrans_table;
18 size = sizeof( trans_table_t ) * ntrans_table + 15U;
19 ptrans_table_orig = memory_alloc( size );
20 if ( ptrans_table_orig == NULL ) { return -1; }
21 ptrans_table = (trans_table_t *)( ((ptrdiff_t)ptrans_table_orig+15)
23 hash_mask = ntrans_table - 1;
24 Out( "Trans. Table Entries = %dK (%dMB)\n",
25 ( ntrans_table * 3U ) / 1024U, size / (1024U * 1024U ) );
27 return clear_trans_table();
31 #define Foo( PIECE, piece ) bb = BB_B ## PIECE; \
32 while( BBToU(bb) ) { \
33 sq = FirstOne( bb ); \
35 key ^= ( b_ ## piece ## _rand )[sq]; \
38 while( BBToU(bb) ) { \
39 sq = FirstOne( bb ); \
41 key ^= ( w_ ## piece ## _rand )[sq]; \
45 hash_func( const tree_t * restrict ptree )
51 key ^= b_king_rand[SQ_BKING];
52 key ^= w_king_rand[SQ_WKING];
56 Foo( KNIGHT, knight );
57 Foo( SILVER, silver );
59 Foo( BISHOP, bishop );
61 Foo( PRO_PAWN, pro_pawn );
62 Foo( PRO_LANCE, pro_lance );
63 Foo( PRO_KNIGHT, pro_knight );
64 Foo( PRO_SILVER, pro_silver );
66 Foo( DRAGON, dragon );
88 hash_store( const tree_t * restrict ptree, int ply, int depth, int turn,
89 int value_type, int value, unsigned int move,
90 unsigned int state_node )
92 uint64_t word1, word2, hash_word1, hash_word2;
93 unsigned int index, slot;
94 int depth_hash, age_hash;
96 #if ! defined(MINIMUM)
97 if ( game_status & flag_learning ) { return; }
99 assert( depth <= 0xff );
101 if ( depth < 0 ) { depth = 0; }
102 if ( abs(value) > score_max_eval )
104 if ( abs(value) > score_mate1ply ) { return; }
105 if ( value > 0 ) { value += ply-1; }
106 else { value -= ply-1; }
107 #if ! defined(MINIMUM)
108 if ( abs(value) > score_mate1ply )
110 out_warning( "A stored hash value is out of bounce!" );
114 word2 = ( ( HASH_KEY & ~(uint64_t)0x7fU )
115 | (uint64_t)( (turn<<6) | ( state_node & node_mate_threat )
116 | (value_type<<3) | trans_table_age ) );
117 word1 = ( ( (uint64_t)( depth<<16 | (value+32768) ) << 40 )
118 | ( (uint64_t)( move & 0x7ffffU ) << 21 )
121 index = (unsigned int)HASH_KEY & hash_mask;
122 hash_word1 = ptrans_table[index].prefer.word1;
123 hash_word2 = ptrans_table[index].prefer.word2;
124 SignKey( hash_word2, hash_word1 );
125 age_hash = (int)((unsigned int)(hash_word2 ) & 0x07U);
126 depth_hash = (int)((unsigned int)(hash_word1>>56) & 0xffU);
128 SignKey( word2, word1 );
130 if ( age_hash != trans_table_age || depth_hash <= depth )
132 ptrans_table[index].prefer.word1 = word1;
133 ptrans_table[index].prefer.word2 = word2;
136 slot = (unsigned int)HASH_KEY >> 31;
137 ptrans_table[index].always[slot].word1 = word1;
138 ptrans_table[index].always[slot].word2 = word2;
144 hash_store_pv( const tree_t * restrict ptree, unsigned int move, int turn )
146 uint64_t key_turn_pv, word1, word2;
149 key_turn_pv = ( HASH_KEY & ~(uint64_t)0x7fU ) | (unsigned int)( turn << 6 );
150 index = (unsigned int)HASH_KEY & hash_mask;
152 word1 = ptrans_table[index].prefer.word1;
153 word2 = ptrans_table[index].prefer.word2;
154 SignKey( word2, word1 );
156 if ( ( (unsigned int)word1 & 0x1fffffU ) == HAND_B
157 && ( word2 & ~(uint64_t)0x3fU ) == key_turn_pv )
159 if ( ( (unsigned int)(word1>>21) & 0x7ffffU ) != ( move & 0x7ffffU ) )
161 word1 &= ~((uint64_t)0x7ffffU << 21);
162 word1 |= (uint64_t)( move & 0x7ffffU ) << 21;
163 word2 &= ~((uint64_t)0x3U << 3);
164 SignKey( word2, word1 );
165 ptrans_table[index].prefer.word1 = word1;
166 ptrans_table[index].prefer.word2 = word2;
172 slot = (unsigned int)HASH_KEY >> 31;
173 word1 = ptrans_table[index].always[slot].word1;
174 word2 = ptrans_table[index].always[slot].word2;
175 SignKey( word2, word1 );
176 if ( ( (unsigned int)word1 & 0x1fffffU ) == HAND_B
177 && ( word2 & ~(uint64_t)0x3fU ) == key_turn_pv )
179 if ( ( (unsigned int)(word1>>21) & 0x7ffffU )
180 != ( move & 0x7ffffU ) )
182 word1 &= ~((uint64_t)0x7ffffU << 21);
183 word1 |= (uint64_t)( move & 0x7ffffU ) << 21;
184 word2 &= ~((uint64_t)0x3U << 3);
185 SignKey( word2, word1 );
186 ptrans_table[index].always[slot].word1 = word1;
187 ptrans_table[index].always[slot].word2 = word2;
191 word1 = (uint64_t)32768U << 40;
192 word1 |= (uint64_t)( move & 0x7ffffU ) << 21;
194 word2 = key_turn_pv | trans_table_age;
195 SignKey( word2, word1 );
196 ptrans_table[index].prefer.word1 = word1;
197 ptrans_table[index].prefer.word2 = word2;
204 hash_learn_store( const tree_t * restrict ptree, int depth, int value,
209 assert( 0 <= depth && depth <= 0xff );
211 ret.word2 = ( (HASH_KEY&(~(uint64_t)0x7fU))
212 | (uint64_t)( (root_turn<<6)
213 | (value_exact<<3) | trans_table_age ) );
214 ret.word1 = ( ( (uint64_t)( depth<<16 | (value+32768) ) << 40 )
215 | ( (uint64_t)( move & 0x7ffffU ) << 21 )
223 all_hash_learn_store( void )
226 unsigned int u32key, unext, u, index;
228 if ( pf_hash == NULL ) { return 0; }
230 if ( fseek( pf_hash, sizeof(unsigned int), SEEK_SET ) == EOF
231 || fread( &unext, sizeof(unsigned int), 1, pf_hash ) != 1 )
233 str_error = str_io_error;
236 if ( ++unext == 0x10000U ) { unext = 0x1U; }
237 if ( fseek( pf_hash, (long)( 20U * unext ), SEEK_SET ) == EOF )
239 str_error = str_io_error;
244 if ( fread( &u32key, sizeof(unsigned int), 1, pf_hash ) != 1
245 || fread( aword, sizeof(uint64_t), 2, pf_hash ) != 2 )
247 str_error = str_io_error;
250 index = u32key & hash_mask;
251 aword[1] |= (uint64_t)trans_table_age;
252 SignKey( aword[1], aword[0] );
253 ptrans_table[index].prefer.word1 = aword[0];
254 ptrans_table[index].prefer.word2 = aword[1];
255 if ( u == 0xfffeU ) { break; }
256 if ( ++unext == 0x10000U )
259 if ( fseek( pf_hash, 20, SEEK_SET ) == EOF )
261 str_error = str_io_error;
272 hash_probe( tree_t * restrict ptree, int ply, int depth_current,
273 int turn_current, int alpha, int beta, unsigned int state_node )
275 uint64_t word1, word2, key_current, key_hash;
276 unsigned int hand_hash, move_hash, move_infe, move_supe, slot, utemp;
277 unsigned int state_node_hash, index;
278 int null_depth, value_hash, ifrom;
279 int turn_hash, depth_hash, type_hash, is_superior;
281 ptree->ntrans_probe++;
285 if ( depth_current < 0 ) { depth_current = 0; }
286 null_depth = NullDepth( depth_current );
287 if ( null_depth < PLY_INC ) { null_depth = 0; }
289 key_current = HASH_KEY & ~(uint64_t)0x7fU;
291 index = (unsigned int)HASH_KEY & hash_mask;
292 word1 = ptrans_table[index].prefer.word1;
293 word2 = ptrans_table[index].prefer.word2;
294 SignKey( word2, word1 );
295 key_hash = word2 & ~(uint64_t)0x7fU;
297 if ( key_hash == key_current ) {
299 ptree->ntrans_prefer_hit++;
301 depth_hash = (int)((unsigned int)(word1>>56) & 0x00ffU);
302 value_hash = (int)((unsigned int)(word1>>40) & 0xffffU) - 32768;
303 move_hash = (unsigned int)(word1>>21) & 0x7ffffU;
304 hand_hash = (unsigned int)word1 & 0x1fffffU;
306 utemp = (unsigned int)word2;
307 state_node_hash = utemp & node_mate_threat;
308 turn_hash = (int)((utemp>>6) & 0x1U);
309 type_hash = (int)((utemp>>3) & 0x3U);
311 if ( abs(value_hash) > score_max_eval )
313 if ( value_hash > 0 ) { value_hash -= ply-1; }
314 else { value_hash += ply-1; }
315 #if ! defined(MINIMUM)
316 if ( abs(value_hash) > score_mate1ply )
318 out_warning( "Hash value is out of bounce!!" );
325 move_hash |= turn_current ? Cap2Move( BOARD[I2To(move_hash)])
326 : Cap2Move(-BOARD[I2To(move_hash)]);
329 if ( turn_hash == turn_current && hand_hash == HAND_B ) {
331 assert( ! move_hash || is_move_valid( ptree, move_hash, turn_current ) );
332 ptree->amove_hash[ply] = move_hash;
334 if ( type_hash == value_lower
335 && value_hash >= beta
336 && ( depth_hash >= depth_current || value_hash > score_max_eval ) )
338 HASH_VALUE = value_hash;
339 ptree->ntrans_lower++;
343 if ( type_hash == value_upper
344 && value_hash <= alpha
345 && ( depth_hash >= depth_current || value_hash < -score_max_eval ) )
347 HASH_VALUE = value_hash;
348 ptree->ntrans_upper++;
352 if ( type_hash == value_exact
353 && ( depth_hash >= depth_current
354 || abs(value_hash) > score_max_eval ) )
356 HASH_VALUE = value_hash;
357 ptree->ntrans_upper++;
361 if ( ( type_hash & flag_value_low_exact )
362 && ! ptree->nsuc_check[ply]
363 && ! ptree->nsuc_check[ply-1]
364 && ( ( depth_current < 2*PLY_INC
365 && beta+EFUTIL_MG1 <= value_hash )
366 || ( depth_current < 3*PLY_INC
367 && beta+EFUTIL_MG2 <= value_hash ) ) )
370 ptree->ntrans_lower++;
374 state_node |= state_node_hash;
376 if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate; }
378 if ( ( type_hash & flag_value_up_exact )
380 && null_depth <= depth_hash )
382 state_node &= ~node_do_null;
387 is_superior = eval_supe( HAND_B, hand_hash, turn_current, turn_hash,
388 &value_hash, &type_hash );
390 if ( is_superior == 1 ) {
392 if ( turn_hash == turn_current ) { move_supe = move_hash; }
394 if ( type_hash & flag_value_low_exact )
396 if ( ! ptree->nsuc_check[ply]
397 && ! ptree->nsuc_check[ply-1]
398 && ( ( depth_current < 2*PLY_INC
399 && beta+EFUTIL_MG1 <= value_hash )
400 || ( depth_current < 3*PLY_INC
401 && beta+EFUTIL_MG2 <= value_hash ) ) )
404 ptree->ntrans_lower++;
408 if ( beta <= value_hash
409 && ( depth_current <= depth_hash
410 || score_max_eval < value_hash
411 || ( turn_current != turn_hash
412 && depth_hash >= null_depth
413 && ( state_node & node_do_null ) ) ) )
415 HASH_VALUE = value_hash;
416 ptree->ntrans_superior_hit++;
423 if ( turn_hash == turn_current ) { move_infe = move_hash; }
425 if ( is_superior == -1 ) {
427 state_node |= state_node_hash;
429 if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate; }
431 if ( type_hash & flag_value_up_exact )
433 if ( value_hash <= alpha
434 && ( depth_current <= depth_hash
435 || value_hash < -score_max_eval ) )
437 HASH_VALUE = value_hash;
438 ptree->ntrans_inferior_hit++;
441 if ( value_hash < beta && null_depth <= depth_hash )
443 state_node &= ~node_do_null;
451 slot = (unsigned int)HASH_KEY >> 31;
452 word1 = ptrans_table[index].always[slot].word1;
453 word2 = ptrans_table[index].always[slot].word2;
455 SignKey( word2, word1 );
456 key_hash = word2 & ~(uint64_t)0x7fU;
458 if ( key_hash == key_current ) {
460 ptree->ntrans_always_hit++;
462 depth_hash = (int)((unsigned int)(word1>>56) & 0x00ffU);
463 value_hash = (int)((unsigned int)(word1>>40) & 0xffffU) - 32768;
464 move_hash = (unsigned int)(word1>>21) & 0x7ffffU;
465 hand_hash = (unsigned int)word1 & 0x1fffffU;
467 utemp = (unsigned int)word2;
468 state_node_hash = utemp & node_mate_threat;
469 turn_hash = (int)((utemp>>6) & 0x1U);
470 type_hash = (int)((utemp>>3) & 0x3U);
472 if ( abs(value_hash) > score_max_eval )
474 if ( value_hash > 0 ) { value_hash -= ply-1; }
475 else { value_hash += ply-1; }
476 #if ! defined(MINIMUM)
477 if ( abs(value_hash) > score_mate1ply )
479 out_warning( "Hash value is out of bounce!!" );
486 move_hash |= turn_current ? Cap2Move( BOARD[I2To(move_hash)])
487 : Cap2Move(-BOARD[I2To(move_hash)]);
490 if ( turn_hash == turn_current && hand_hash == HAND_B ) {
492 if ( ! ptree->amove_hash[ply] )
495 || is_move_valid( ptree, move_hash, turn_current ) );
496 ptree->amove_hash[ply] = move_hash;
499 if ( type_hash == value_lower
500 && value_hash >= beta
501 && ( depth_hash >= depth_current || value_hash > score_max_eval ) )
503 HASH_VALUE = value_hash;
504 ptree->ntrans_lower++;
508 if ( type_hash == value_upper
509 && value_hash <= alpha
510 && ( depth_hash >= depth_current || value_hash < -score_max_eval ) )
512 HASH_VALUE = value_hash;
513 ptree->ntrans_upper++;
517 if ( type_hash == value_exact
518 && ( depth_hash >= depth_current
519 || abs(value_hash) > score_max_eval ) )
521 HASH_VALUE = value_hash;
522 ptree->ntrans_upper++;
527 if ( ( type_hash & flag_value_low_exact )
528 && ! ptree->nsuc_check[ply]
529 && ! ptree->nsuc_check[ply-1]
530 && ( ( depth_current < 2*PLY_INC
531 && beta+EFUTIL_MG1 <= value_hash )
532 || ( depth_current < 3*PLY_INC
533 && beta+EFUTIL_MG2 <= value_hash ) ) )
536 ptree->ntrans_lower++;
540 state_node |= state_node_hash;
542 if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate; }
544 if ( ( type_hash & flag_value_up_exact )
546 && null_depth <= depth_hash )
548 state_node &= ~node_do_null;
553 is_superior = eval_supe( HAND_B, hand_hash, turn_current, turn_hash,
554 &value_hash, &type_hash );
556 if ( is_superior == 1 ) {
558 if ( ( turn_hash == turn_current ) && ! move_supe )
560 move_supe = move_hash;
563 if ( type_hash & flag_value_low_exact )
565 if ( ! ptree->nsuc_check[ply]
566 && ! ptree->nsuc_check[ply-1]
567 && ( ( depth_current < 2*PLY_INC
568 && beta+EFUTIL_MG1 <= value_hash )
569 || ( depth_current < 3*PLY_INC
570 && beta+EFUTIL_MG2 <= value_hash ) ) )
573 ptree->ntrans_lower++;
577 if ( value_hash >= beta
578 && ( depth_hash >= depth_current
579 || score_max_eval < value_hash
580 || ( turn_current != turn_hash
581 && depth_hash >= null_depth
582 && ( state_node & node_do_null ) ) ) )
584 HASH_VALUE = value_hash;
585 ptree->ntrans_superior_hit++;
592 if ( ! move_infe && turn_hash == turn_current )
594 move_infe = move_hash;
597 if ( is_superior == -1 ) {
599 state_node |= state_node_hash;
601 if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate;}
603 if ( type_hash & flag_value_up_exact )
605 if ( value_hash <= alpha
606 && ( depth_hash >= depth_current
607 || value_hash < -score_max_eval ) )
609 HASH_VALUE = value_hash;
610 ptree->ntrans_inferior_hit++;
613 if ( value_hash < beta && null_depth <= depth_hash )
615 state_node &= ~node_do_null;
623 if ( ! ptree->amove_hash[ply] )
627 ifrom = (int)I2From(move_supe);
628 if ( ifrom >= nsquare )
630 unsigned int hand = turn_current ? HAND_W : HAND_B;
631 switch( From2Drop(ifrom) )
634 if ( ! IsHandPawn(hand) ) {
635 move_supe = To2Move(I2To(move_supe));
636 if ( IsHandLance(hand) )
638 move_supe |= Drop2Move(lance);
640 else if ( IsHandSilver(hand))
642 move_supe |= Drop2Move(silver);
644 else if ( IsHandGold(hand) )
646 move_supe |= Drop2Move(gold);
648 else { move_supe |= Drop2Move(rook); }
653 if ( ! IsHandLance(hand) )
655 move_supe = To2Move(I2To(move_supe)) | Drop2Move(rook);
661 assert( is_move_valid( ptree, move_supe, turn_current ) );
662 ptree->amove_hash[ply] = move_supe;
664 else if ( move_infe )
666 ifrom = (int)I2From(move_infe);
667 if ( ifrom >= nsquare )
669 unsigned int hand = turn_current ? HAND_W : HAND_B;
670 switch( From2Drop(ifrom) )
672 case pawn: if ( ! IsHandPawn(hand) ) { goto esc; } break;
673 case lance: if ( ! IsHandLance(hand) ) { goto esc; } break;
674 case knight: if ( ! IsHandKnight(hand) ) { goto esc; } break;
675 case silver: if ( ! IsHandSilver(hand) ) { goto esc; } break;
676 case gold: if ( ! IsHandGold(hand) ) { goto esc; } break;
677 case bishop: if ( ! IsHandBishop(hand) ) { goto esc; } break;
678 case rook: if ( ! IsHandRook(hand) ) { goto esc; } break;
681 assert( is_move_valid( ptree, move_infe, turn_current ) );
682 ptree->amove_hash[ply] = move_infe;
692 hash_learn_on( void )
694 int iret = file_close( pf_hash );
695 if ( iret < 0 ) { return iret; }
697 pf_hash = file_open( str_hash, "rb+" );
698 if ( pf_hash == NULL ) { return -2; }
705 hash_learn_off( void )
707 int iret = file_close( pf_hash );
708 if ( iret < 0 ) { return iret; }
715 #if !defined(MINIMUM)
717 hash_learn_create( void )
723 iret = hash_learn_off();
724 if ( iret < 0 ) { return iret; }
726 pf_hash = file_open( str_hash, "wb" );
727 if ( pf_hash == NULL ) { return -2; }
729 for ( i = 0; i < 5; i++ )
732 if ( fwrite( &u, sizeof(unsigned int), 1, pf_hash ) != 1 )
734 str_error = str_io_error;
740 au64[0] = au64[1] = 0;
741 for ( i = 1; i < 0x10000; i++ )
742 if ( fwrite( &u, sizeof(unsigned int), 1, pf_hash ) != 1
743 || fwrite( au64, sizeof(uint64_t), 2, pf_hash ) != 2 )
745 str_error = str_io_error;
749 return hash_learn_on();
754 hash_learn( const tree_t * restrict ptree, unsigned int move, int value,
757 trans_entry_t trans_entry;
758 unsigned int unum, unext, u;
761 ply = record_game.moves;
762 if ( ply >= HASH_REG_HIST_LEN ) { return 1; }
763 if ( pf_hash == NULL ) { return 1; }
764 if ( abs(value) > score_max_eval ) { return 1; }
765 if ( ply < 2 ) { return 1; }
766 if ( depth < 2 ) { return 1; }
768 if ( history_book_learn[ply].key_probed == (unsigned int)HASH_KEY
769 && history_book_learn[ply].hand_probed == HAND_B
770 && history_book_learn[ply].move_probed == move ) { return 1; }
772 if ( history_book_learn[ply-2].key_responsible
773 != history_book_learn[ply-2].key_played ) { return 1; }
774 if ( history_book_learn[ply-2].hand_responsible
775 != history_book_learn[ply-2].hand_played ) { return 1; }
776 if ( history_book_learn[ply-2].move_responsible
777 != history_book_learn[ply-2].move_played ) { return 1; }
779 if ( ( history_book_learn[ply-2].key_probed
780 == history_book_learn[ply-2].key_played )
781 && ( history_book_learn[ply-2].hand_probed
782 == history_book_learn[ply-2].hand_played )
783 && ( history_book_learn[ply-2].move_probed
784 == history_book_learn[ply-2].move_played ) ) { return 1; }
786 pre_value = (int)( history_book_learn[ply-2].data & 0xffffU ) - 32768;
788 if ( pre_value < value + HASH_REG_MINDIFF ) { return 1; }
789 if ( pre_value < -HASH_REG_THRESHOLD ) { return 1; }
790 if ( pre_value == score_inferior ) { return 1; }
792 Out( "save hash value of the position\n\n" );
793 if ( fseek( pf_hash, 0, SEEK_SET ) == EOF
794 || fread( &unum, sizeof(unsigned int), 1, pf_hash ) != 1
795 || fread( &unext, sizeof(unsigned int), 1, pf_hash ) != 1 )
797 str_error = str_io_error;
800 if ( ++unum == 0x10000U ) { unum = 0xffffU; }
801 if ( ++unext == 0x10000U ) { unext = 0x0001U; }
803 if ( fseek( pf_hash, 0, SEEK_SET ) == EOF
804 || fwrite( &unum, sizeof(unsigned int), 1, pf_hash ) != 1
805 || fwrite( &unext, sizeof(unsigned int), 1, pf_hash ) != 1 )
807 str_error = str_io_error;
811 = hash_learn_store( ptree, depth * PLY_INC + PLY_INC/2, value, move );
812 u = (unsigned int)HASH_KEY;
813 if ( fseek( pf_hash, (long)( 20 * unext ), SEEK_SET ) == EOF
814 || fwrite( &u, sizeof(unsigned int), 1, pf_hash ) != 1
815 || fwrite( &trans_entry.word1, sizeof(uint64_t), 1, pf_hash ) != 1
816 || fwrite( &trans_entry.word2, sizeof(uint64_t), 1, pf_hash ) != 1
817 || fflush( pf_hash ) == EOF )
819 str_error = str_io_error;
828 eval_supe( unsigned int hand_current, unsigned int hand_hash,
829 int turn_current, int turn_hash,
830 int * restrict pvalue_hash, int * restrict ptype_hash )
834 if ( hand_current == hand_hash ) { is_superior = 0; }
835 else if ( is_hand_eq_supe( hand_current, hand_hash ) )
837 is_superior = turn_current ? -1 : 1;
839 else if ( is_hand_eq_supe( hand_hash, hand_current ) )
841 is_superior = turn_current ? 1 : -1;
845 if ( turn_hash != turn_current )
847 if ( is_superior == -1 ) { is_superior = 0; }
851 switch ( *ptype_hash )
853 case value_lower: *ptype_hash=value_upper; break;
854 case value_upper: *ptype_hash=value_lower; break;
864 clear_trans_table( void )
866 unsigned int elapsed_start, elapsed_end;
869 if ( get_elapsed( &elapsed_start ) < 0 ) { return -1; }
871 Out( "cleanning the transposition table ..." );
874 ntrans_table = 1 << log2_ntrans_table;
875 for ( i = 0; i < ntrans_table; i++ )
877 ptrans_table[i].prefer.word1 = 0;
878 ptrans_table[i].prefer.word2 = 0;
879 ptrans_table[i].always[0].word1 = 0;
880 ptrans_table[i].always[0].word2 = 0;
881 ptrans_table[i].always[1].word1 = 0;
882 ptrans_table[i].always[1].word2 = 0;
885 if ( get_elapsed( &elapsed_end ) < 0 ) { return -1; }
886 Out( " done (%ss)\n", str_time_symple( elapsed_end - elapsed_start ) );
893 add_rejections_root( tree_t * restrict ptree, unsigned int move_made )
896 unsigned int * restrict pmove;
897 unsigned int *pmove_last;
898 unsigned int hash_key, hand_ply_turn;
900 unsigned char hash_parent;
902 tt = Flip( root_turn );
903 UnMakeMove( tt, move_made, 1 );
904 hash_parent = (unsigned char)(HASH_KEY >> 32);
906 pmove = ptree->amove;
907 pmove_last = GenCaptures( tt, pmove );
908 pmove_last = GenNoCaptures( tt, pmove_last );
909 pmove_last = GenCapNoProEx2( tt, pmove_last );
910 pmove_last = GenNoCapNoProEx2( tt, pmove_last );
911 pmove_last = GenDrop( tt, pmove_last );
913 while ( pmove != pmove_last )
915 if ( *pmove != move_made )
917 MakeMove( tt, *pmove, 1 );
918 if ( ! InCheck( tt ) )
920 hash_key = (unsigned int)HASH_KEY & REJEC_MASK;
921 hand_ply_turn = ( HAND_B << 6 ) | 2U | (unsigned int)tt;
922 hash_value = ( ( HASH_KEY & ~(uint64_t)0x7ffffffU )
923 | (uint64_t)hand_ply_turn );
924 hash_rejections[hash_key].root = hash_value;
925 hash_rejections_parent[hash_key] = hash_parent;
927 UnMakeMove( tt, *pmove, 1 );
932 MakeMove( tt, move_made, 1 );
937 sub_rejections_root( tree_t * restrict ptree, unsigned int move_made )
939 unsigned int * restrict pmove;
940 unsigned int *pmove_last;
941 unsigned int hash_key;
943 pmove = ptree->amove;
944 pmove_last = GenCaptures( root_turn, pmove );
945 pmove_last = GenNoCaptures( root_turn, pmove_last );
946 pmove_last = GenCapNoProEx2( root_turn, pmove_last );
947 pmove_last = GenNoCapNoProEx2( root_turn, pmove_last );
948 pmove_last = GenDrop( root_turn, pmove_last );
950 while ( pmove != pmove_last )
952 if ( *pmove != move_made )
954 MakeMove( root_turn, *pmove, 1 );
955 if ( ! InCheck( root_turn ) )
957 hash_key = (unsigned int)HASH_KEY & REJEC_MASK;
959 hash_rejections[hash_key].root = 0;
960 hash_rejections_parent[hash_key] = 0;
962 UnMakeMove( root_turn, *pmove, 1 );
970 add_rejections( tree_t * restrict ptree, int turn, int ply )
973 unsigned int * restrict pmove;
974 unsigned int * restrict pmove_last;
975 unsigned int hash_key, hand_ply_turn;
977 #if ! defined(MINIMUM)
978 if ( game_status & flag_learning ) { return; }
981 pmove = ptree->move_last[ply-1];
982 pmove_last = GenCaptures( turn, pmove );
983 pmove_last = GenNoCaptures( turn, pmove_last );
984 pmove_last = GenCapNoProEx2( turn, pmove_last );
985 pmove_last = GenNoCapNoProEx2( turn, pmove_last );
986 pmove_last = GenDrop( turn, pmove_last );
988 while ( pmove != pmove_last )
990 MakeMove( turn, *pmove, ply );
991 if ( ! InCheck( turn ) )
993 hash_key = (unsigned int)HASH_KEY & REJEC_MASK;
994 if ( ! (unsigned int)hash_rejections[hash_key].sibling )
996 hand_ply_turn = ( ( HAND_B << 6 ) | ( (unsigned int)ply << 1 )
997 | (unsigned int)turn );
998 hash_value = ( ( HASH_KEY & ~(uint64_t)0x7ffffffU )
999 | (uint64_t)hand_ply_turn );
1000 hash_rejections[hash_key].sibling = hash_value;
1002 tlp_rejections_slot[hash_key] = (unsigned short)
1003 ( ptree->tlp_slot ^ (unsigned short)( hash_value >> 32 ) );
1007 UnMakeMove( turn, *pmove, ply );
1014 sub_rejections( tree_t * restrict ptree, int turn, int ply )
1016 uint64_t hash_value;
1017 unsigned int * restrict pmove;
1018 unsigned int * restrict pmove_last;
1019 unsigned int hash_key, hand_ply_turn;
1021 #if ! defined(MINIMUM)
1022 if ( game_status & flag_learning ) { return; }
1025 pmove = ptree->move_last[ply-1];
1026 pmove_last = GenCaptures( turn, pmove );
1027 pmove_last = GenNoCaptures( turn, pmove_last );
1028 pmove_last = GenCapNoProEx2( turn, pmove_last );
1029 pmove_last = GenNoCapNoProEx2( turn, pmove_last );
1030 pmove_last = GenDrop( turn, pmove_last );
1032 while ( pmove != pmove_last )
1034 MakeMove( turn, *pmove, ply );
1035 if ( ! InCheck( turn ) )
1037 hash_key = (unsigned int)HASH_KEY & REJEC_MASK;
1038 hand_ply_turn = ( ( HAND_B << 6 )
1039 | ( (unsigned int)ply << 1 )
1040 | (unsigned int)turn );
1041 hash_value = ( ( HASH_KEY & ~(uint64_t)0x7ffffffU )
1042 | (uint64_t)hand_ply_turn );
1044 if ( hash_rejections[hash_key].sibling == hash_value )
1046 hash_rejections[hash_key].sibling = 0;
1049 UnMakeMove( turn, *pmove, ply );
1056 rejections_probe( tree_t * restrict ptree, int turn, int ply )
1058 uint64_t value_turn, value_turn_current, value;
1059 unsigned int hand_hash, hand_current, key_current;
1060 int nrep, value_ply;
1061 unsigned char parent_hash, parent_current;
1064 hand_current = HAND_B;
1065 key_current = (unsigned int)HASH_KEY & REJEC_MASK;
1066 value_turn_current = ( HASH_KEY & ~(uint64_t)0x7ffffffU ) | (uint64_t)turn;
1068 value = hash_rejections[key_current].root;
1069 value_turn = value & ~(uint64_t)0x7fffffeU;
1070 if ( value_turn == value_turn_current )
1072 hand_hash = ( (unsigned int)value & 0x7ffffffU ) >> 6;
1073 if ( ( turn && is_hand_eq_supe( hand_current, hand_hash ) )
1074 || ( ! turn && is_hand_eq_supe( hand_hash, hand_current ) ) )
1076 nrep = root_nrep + ply - 2;
1077 parent_current = (unsigned char)(ptree->rep_board_list[nrep] >> 32);
1078 parent_hash = hash_rejections_parent[key_current];
1079 if ( parent_hash != parent_current ) { return 1; }
1083 value = hash_rejections[key_current].sibling;
1084 value_ply = ( (int)value & 0x3eU ) >> 1;
1085 if ( value_ply + 2 < ply )
1087 value_turn = value & ~(uint64_t)0x7fffffeU;
1088 if ( value_turn == value_turn_current )
1090 hand_hash = ( (unsigned int)value & 0x7ffffffU ) >> 6;
1091 if ( ( turn && is_hand_eq_supe( hand_current, hand_hash ) )
1092 || ( ! turn && is_hand_eq_supe( hand_hash, hand_current ) ) )
1096 slot_hash = (int)( tlp_rejections_slot[key_current]
1097 ^ (unsigned short)( value >> 32 ) );
1098 if ( tlp_is_descendant( ptree, slot_hash ) )