#include <limits.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include <assert.h>
#include "shogi.h"
-static void hist_add( tree_t * restrict ptree, int ply );
-static void hist_good( tree_t * restrict ptree, unsigned int move, int ply,
- int depth, int turn );
-static int detect_signals( tree_t * restrict ptree );
-static int detect_rep( tree_t * restrict ptree, int ply, int turn );
-static int rep_type( const tree_t * restrict ptree, int n, int i, int ply,
- int turn );
+static void CONV hist_add( tree_t * restrict ptree, int ply );
+static void CONV hist_good( tree_t * restrict ptree, unsigned int move,
+ int ply, int depth, int turn );
+static int CONV detect_rep( tree_t * restrict ptree, int ply, int turn );
+static int CONV rep_type( const tree_t * restrict ptree, int n, int i, int ply,
+ int turn );
/* #define DBG_SEARCH */
#if defined(DBG_SEARCH)
# define DOut( ... )
#endif
-int
+int CONV
search( tree_t * restrict ptree, int alpha, int beta, int turn, int depth,
int ply, unsigned int state_node )
{
int value, alpha_old;
- if ( ! ptree->nsuc_check[ply] && depth < PLY_INC )
+ if ( ! ptree->nsuc_check[ply] && depth < PLY_INC )
{
return search_quies( ptree, alpha, beta, turn, ply, 1 );
}
}
break;
}
-
- ptree->nreject_tried++;
- if ( rejections_probe( ptree, turn, ply ) )
- {
- ptree->nreject_done++;
- if ( alpha < score_inferior && score_inferior < beta )
- {
- pv_close( ptree, ply, turn ? white_superi_rep:black_superi_rep );
- }
- MOVE_CURR = MOVE_NA;
- return score_inferior;
- }
}
/*
if ( value <= alpha ) { return value; }
}
-#if defined(NO_NULL_PRUNE)
- state_node &= ~node_do_null;
-#endif
-
ptree->amove_hash[ply] = 0;
+
#if ! defined(MINIMUM)
if ( ! ( game_status & flag_learning ) )
#endif
{
/* probe the transposition table */
- int tv = hash_probe( ptree, ply, depth, turn, alpha, beta, state_node );
- switch ( tv )
+ switch ( hash_probe( ptree, ply, depth, turn, alpha, beta,
+ &state_node ) )
{
case value_exact:
- if ( alpha < HASH_VALUE )
+ MOVE_CURR = ptree->amove_hash[ply];
+ assert( ! IsMove(MOVE_CURR)
+ || is_move_valid( ptree, MOVE_CURR, turn ) );
+ if ( ( state_node & node_do_hashcut ) && beta == alpha_old + 1 )
{
- if ( HASH_VALUE < beta ) { pv_close( ptree, ply, hash_hit ); }
- else {
- MOVE_CURR = ptree->amove_hash[ply];
- assert( is_move_valid( ptree, MOVE_CURR, turn ) );
- }
+ if ( alpha < HASH_VALUE
+ && HASH_VALUE < beta ) { pv_close( ptree, ply, hash_hit ); }
+ return HASH_VALUE;
}
- return HASH_VALUE;
-
+ break;
+
case value_lower:
MOVE_CURR = ptree->amove_hash[ply];
assert( beta <= HASH_VALUE );
assert( ! IsMove(MOVE_CURR)
|| is_move_valid( ptree, MOVE_CURR, turn ) );
- if ( beta == alpha_old + 1 ) { return HASH_VALUE; }
+ if ( ( state_node & node_do_hashcut )
+ && beta == alpha_old + 1 ) { return HASH_VALUE; }
break;
case value_upper:
assert( HASH_VALUE <= alpha );
- if ( beta == alpha_old + 1 ) { return HASH_VALUE; }
+ if ( ( state_node & node_do_hashcut )
+ && beta == alpha_old + 1 ) { return HASH_VALUE; }
break;
-
- default:
- state_node = tv;
}
}
DOut( "\nhash cut passed" );
- if ( depth >= REJEC_MIN_DEPTH ) { add_rejections( ptree, turn, ply ); }
-
if ( ! ptree->nsuc_check[ply] )
{
if ( alpha < value
&& value < beta ) { pv_close( ptree, ply, mate_search ); }
- if ( depth >= REJEC_MIN_DEPTH )
- {
- sub_rejections( ptree, turn, ply );
- }
assert( is_move_valid( ptree, MOVE_CURR, turn ) );
return value;
}
int null_depth, nrep;
null_depth = NullDepth(depth);
- nrep = root_nrep + ply - 1;
+ nrep = ptree->nrep + ply - 1;
MOVE_CURR = MOVE_PASS;
ptree->move_last[ply] = ptree->move_last[ply-1];
- ptree->stand_pat[ply+1] = (short)( - ptree->stand_pat[ply] );
+ ptree->save_eval[ply+1] = - ptree->save_eval[ply];
ptree->nsuc_check[ply+1] = 0;
ptree->rep_board_list[nrep] = HASH_KEY;
ptree->rep_hand_list[nrep] = HAND_B;
ptree->null_pruning_tried++;
value = -search( ptree, -beta, 1-beta, Flip(turn), null_depth, ply+1,
- node_do_mate | node_do_recap | node_do_futile );
- if ( SEARCH_ABORT )
- {
- if ( depth >= REJEC_MIN_DEPTH )
- {
- sub_rejections( ptree, turn, ply );
- }
- return 0;
- }
+ node_do_mate | node_do_recap | node_do_futile
+ | node_do_recursion | node_do_hashcut );
+ if ( SEARCH_ABORT ) { return 0; }
if ( beta <= value )
{
hash_store( ptree, ply, depth, turn, value_lower,
value, MOVE_NA, state_node );
}
- if ( depth >= REJEC_MIN_DEPTH )
- {
- sub_rejections( ptree, turn, ply );
- }
DOut( "\nnull move cut!\n" );
}
}
- /* recursive iterative-deepening for pv nodes */
- if ( ! ptree->amove_hash[ply]
- && depth >= 3*PLY_INC
- && ( ( alpha == root_alpha && beta == root_beta )
- || ( alpha == -root_beta && beta == -root_alpha ) ) )
+ /* recursive iterative-deepening */
+ if ( ! ptree->amove_hash[ply] && RecursionThreshold <= depth
+ && ( state_node & node_do_recursion ) )
{
- if ( depth >= REJEC_MIN_DEPTH ) { sub_rejections( ptree, turn, ply ); }
- value = search( ptree, -score_bound, beta, turn, depth-2*PLY_INC, ply,
- node_do_mate | node_do_recap );
+ int new_depth = RecursionDepth(depth);
+ int state_node_new = state_node & ~( node_do_mate | node_do_null
+ | node_do_hashcut );
+
+ value = search( ptree, alpha, beta, turn, new_depth, ply,
+ state_node_new );
if ( SEARCH_ABORT ) { return 0; }
- if ( beta <= value && IsMove(MOVE_CURR) )
- {
- ptree->amove_hash[ply] = MOVE_CURR;
- }
- else if ( value < beta && ply <= (int)ptree->pv[ply-1].length )
+ if ( beta <= value ) { ptree->amove_hash[ply] = MOVE_CURR; }
+ else if ( alpha < value )
{
+ assert( ply <= (int)ptree->pv[ply-1].length );
assert( -score_bound < value );
ptree->amove_hash[ply] = ptree->pv[ply-1].a[ply];
}
+
assert( ! ptree->amove_hash[ply]
|| is_move_valid( ptree, ptree->amove_hash[ply], turn ) );
- if ( depth >= REJEC_MIN_DEPTH ) { add_rejections( ptree, turn, ply ); }
}
{
ptree->nsuc_check[ply+1] = 0U;
state_node_new = ( node_do_mate | node_do_recap | node_do_null
- | node_do_futile );
+ | node_do_futile | node_do_recursion
+ | node_do_hashcut );
extension = 0;
depth_reduced = 0;
hist_add( ptree, ply );
/* decision of extensions */
- if ( turn ? is_move_check_w( ptree, MOVE_CURR )
- : is_move_check_b( ptree, MOVE_CURR ) )
+ if ( IsMoveCheck( ptree, turn, MOVE_CURR ) )
{
ptree->check_extension_done++;
ptree->nsuc_check[ply+1]
&& I2PieceMove(MOVE_LAST) != silver ) ) )
{
ptree->recap_extension_done++;
- state_node_new = node_do_null | node_do_mate | node_do_futile;
+ state_node_new = ( node_do_null | node_do_mate | node_do_futile
+ | node_do_recursion | node_do_hashcut );
if ( ! I2IsPromote(MOVE_CURR)
&& I2PieceMove(MOVE_LAST) == UToCap(MOVE_LAST) )
{
/* reductions */
if ( PLY_INC <= new_depth
+ && first_move_expanded
&& ! ( state_node & node_mate_threat )
&& ! ptree->nsuc_check[ply]
&& ! UToCap(MOVE_CURR)
unsigned int triedx8 = ( ptree->hist_tried[key] + 2 ) * 8U;
if ( beta != alpha_old + 1 ) {
-
- if ( good * 62U < triedx8 ) { depth_reduced = PLY_INC * 4/2; }
- else if ( good * 46U < triedx8 ) { depth_reduced = PLY_INC * 3/2; }
- else if ( good * 34U < triedx8 ) { depth_reduced = PLY_INC * 2/2; }
+
+ if ( good *160U < triedx8 ) { depth_reduced = PLY_INC * 3/2; }
+ else if ( good * 50U < triedx8 ) { depth_reduced = PLY_INC * 2/2; }
else if ( good * 19U < triedx8 ) { depth_reduced = PLY_INC * 1/2; }
-
+
} else {
- if ( good * 62U < triedx8 ) { depth_reduced = PLY_INC * 4/2; }
+ if ( good * 75U < triedx8 ) { depth_reduced = PLY_INC * 4/2; }
else if ( good * 46U < triedx8 ) { depth_reduced = PLY_INC * 3/2; }
else if ( good * 30U < triedx8 ) { depth_reduced = PLY_INC * 2/2; }
else if ( good * 12U < triedx8 ) { depth_reduced = PLY_INC * 1/2; }
new_depth -= depth_reduced;
}
-
+
/* futility pruning */
if ( ! ptree->nsuc_check[ply+1]
&& ! ptree->nsuc_check[ply]
if ( 2*PLY_INC <= new_depth ) { bound -= EFUTIL_MG2; }
else if ( 1*PLY_INC <= new_depth ) { bound -= EFUTIL_MG1; }
- if ( eval_max_score( ptree, MOVE_CURR, ptree->stand_pat[ply],
+ if ( eval_max_score( ptree, MOVE_CURR, ptree->save_eval[ply],
turn, diff ) <= bound )
{
first_move_expanded += 1;
DOut( ", futil passed" );
+ if ( new_depth < 2*PLY_INC
+ && ! ptree->nsuc_check[ply]
+ && ! ptree->nsuc_check[ply+1]
+ && ! UToCap(MOVE_CURR)
+ && ! ( I2IsPromote(MOVE_CURR)
+ && I2PieceMove(MOVE_CURR) != silver )
+ && ptree->amove_hash[ply] != MOVE_CURR
+ && ptree->killers[ply].no1 != MOVE_CURR
+ && ptree->killers[ply].no2 != MOVE_CURR
+ && beta == alpha_old + 1
+ && swap( ptree, MOVE_CURR, -1, 0, turn ) <= -1 )
+ {
+ first_move_expanded += 1;
+ continue;
+ }
+
MakeMove( turn, MOVE_CURR, ply );
if ( I2From(MOVE_CURR) < nsquare
&& ! ptree->nsuc_check[ply]
if ( ! ptree->nsuc_check[ply+1] && ! ptree->nsuc_check[ply] )
{
- evaluate( ptree, ply+1, Flip(turn) );
- assert( ptree->stand_pat[ply] != score_bound );
+ int score = -evaluate( ptree, ply+1, Flip(turn) );
+ assert( ptree->save_eval[ply] != INT_MAX );
/* futility pruning */
- if ( ( new_depth < PLY_INC && - ptree->stand_pat[ply+1] <= alpha )
- || ( new_depth < 2*PLY_INC
- && - ptree->stand_pat[ply+1] <= alpha - EFUTIL_MG1 )
- || ( new_depth < 3*PLY_INC
- && - ptree->stand_pat[ply+1] <= alpha - EFUTIL_MG2 ) )
+ if ( ( new_depth < PLY_INC && score <= alpha )
+ || ( new_depth < 2*PLY_INC && score <= alpha - EFUTIL_MG1 )
+ || ( new_depth < 3*PLY_INC && score <= alpha - EFUTIL_MG2 ) )
{
first_move_expanded += 1;
UnMakeMove( turn, MOVE_CURR, ply );
}
}
- if ( depth_reduced )
- {
- value = -search( ptree, -alpha-1, -alpha, Flip(turn), new_depth,
- ply + 1, state_node_new );
- if ( ! SEARCH_ABORT && alpha < value )
- {
- new_depth += depth_reduced;
- value = -search( ptree, -beta, -alpha, Flip(turn), new_depth,
- ply+1, state_node_new );
- }
- }
- else if ( ! first_move_expanded )
+ if ( ! first_move_expanded )
{
value = -search( ptree, -beta, -alpha, Flip(turn), new_depth, ply+1,
state_node_new );
else {
value = -search( ptree, -alpha-1, -alpha, Flip(turn), new_depth,
ply + 1, state_node_new );
+ if ( ! SEARCH_ABORT && alpha < value && depth_reduced )
+ {
+ new_depth += depth_reduced;
+ value = -search( ptree, -alpha-1, -alpha, Flip(turn), new_depth,
+ ply+1, state_node_new );
+ }
if ( ! SEARCH_ABORT && alpha < value && beta != alpha+1 )
{
value = -search( ptree, -beta, -alpha, Flip(turn), new_depth,
ply + 1, state_node_new );
}
}
-
if ( SEARCH_ABORT )
{
UnMakeMove( turn, MOVE_CURR, ply );
- if ( depth >= REJEC_MIN_DEPTH )
- {
- sub_rejections( ptree, turn, ply );
- }
return 0;
}
{
if ( new_depth < PLY_INC
&& ! ptree->nsuc_check[ply+1]
- && ptree->stand_pat[ply] != score_bound )
+ && ptree->save_eval[ply] != INT_MAX )
{
check_futile_score_quies( ptree, MOVE_CURR,
- ptree->stand_pat[ply],
- -ptree->stand_pat[ply+1], turn );
+ ptree->save_eval[ply],
+ -ptree->save_eval[ply+1], turn );
}
if ( beta <= value )
ptree->fail_high++;
if ( ! first_move_expanded ) { ptree->fail_high_first++; }
- if ( depth >= REJEC_MIN_DEPTH )
- {
- sub_rejections( ptree, turn, ply );
- }
-
assert( is_move_valid( ptree, MOVE_CURR, turn ) );
return value;
}
{
if ( beta <= value )
{
- if ( depth >= REJEC_MIN_DEPTH )
- {
- sub_rejections( ptree, turn, ply );
- }
-
hash_store( ptree, ply, depth, turn, value_lower,
value, MOVE_CURR, state_node );
DOut( "\nall searched (%" PRIu64 ")\n", ptree->node_searched );
- if ( depth >= REJEC_MIN_DEPTH ) { sub_rejections( ptree, turn, ply ); }
-
if ( ! first_move_expanded )
{
#if ! defined(MINIMUM)
#if defined(TLP)
-int
+int CONV
tlp_search( tree_t * restrict ptree, int alpha, int beta, int turn,
int depth, int ply, unsigned int state_node )
{
for ( ;; ) {
lock( & ptree->tlp_ptree_parent->tlp_lock );
+ if ( ptree->tlp_abort )
+ {
+ unlock( & ptree->tlp_ptree_parent->tlp_lock );
+ return 0;
+ }
if ( ptree->nsuc_check[ply] )
{
iret = gen_next_evasion( ptree->tlp_ptree_parent, ply, turn );
}
else { iret = gen_next_move( ptree->tlp_ptree_parent, ply, turn ); }
+
MOVE_CURR = ptree->tlp_ptree_parent->current_move[ply];
hist_add( ptree->tlp_ptree_parent, ply );
unlock( & ptree->tlp_ptree_parent->tlp_lock );
ptree->nsuc_check[ply+1] = 0U;
state_node_new = ( node_do_mate | node_do_recap | node_do_null
- | node_do_futile );
+ | node_do_futile | node_do_recursion
+ | node_do_hashcut );
extension = 0;
depth_reduced = 0;
- if ( turn ? is_move_check_w( ptree, MOVE_CURR )
- : is_move_check_b( ptree, MOVE_CURR ) )
+ if ( IsMoveCheck( ptree, turn, MOVE_CURR ) )
{
ptree->check_extension_done++;
ptree->nsuc_check[ply+1]
&& I2PieceMove(MOVE_LAST) != silver ) ) )
{
ptree->recap_extension_done++;
- state_node_new = node_do_null | node_do_mate | node_do_futile;
+ state_node_new = ( node_do_null | node_do_mate | node_do_futile
+ | node_do_recursion | node_do_hashcut );
if ( ! I2IsPromote(MOVE_CURR)
&& I2PieceMove(MOVE_LAST) == UToCap(MOVE_LAST) )
{
if ( beta != alpha_old + 1 ) {
- if ( good * 62U < triedx8 ) { depth_reduced = PLY_INC * 4/2; }
- else if ( good * 46U < triedx8 ) { depth_reduced = PLY_INC * 3/2; }
- else if ( good * 34U < triedx8 ) { depth_reduced = PLY_INC * 2/2; }
+ if ( good *160U < triedx8 ) { depth_reduced = PLY_INC * 3/2; }
+ else if ( good * 50U < triedx8 ) { depth_reduced = PLY_INC * 2/2; }
else if ( good * 19U < triedx8 ) { depth_reduced = PLY_INC * 1/2; }
} else {
- if ( good * 62U < triedx8 ) { depth_reduced = PLY_INC * 4/2; }
+ if ( good * 75U < triedx8 ) { depth_reduced = PLY_INC * 4/2; }
else if ( good * 46U < triedx8 ) { depth_reduced = PLY_INC * 3/2; }
else if ( good * 30U < triedx8 ) { depth_reduced = PLY_INC * 2/2; }
else if ( good * 12U < triedx8 ) { depth_reduced = PLY_INC * 1/2; }
if ( 2*PLY_INC <= new_depth ) { bound -= EFUTIL_MG2; }
else if ( 1*PLY_INC <= new_depth ) { bound -= EFUTIL_MG1; }
- if ( eval_max_score( ptree, MOVE_CURR, ptree->stand_pat[ply],
+ if ( eval_max_score( ptree, MOVE_CURR, ptree->save_eval[ply],
turn, diff ) <= bound )
{
continue;
if ( ! ptree->nsuc_check[ply+1] && ! ptree->nsuc_check[ply] )
{
- evaluate( ptree, ply+1, Flip(turn) );
- assert( ptree->stand_pat[ply] != score_bound );
+ int score = -evaluate( ptree, ply+1, Flip(turn) );
+ assert( ptree->save_eval[ply] != INT_MAX );
/* futility pruning */
- if ( ( new_depth < PLY_INC && - ptree->stand_pat[ply+1] <= alpha )
- || ( new_depth < 2*PLY_INC
- && - ptree->stand_pat[ply+1] <= alpha - EFUTIL_MG1 )
- || ( new_depth < 3*PLY_INC
- && - ptree->stand_pat[ply+1] <= alpha - EFUTIL_MG2 ) )
+ if ( ( new_depth < PLY_INC && score <= alpha )
+ || ( new_depth < 2*PLY_INC && score <= alpha - EFUTIL_MG1 )
+ || ( new_depth < 3*PLY_INC && score <= alpha - EFUTIL_MG2 ) )
{
UnMakeMove( turn, MOVE_CURR, ply );
continue;
}
#endif /* TLP */
+void CONV
+pv_close( tree_t * restrict ptree, int ply, int type )
+{
+ ptree->pv[ply-1].a[ply-1] = (ptree)->current_move[ply-1];
+ ptree->pv[ply-1].length = (unsigned char)(ply-1);
+ ptree->pv[ply-1].type = (unsigned char)type;
+ ptree->pv[ply-1].depth = (unsigned char)iteration_depth;
+}
+
+void CONV
+pv_copy( tree_t * restrict ptree, int ply )
+{
+ memcpy( &(ptree->pv[ply-1].a[ply]), &(ptree->pv[ply].a[ply]),
+ ( ptree->pv[ply].length-ply+1 ) * sizeof(unsigned int) );
+ ptree->pv[ply-1].type = ptree->pv[ply].type;
+ ptree->pv[ply-1].length = ptree->pv[ply].length;
+ ptree->pv[ply-1].depth = ptree->pv[ply].depth;
+ ptree->pv[ply-1].a[ply-1] = ptree->current_move[ply-1];
+}
+
-static int
+int CONV
detect_signals( tree_t * restrict ptree )
{
unsigned int tnow, telapsed, tpondered, tsearched, tcount, tlimit, tmax;
- unsigned int tmax_limit_count, tlimit_count, u;
+ unsigned int tlimit_count, u;
int iret, easy_time, last_value, stable;
+#if defined(DFPN_CLIENT)
+ int is_first_move_skipped = 0;
+#endif
+
+#if defined(DFPN_CLIENT)
+ /* probe results from DFPN server */
+ if ( dfpn_client_flag_read )
+ {
+ dfpn_client_check_results();
+ if ( dfpn_client_move_unlocked != MOVE_NA ) { return 1; }
+ if ( root_move_list[root_index].dfpn_cresult == dfpn_client_win )
+ {
+ is_first_move_skipped = 1;
+ }
+ }
+#endif
+
+
if ( ! ( game_status & flag_nopeek ) )
{
/* peek input-buffer to find a command */
else if ( iret == -2 )
{
out_warning( "%s", str_error );
- ShutdownClient;
+ ShutdownAll();
}
else if ( game_status & flag_quit ) { return 1; } /* EOF */
else if ( iret )
{
out_warning( "%s", str_error );
next_cmdline( 1 );
- ShutdownClient;
+ ShutdownAll();
}
else if ( iret == 1 ) { next_cmdline( 1 ); }
}
#endif
-#if defined(MNJ_LAN)
- if ( sckt_mnj != SCKT_NULL && 500U < tnow - time_last_send )
+#if defined(USI)
+ if ( usi_mode != usi_off && 1000U + usi_time_out_last < tnow )
{
uint64_t nodes;
+ double dnps;
# if defined(TLP)
lock( &tlp_lock );
nodes = ptree->node_searched;
# endif
- if ( sckt_out( sckt_mnj, "pid=%d n=%" PRIu64 "\n", mnj_posi_id,
- nodes ) < 0 )
- {
- game_status |= flag_search_error;
- return 1;
- }
+ dnps = (double)nodes * 1000.0 / (double)( tnow - time_turn_start );
+ USIOut( "info time %u nodes %" PRIu64 " nps %d\n",
+ tnow, nodes, (unsigned int)dnps );
+
+ usi_time_out_last = tnow;
+ }
+#endif
+
+#if defined(MNJ_LAN)
+ if ( sckt_mnj != SCKT_NULL && 500U + time_last_send < tnow )
+ {
+ uint64_t nodes;
+
+# if defined(TLP)
+ lock( &tlp_lock );
+ nodes = tlp_count_node( tlp_atree_work );
+ unlock( &tlp_lock );
+# else
+ nodes = ptree->node_searched;
+# endif
+
+ MnjOut( "pid=%d n=%" PRIu64 "\n", mnj_posi_id, nodes );
}
#endif
if ( tlimit != tmax )
{
tcount = tsearched;
- tmax_limit_count = tmax;
tlimit_count = tlimit;
}
else {
tcount = telapsed;
- tmax_limit_count = tmax + tpondered;
tlimit_count = tlimit + tpondered;
}
if ( stable && tcount > tlimit ) { return 1; }
if ( stable
- && ( tmax_limit_count * 3U < ( time_last_search - time_start ) * 5U ) )
- {
-#if defined(DBG_EASY)
- if ( ! easy_move )
- {
- Out( " The search can be terminated "
- "before it reaches time-limit.\n" );
- easy_move = ptree->pv[0].a[1];
- }
-#else
- Out( " The search is terminated before it reaches time-limit.\n" );
- return 1;
-#endif
- }
-
- if ( stable
&& easy_abs > abs( last_value )
&& easy_min < last_value - easy_value
&& easy_max > last_value - easy_value )
else if ( tsearched + 500U > u ) { easy_time = 1; }
}
- /* renew node_per_second */
+ /* update node_per_second */
{
double dn, dd;
else { node_per_second = u; }
}
- /* renew node_next_signal */
+ /* update node_next_signal */
if ( ! ( game_status & flag_pondering ) && root_nmove == 1 )
{
u = 2000U - time_response;
}
else { node_next_signal = node_per_second / 32U; }
- /* renew time_last_check and node_last_check */
+ /* update time_last_check and node_last_check */
time_last_check = tnow;
node_last_check = 0;
-
- return 0;
-}
-
-int
-is_move_check_b( const tree_t * restrict ptree, unsigned int move )
-{
- const int from = (int)I2From(move);
- const int to = (int)I2To(move);
- int is_check, ipiece_move, idirec;
- bitboard_t bb;
-
- is_check = 0;
-
- if ( from >= nsquare ) { ipiece_move = From2Drop(from); }
- else {
- ipiece_move = (int)I2PieceMove(move);
- if ( I2IsPromote(move) ) { ipiece_move += promote; }
-
- idirec = (int)adirec[SQ_WKING][from];
- if ( idirec && idirec != (int)adirec[SQ_WKING][to]
- && is_pinned_on_white_king( ptree, from, idirec ) )
- {
- is_check = 1;
- goto end;
- }
- }
-
- switch ( ipiece_move )
+#if defined(DFPN_CLIENT)
+ if ( is_first_move_skipped )
{
- case pawn:
- if ( BOARD[to-nfile] == -king ) { is_check = 1; }
- break;
-
- case lance:
- AttackBLance( bb, to );
- if ( BBContract( bb, BB_WKING ) ) { is_check = 1; }
- break;
-
- case knight:
- if ( BBContract(abb_b_knight_attacks[to],BB_WKING) ) { is_check = 1; }
- break;
-
- case silver:
- if ( BBContract(abb_b_silver_attacks[to],BB_WKING) ) { is_check = 1; }
- break;
-
- case gold: case pro_pawn:
- case pro_lance: case pro_knight:
- case pro_silver:
- if ( BBContract(abb_b_gold_attacks[to],BB_WKING) ) { is_check = 1; }
- break;
-
- case bishop:
- AttackBishop( bb, to );
- if ( BBContract( bb, BB_WKING ) ) { is_check = 1; }
- break;
-
- case rook:
- AttackRook( bb, to );
- if ( BBContract( bb, BB_WKING ) ) { is_check = 1; }
- break;
-
- case king:
- break;
-
- case horse:
- AttackHorse( bb, to );
- if ( BBContract( bb, BB_WKING ) ) { is_check = 1; }
- break;
-
- default:
- assert( ipiece_move == dragon );
- AttackDragon( bb, to );
- if ( BBContract( bb, BB_WKING ) ) { is_check = 1; }
- break;
- }
-
- end:
- return is_check;
-}
-
-
-int
-is_move_check_w( const tree_t * restrict ptree, unsigned int move )
-{
- const int from = (int)I2From(move);
- const int to = (int)I2To(move);
- int is_check, ipiece_move, idirec;
- bitboard_t bb;
-
- is_check = 0;
-
- if ( from >= nsquare ) { ipiece_move = From2Drop(from); }
- else {
- ipiece_move = (int)I2PieceMove(move);
- if ( I2IsPromote(move) ) { ipiece_move += promote; }
-
- idirec = (int)adirec[SQ_BKING][from];
- if ( idirec && idirec != (int)adirec[SQ_BKING][to]
- && is_pinned_on_black_king( ptree, from, idirec ) )
- {
- is_check = 1;
- goto end;
- }
- }
-
- switch ( ipiece_move )
- {
- case pawn:
- if ( BOARD[to+nfile] == king ) { is_check = 1; }
- break;
-
- case lance:
- AttackWLance( bb, to );
- if ( BBContract( bb, BB_BKING ) ) { is_check = 1; }
- break;
-
- case knight:
- if ( BBContract(abb_w_knight_attacks[to],BB_BKING) ) { is_check = 1; }
- break;
-
- case silver:
- if ( BBContract(abb_w_silver_attacks[to],BB_BKING) ) { is_check = 1; }
- break;
-
- case gold: case pro_pawn:
- case pro_lance: case pro_knight:
- case pro_silver:
- if ( BBContract(abb_w_gold_attacks[to],BB_BKING) ) { is_check = 1; }
- break;
-
- case bishop:
- AttackBishop( bb, to );
- if ( BBContract( bb, BB_BKING ) ) { is_check = 1; }
- break;
-
- case rook:
- AttackRook( bb, to );
- if ( BBContract( bb, BB_BKING ) ) { is_check = 1; }
- break;
-
- case king:
- break;
-
- case horse:
- AttackHorse( bb, to );
- if ( BBContract( bb, BB_BKING ) ) { is_check = 1; }
- break;
-
- default:
- assert( ipiece_move == dragon );
- AttackDragon( bb, to );
- if ( BBContract( bb, BB_BKING ) ) { is_check = 1; }
- break;
+ game_status |= flag_skip_root_move;
+ return 1;
}
-
- end:
- return is_check;
-}
-
-
-void
-pv_close( tree_t * restrict ptree, int ply, int type )
-{
- ptree->pv[ply-1].a[ply-1] = (ptree)->current_move[ply-1];
- ptree->pv[ply-1].length = (unsigned char)(ply-1);
- ptree->pv[ply-1].type = (unsigned char)type;
- ptree->pv[ply-1].depth = (unsigned char)iteration_depth;
-}
-
-
-void
-pv_copy( tree_t * restrict ptree, int ply )
-{
- memcpy( &(ptree->pv[ply-1].a[ply]), &(ptree->pv[ply].a[ply]),
- ( ptree->pv[ply].length-ply+1 ) * sizeof(unsigned int) );
- ptree->pv[ply-1].type = ptree->pv[ply].type;
- ptree->pv[ply-1].length = ptree->pv[ply].length;
- ptree->pv[ply-1].depth = ptree->pv[ply].depth;
- ptree->pv[ply-1].a[ply-1] = ptree->current_move[ply-1];
+#endif
+
+ return 0;
}
-static int
+static int CONV
detect_rep( tree_t * restrict ptree, int ply, int turn )
{
if ( ply < 4 ) { return detect_repetition( ptree, ply, turn, 2 ); }
else {
int n, i, imin, iret;
- n = root_nrep + ply - 1;
+ n = ptree->nrep + ply - 1;
imin = n - REP_MAX_PLY;
if ( imin < 0 ) { imin = 0; }
}
-static int
+static int CONV
rep_type( const tree_t * restrict ptree, int n, int i, int ply, int turn )
{
const unsigned int hand1 = HAND_B;
}
-static void
+static void CONV
hist_add( tree_t * restrict ptree, int ply )
{
if ( ptree->nsuc_check[ply] ) { return; }
}
-static void
+static void CONV
hist_good( tree_t * restrict ptree, unsigned int move_good, int ply,
int depth, int turn )
{