X-Git-Url: http://winboard.nl/cgi-bin?p=bonanza.git;a=blobdiff_plain;f=hash.c;h=9a66ff1b9078072b8edfea86b60655ff5266c36f;hp=5ab568a61ee1a23ac39850b7a2bf4e8a41394ed3;hb=31daebfc1031441aa180e3af2e547a8cd2b92c32;hpb=18b507e1b20fc6c32ee50f00fb910a59110c1a1d diff --git a/hash.c b/hash.c index 5ab568a..9a66ff1 100644 --- a/hash.c +++ b/hash.c @@ -4,11 +4,12 @@ #include #include "shogi.h" -static int eval_supe( unsigned int hand_current, unsigned int hand_hash, - int turn_current, int turn_hash, - int * restrict pvalue_hash, int * restrict ptype_hash ); +static int CONV eval_supe( unsigned int hand_current, unsigned int hand_hash, + int turn_current, int turn_hash, + int * restrict pvalue_hash, + int * restrict ptype_hash ); -int +int CONV ini_trans_table( void ) { size_t size; @@ -29,19 +30,19 @@ ini_trans_table( void ) #define Foo( PIECE, piece ) bb = BB_B ## PIECE; \ - while( BBToU(bb) ) { \ + while( BBTest(bb) ) { \ sq = FirstOne( bb ); \ Xor( sq, bb ); \ key ^= ( b_ ## piece ## _rand )[sq]; \ } \ bb = BB_W ## PIECE; \ - while( BBToU(bb) ) { \ + while( BBTest(bb) ) { \ sq = FirstOne( bb ); \ Xor( sq, bb ); \ key ^= ( w_ ## piece ## _rand )[sq]; \ } -uint64_t +uint64_t CONV hash_func( const tree_t * restrict ptree ) { uint64_t key = 0; @@ -84,7 +85,7 @@ word2 key 57 7 age 3 0 */ -void +void CONV hash_store( const tree_t * restrict ptree, int ply, int depth, int turn, int value_type, int value, unsigned int move, unsigned int state_node ) @@ -140,7 +141,7 @@ hash_store( const tree_t * restrict ptree, int ply, int depth, int turn, } -void +void CONV hash_store_pv( const tree_t * restrict ptree, unsigned int move, int turn ) { uint64_t key_turn_pv, word1, word2; @@ -200,87 +201,18 @@ hash_store_pv( const tree_t * restrict ptree, unsigned int move, int turn ) } -trans_entry_t -hash_learn_store( const tree_t * restrict ptree, int depth, int value, - unsigned int move ) -{ - trans_entry_t ret; - - assert( 0 <= depth && depth <= 0xff ); - - ret.word2 = ( (HASH_KEY&(~(uint64_t)0x7fU)) - | (uint64_t)( (root_turn<<6) - | (value_exact<<3) | trans_table_age ) ); - ret.word1 = ( ( (uint64_t)( depth<<16 | (value+32768) ) << 40 ) - | ( (uint64_t)( move & 0x7ffffU ) << 21 ) - | HAND_B ); - - return ret; -} - - -int -all_hash_learn_store( void ) -{ - uint64_t aword[2]; - unsigned int u32key, unext, u, index; - - if ( pf_hash == NULL ) { return 0; } - - if ( fseek( pf_hash, sizeof(unsigned int), SEEK_SET ) == EOF - || fread( &unext, sizeof(unsigned int), 1, pf_hash ) != 1 ) - { - str_error = str_io_error; - return -2; - } - if ( ++unext == 0x10000U ) { unext = 0x1U; } - if ( fseek( pf_hash, (long)( 20U * unext ), SEEK_SET ) == EOF ) - { - str_error = str_io_error; - return -2; - } - for ( u = 0;; u++ ) - { - if ( fread( &u32key, sizeof(unsigned int), 1, pf_hash ) != 1 - || fread( aword, sizeof(uint64_t), 2, pf_hash ) != 2 ) - { - str_error = str_io_error; - return -2; - } - index = u32key & hash_mask; - aword[1] |= (uint64_t)trans_table_age; - SignKey( aword[1], aword[0] ); - ptrans_table[index].prefer.word1 = aword[0]; - ptrans_table[index].prefer.word2 = aword[1]; - if ( u == 0xfffeU ) { break; } - if ( ++unext == 0x10000U ) - { - unext = 0x1U; - if ( fseek( pf_hash, 20, SEEK_SET ) == EOF ) - { - str_error = str_io_error; - return -2; - } - } - } - - return 1; -} - - -unsigned int +unsigned int CONV hash_probe( tree_t * restrict ptree, int ply, int depth_current, - int turn_current, int alpha, int beta, unsigned int state_node ) + int turn_current, int alpha, int beta, unsigned int *pstate_node ) { uint64_t word1, word2, key_current, key_hash; - unsigned int hand_hash, move_hash, move_infe, move_supe, slot, utemp; + unsigned int hand_hash, move_hash, move_supe, slot, utemp; unsigned int state_node_hash, index; int null_depth, value_hash, ifrom; int turn_hash, depth_hash, type_hash, is_superior; ptree->ntrans_probe++; move_supe = 0; - move_infe = 0; if ( depth_current < 0 ) { depth_current = 0; } null_depth = NullDepth( depth_current ); @@ -312,6 +244,7 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, { if ( value_hash > 0 ) { value_hash -= ply-1; } else { value_hash += ply-1; } + #if ! defined(MINIMUM) if ( abs(value_hash) > score_mate1ply ) { @@ -319,8 +252,10 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, } #endif } - - if ( move_hash ) + + if ( RecursionThreshold <= depth_current + && depth_hash < RecursionDepth(depth_current) ) { move_hash = 0; } + else if ( move_hash ) { move_hash |= turn_current ? Cap2Move( BOARD[I2To(move_hash)]) : Cap2Move(-BOARD[I2To(move_hash)]); @@ -331,8 +266,26 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, assert( ! move_hash || is_move_valid( ptree, move_hash, turn_current ) ); ptree->amove_hash[ply] = move_hash; + *pstate_node |= state_node_hash; + + if ( value_hash <= score_max_eval ) { *pstate_node &= ~node_do_mate; } + + if ( ( type_hash & flag_value_up_exact ) + && value_hash < beta + && null_depth <= depth_hash ) + { + *pstate_node &= ~node_do_null; + } + + if ( ( type_hash & flag_value_up_exact ) + && value_hash <= alpha + && RecursionDepth(depth_current) <= depth_hash ) + { + *pstate_node &= ~node_do_recursion; + } + if ( type_hash == value_lower - && value_hash >= beta + && beta <= value_hash && ( depth_hash >= depth_current || value_hash > score_max_eval ) ) { HASH_VALUE = value_hash; @@ -371,17 +324,6 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, return value_lower; } - state_node |= state_node_hash; - - if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate; } - - if ( ( type_hash & flag_value_up_exact ) - && value_hash < beta - && null_depth <= depth_hash ) - { - state_node &= ~node_do_null; - } - } else { is_superior = eval_supe( HAND_B, hand_hash, turn_current, turn_hash, @@ -410,7 +352,7 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, || score_max_eval < value_hash || ( turn_current != turn_hash && depth_hash >= null_depth - && ( state_node & node_do_null ) ) ) ) + && ( *pstate_node & node_do_null ) ) ) ) { HASH_VALUE = value_hash; ptree->ntrans_superior_hit++; @@ -418,32 +360,37 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, } } - } else { - - if ( turn_hash == turn_current ) { move_infe = move_hash; } + } else if ( is_superior == -1 ) { - if ( is_superior == -1 ) { - - state_node |= state_node_hash; - - if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate; } - - if ( type_hash & flag_value_up_exact ) - { - if ( value_hash <= alpha - && ( depth_current <= depth_hash - || value_hash < -score_max_eval ) ) - { - HASH_VALUE = value_hash; - ptree->ntrans_inferior_hit++; - return value_upper; - } - if ( value_hash < beta && null_depth <= depth_hash ) - { - state_node &= ~node_do_null; - } - } - } + *pstate_node |= state_node_hash; + + if ( value_hash <= score_max_eval ) + { + *pstate_node &= ~node_do_mate; + } + + if ( ( type_hash & flag_value_up_exact ) + && value_hash <= alpha + && RecursionDepth(depth_current) <= depth_hash ) + { + *pstate_node &= ~node_do_recursion; + } + + if ( type_hash & flag_value_up_exact ) + { + if ( value_hash < beta && null_depth <= depth_hash ) + { + *pstate_node &= ~node_do_null; + } + if ( value_hash <= alpha + && ( depth_current <= depth_hash + || value_hash < -score_max_eval ) ) + { + HASH_VALUE = value_hash; + ptree->ntrans_inferior_hit++; + return value_upper; + } + } } } } @@ -473,6 +420,7 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, { if ( value_hash > 0 ) { value_hash -= ply-1; } else { value_hash += ply-1; } + #if ! defined(MINIMUM) if ( abs(value_hash) > score_mate1ply ) { @@ -481,7 +429,9 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, #endif } - if ( move_hash ) + if ( RecursionThreshold <= depth_current + && depth_hash < RecursionDepth(depth_current) ) { move_hash = 0; } + else if ( move_hash ) { move_hash |= turn_current ? Cap2Move( BOARD[I2To(move_hash)]) : Cap2Move(-BOARD[I2To(move_hash)]); @@ -496,6 +446,24 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, ptree->amove_hash[ply] = move_hash; } + *pstate_node |= state_node_hash; + + if ( value_hash <= score_max_eval ) { *pstate_node &= ~node_do_mate; } + + if ( ( type_hash & flag_value_up_exact ) + && value_hash <= alpha + && RecursionDepth(depth_current) <= depth_hash ) + { + *pstate_node &= ~node_do_recursion; + } + + if ( ( type_hash & flag_value_up_exact ) + && value_hash < beta + && null_depth <= depth_hash ) + { + *pstate_node &= ~node_do_null; + } + if ( type_hash == value_lower && value_hash >= beta && ( depth_hash >= depth_current || value_hash > score_max_eval ) ) @@ -537,17 +505,6 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, return value_lower; } - state_node |= state_node_hash; - - if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate; } - - if ( ( type_hash & flag_value_up_exact ) - && value_hash < beta - && null_depth <= depth_hash ) - { - state_node &= ~node_do_null; - } - } else { is_superior = eval_supe( HAND_B, hand_hash, turn_current, turn_hash, @@ -579,7 +536,7 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, || score_max_eval < value_hash || ( turn_current != turn_hash && depth_hash >= null_depth - && ( state_node & node_do_null ) ) ) ) + && ( *pstate_node & node_do_null ) ) ) ) { HASH_VALUE = value_hash; ptree->ntrans_superior_hit++; @@ -587,35 +544,37 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, } } - } else { + } else if ( is_superior == -1 ) { - if ( ! move_infe && turn_hash == turn_current ) + *pstate_node |= state_node_hash; + + if ( value_hash <= score_max_eval ) { - move_infe = move_hash; + *pstate_node &= ~node_do_mate; + } + + if ( ( type_hash & flag_value_up_exact ) + && value_hash <= alpha + && RecursionDepth(depth_current) <= depth_hash ) + { + *pstate_node &= ~node_do_recursion; + } + + if ( type_hash & flag_value_up_exact ) + { + if ( value_hash < beta && null_depth <= depth_hash ) + { + *pstate_node &= ~node_do_null; + } + if ( value_hash <= alpha + && ( depth_hash >= depth_current + || value_hash < -score_max_eval ) ) + { + HASH_VALUE = value_hash; + ptree->ntrans_inferior_hit++; + return value_upper; + } } - - if ( is_superior == -1 ) { - - state_node |= state_node_hash; - - if ( value_hash <= score_max_eval ) { state_node &= ~node_do_mate;} - - if ( type_hash & flag_value_up_exact ) - { - if ( value_hash <= alpha - && ( depth_hash >= depth_current - || value_hash < -score_max_eval ) ) - { - HASH_VALUE = value_hash; - ptree->ntrans_inferior_hit++; - return value_upper; - } - if ( value_hash < beta && null_depth <= depth_hash ) - { - state_node &= ~node_do_null; - } - } - } } } } @@ -661,170 +620,13 @@ hash_probe( tree_t * restrict ptree, int ply, int depth_current, assert( is_move_valid( ptree, move_supe, turn_current ) ); ptree->amove_hash[ply] = move_supe; } - else if ( move_infe ) - { - ifrom = (int)I2From(move_infe); - if ( ifrom >= nsquare ) - { - unsigned int hand = turn_current ? HAND_W : HAND_B; - switch( From2Drop(ifrom) ) - { - case pawn: if ( ! IsHandPawn(hand) ) { goto esc; } break; - case lance: if ( ! IsHandLance(hand) ) { goto esc; } break; - case knight: if ( ! IsHandKnight(hand) ) { goto esc; } break; - case silver: if ( ! IsHandSilver(hand) ) { goto esc; } break; - case gold: if ( ! IsHandGold(hand) ) { goto esc; } break; - case bishop: if ( ! IsHandBishop(hand) ) { goto esc; } break; - case rook: if ( ! IsHandRook(hand) ) { goto esc; } break; - } - } - assert( is_move_valid( ptree, move_infe, turn_current ) ); - ptree->amove_hash[ply] = move_infe; - } - } - - esc: - return state_node; -} - - -int -hash_learn_on( void ) -{ - int iret = file_close( pf_hash ); - if ( iret < 0 ) { return iret; } - - pf_hash = file_open( str_hash, "rb+" ); - if ( pf_hash == NULL ) { return -2; } - - return 1; -} - - -int -hash_learn_off( void ) -{ - int iret = file_close( pf_hash ); - if ( iret < 0 ) { return iret; } - - pf_hash = NULL; - - return 1; -} - -#if !defined(MINIMUM) -int -hash_learn_create( void ) -{ - uint64_t au64[2]; - unsigned int u; - int iret, i; - - iret = hash_learn_off(); - if ( iret < 0 ) { return iret; } - - pf_hash = file_open( str_hash, "wb" ); - if ( pf_hash == NULL ) { return -2; } - - for ( i = 0; i < 5; i++ ) - { - u = 0; - if ( fwrite( &u, sizeof(unsigned int), 1, pf_hash ) != 1 ) - { - str_error = str_io_error; - return -2; - } - } - - u = 0; - au64[0] = au64[1] = 0; - for ( i = 1; i < 0x10000; i++ ) - if ( fwrite( &u, sizeof(unsigned int), 1, pf_hash ) != 1 - || fwrite( au64, sizeof(uint64_t), 2, pf_hash ) != 2 ) - { - str_error = str_io_error; - return -2; - } - - return hash_learn_on(); -} -#endif - -int -hash_learn( const tree_t * restrict ptree, unsigned int move, int value, - int depth ) -{ - trans_entry_t trans_entry; - unsigned int unum, unext, u; - int pre_value, ply; - - ply = record_game.moves; - if ( ply >= HASH_REG_HIST_LEN ) { return 1; } - if ( pf_hash == NULL ) { return 1; } - if ( abs(value) > score_max_eval ) { return 1; } - if ( ply < 2 ) { return 1; } - if ( depth < 2 ) { return 1; } - - if ( history_book_learn[ply].key_probed == (unsigned int)HASH_KEY - && history_book_learn[ply].hand_probed == HAND_B - && history_book_learn[ply].move_probed == move ) { return 1; } - - if ( history_book_learn[ply-2].key_responsible - != history_book_learn[ply-2].key_played ) { return 1; } - if ( history_book_learn[ply-2].hand_responsible - != history_book_learn[ply-2].hand_played ) { return 1; } - if ( history_book_learn[ply-2].move_responsible - != history_book_learn[ply-2].move_played ) { return 1; } - - if ( ( history_book_learn[ply-2].key_probed - == history_book_learn[ply-2].key_played ) - && ( history_book_learn[ply-2].hand_probed - == history_book_learn[ply-2].hand_played ) - && ( history_book_learn[ply-2].move_probed - == history_book_learn[ply-2].move_played ) ) { return 1; } - - pre_value = (int)( history_book_learn[ply-2].data & 0xffffU ) - 32768; - - if ( pre_value < value + HASH_REG_MINDIFF ) { return 1; } - if ( pre_value < -HASH_REG_THRESHOLD ) { return 1; } - if ( pre_value == score_inferior ) { return 1; } - - Out( "save hash value of the position\n\n" ); - if ( fseek( pf_hash, 0, SEEK_SET ) == EOF - || fread( &unum, sizeof(unsigned int), 1, pf_hash ) != 1 - || fread( &unext, sizeof(unsigned int), 1, pf_hash ) != 1 ) - { - str_error = str_io_error; - return -2; - } - if ( ++unum == 0x10000U ) { unum = 0xffffU; } - if ( ++unext == 0x10000U ) { unext = 0x0001U; } - - if ( fseek( pf_hash, 0, SEEK_SET ) == EOF - || fwrite( &unum, sizeof(unsigned int), 1, pf_hash ) != 1 - || fwrite( &unext, sizeof(unsigned int), 1, pf_hash ) != 1 ) - { - str_error = str_io_error; - return -2; - } - trans_entry - = hash_learn_store( ptree, depth * PLY_INC + PLY_INC/2, value, move ); - u = (unsigned int)HASH_KEY; - if ( fseek( pf_hash, (long)( 20 * unext ), SEEK_SET ) == EOF - || fwrite( &u, sizeof(unsigned int), 1, pf_hash ) != 1 - || fwrite( &trans_entry.word1, sizeof(uint64_t), 1, pf_hash ) != 1 - || fwrite( &trans_entry.word2, sizeof(uint64_t), 1, pf_hash ) != 1 - || fflush( pf_hash ) == EOF ) - { - str_error = str_io_error; - return -2; } - return 1; + return value_null; } -static int +static int CONV eval_supe( unsigned int hand_current, unsigned int hand_hash, int turn_current, int turn_hash, int * restrict pvalue_hash, int * restrict ptype_hash ) @@ -860,7 +662,7 @@ eval_supe( unsigned int hand_current, unsigned int hand_hash, } -int +int CONV clear_trans_table( void ) { unsigned int elapsed_start, elapsed_end; @@ -887,221 +689,3 @@ clear_trans_table( void ) return 1; } - - -void -add_rejections_root( tree_t * restrict ptree, unsigned int move_made ) -{ - uint64_t hash_value; - unsigned int * restrict pmove; - unsigned int *pmove_last; - unsigned int hash_key, hand_ply_turn; - int tt; - unsigned char hash_parent; - - tt = Flip( root_turn ); - UnMakeMove( tt, move_made, 1 ); - hash_parent = (unsigned char)(HASH_KEY >> 32); - - pmove = ptree->amove; - pmove_last = GenCaptures( tt, pmove ); - pmove_last = GenNoCaptures( tt, pmove_last ); - pmove_last = GenCapNoProEx2( tt, pmove_last ); - pmove_last = GenNoCapNoProEx2( tt, pmove_last ); - pmove_last = GenDrop( tt, pmove_last ); - - while ( pmove != pmove_last ) - { - if ( *pmove != move_made ) - { - MakeMove( tt, *pmove, 1 ); - if ( ! InCheck( tt ) ) - { - hash_key = (unsigned int)HASH_KEY & REJEC_MASK; - hand_ply_turn = ( HAND_B << 6 ) | 2U | (unsigned int)tt; - hash_value = ( ( HASH_KEY & ~(uint64_t)0x7ffffffU ) - | (uint64_t)hand_ply_turn ); - hash_rejections[hash_key].root = hash_value; - hash_rejections_parent[hash_key] = hash_parent; - } - UnMakeMove( tt, *pmove, 1 ); - } - pmove++; - } - - MakeMove( tt, move_made, 1 ); -} - - -void -sub_rejections_root( tree_t * restrict ptree, unsigned int move_made ) -{ - unsigned int * restrict pmove; - unsigned int *pmove_last; - unsigned int hash_key; - - pmove = ptree->amove; - pmove_last = GenCaptures( root_turn, pmove ); - pmove_last = GenNoCaptures( root_turn, pmove_last ); - pmove_last = GenCapNoProEx2( root_turn, pmove_last ); - pmove_last = GenNoCapNoProEx2( root_turn, pmove_last ); - pmove_last = GenDrop( root_turn, pmove_last ); - - while ( pmove != pmove_last ) - { - if ( *pmove != move_made ) - { - MakeMove( root_turn, *pmove, 1 ); - if ( ! InCheck( root_turn ) ) - { - hash_key = (unsigned int)HASH_KEY & REJEC_MASK; - - hash_rejections[hash_key].root = 0; - hash_rejections_parent[hash_key] = 0; - } - UnMakeMove( root_turn, *pmove, 1 ); - } - pmove++; - } -} - - -void -add_rejections( tree_t * restrict ptree, int turn, int ply ) -{ - uint64_t hash_value; - unsigned int * restrict pmove; - unsigned int * restrict pmove_last; - unsigned int hash_key, hand_ply_turn; - -#if ! defined(MINIMUM) - if ( game_status & flag_learning ) { return; } -#endif - - pmove = ptree->move_last[ply-1]; - pmove_last = GenCaptures( turn, pmove ); - pmove_last = GenNoCaptures( turn, pmove_last ); - pmove_last = GenCapNoProEx2( turn, pmove_last ); - pmove_last = GenNoCapNoProEx2( turn, pmove_last ); - pmove_last = GenDrop( turn, pmove_last ); - - while ( pmove != pmove_last ) - { - MakeMove( turn, *pmove, ply ); - if ( ! InCheck( turn ) ) - { - hash_key = (unsigned int)HASH_KEY & REJEC_MASK; - if ( ! (unsigned int)hash_rejections[hash_key].sibling ) - { - hand_ply_turn = ( ( HAND_B << 6 ) | ( (unsigned int)ply << 1 ) - | (unsigned int)turn ); - hash_value = ( ( HASH_KEY & ~(uint64_t)0x7ffffffU ) - | (uint64_t)hand_ply_turn ); - hash_rejections[hash_key].sibling = hash_value; -#if defined(TLP) - tlp_rejections_slot[hash_key] = (unsigned short) - ( ptree->tlp_slot ^ (unsigned short)( hash_value >> 32 ) ); -#endif - } - } - UnMakeMove( turn, *pmove, ply ); - pmove++; - } -} - - -void -sub_rejections( tree_t * restrict ptree, int turn, int ply ) -{ - uint64_t hash_value; - unsigned int * restrict pmove; - unsigned int * restrict pmove_last; - unsigned int hash_key, hand_ply_turn; - -#if ! defined(MINIMUM) - if ( game_status & flag_learning ) { return; } -#endif - - pmove = ptree->move_last[ply-1]; - pmove_last = GenCaptures( turn, pmove ); - pmove_last = GenNoCaptures( turn, pmove_last ); - pmove_last = GenCapNoProEx2( turn, pmove_last ); - pmove_last = GenNoCapNoProEx2( turn, pmove_last ); - pmove_last = GenDrop( turn, pmove_last ); - - while ( pmove != pmove_last ) - { - MakeMove( turn, *pmove, ply ); - if ( ! InCheck( turn ) ) - { - hash_key = (unsigned int)HASH_KEY & REJEC_MASK; - hand_ply_turn = ( ( HAND_B << 6 ) - | ( (unsigned int)ply << 1 ) - | (unsigned int)turn ); - hash_value = ( ( HASH_KEY & ~(uint64_t)0x7ffffffU ) - | (uint64_t)hand_ply_turn ); - - if ( hash_rejections[hash_key].sibling == hash_value ) - { - hash_rejections[hash_key].sibling = 0; - } - } - UnMakeMove( turn, *pmove, ply ); - pmove++; - } -} - - -int -rejections_probe( tree_t * restrict ptree, int turn, int ply ) -{ - uint64_t value_turn, value_turn_current, value; - unsigned int hand_hash, hand_current, key_current; - int nrep, value_ply; - unsigned char parent_hash, parent_current; - - turn = Flip(turn); - hand_current = HAND_B; - key_current = (unsigned int)HASH_KEY & REJEC_MASK; - value_turn_current = ( HASH_KEY & ~(uint64_t)0x7ffffffU ) | (uint64_t)turn; - - value = hash_rejections[key_current].root; - value_turn = value & ~(uint64_t)0x7fffffeU; - if ( value_turn == value_turn_current ) - { - hand_hash = ( (unsigned int)value & 0x7ffffffU ) >> 6; - if ( ( turn && is_hand_eq_supe( hand_current, hand_hash ) ) - || ( ! turn && is_hand_eq_supe( hand_hash, hand_current ) ) ) - { - nrep = root_nrep + ply - 2; - parent_current = (unsigned char)(ptree->rep_board_list[nrep] >> 32); - parent_hash = hash_rejections_parent[key_current]; - if ( parent_hash != parent_current ) { return 1; } - } - } - - value = hash_rejections[key_current].sibling; - value_ply = ( (int)value & 0x3eU ) >> 1; - if ( value_ply + 2 < ply ) - { - value_turn = value & ~(uint64_t)0x7fffffeU; - if ( value_turn == value_turn_current ) - { - hand_hash = ( (unsigned int)value & 0x7ffffffU ) >> 6; - if ( ( turn && is_hand_eq_supe( hand_current, hand_hash ) ) - || ( ! turn && is_hand_eq_supe( hand_hash, hand_current ) ) ) - { -#if defined(TLP) - int slot_hash; - slot_hash = (int)( tlp_rejections_slot[key_current] - ^ (unsigned short)( value >> 32 ) ); - if ( tlp_is_descendant( ptree, slot_hash ) ) - -#endif - return 1; - } - } - } - - return 0; -}