gochatai/pachi_py/pachi/timeinfo.c
/* Pre-process time_info for search control and sets the desired stopping conditions. */
Pre-process time_info for search control and sets the desired stopping conditions.
Pre - process time_info for search control and sets the desired stopping conditions .
void
time_stop_conditions(struct time_info *ti, struct board *b, int fuseki_end, int yose_start,
		     floating_t max_maintime_ratio, struct time_stop *stop)
{
	assert(ti->period != TT_NULL);
	if (ti->dim == TD_GAMES) {
		if (ti->period == TT_TOTAL) {
			ti->period = TT_MOVE;
			ti->len.games /= board_estimated_moves_left(b);
		}
		stop->desired.playouts = ti->len.games;
		stop->worst.playouts = ti->len.games;
		return;
	}
	assert(ti->dim == TD_WALLTIME);
	double net_lag = MAX_NET_LAG;
	net_lag += time_now() - ti->len.t.timer_start;
	if (ti->period == TT_TOTAL && time_in_byoyomi(ti)) {
		ti->period = TT_MOVE;
	}
	if (ti->period == TT_MOVE) {
		double period_len = ti->len.t.byoyomi_time + ti->len.t.main_time;
		stop->worst.time = period_len;
		assert(ti->len.t.byoyomi_stones > 0);
		stop->desired.time = period_len / ti->len.t.byoyomi_stones;
		if (stop->desired.time >= period_len - net_lag) {
			double safe_margin = RESERVED_BYOYOMI_PERCENT * stop->desired.time / 100;
			if (safe_margin > net_lag)
				net_lag = safe_margin;
		}
		double worst_time = stop->desired.time * MAX_BYOYOMI_TIME_RATIO;
		if (worst_time < stop->worst.time)
			stop->worst.time = worst_time;
		stop->desired.time *= (2 - MAX_BYOYOMI_TIME_RATIO);
	} else { assert(ti->period == TT_TOTAL);
		assert(ti->len.t.main_time > 0);
		int moves_left = time_stop_set_remaining(ti, b, net_lag, stop);
		stop->desired.time = stop->worst.time / moves_left;
		assert(stop->desired.time > 0 && stop->worst.time > 0);
		assert(stop->desired.time <= stop->worst.time + 0.001);
		time_stop_phase_adjust(b, fuseki_end, yose_start, stop);
		double worst_time = stop->desired.time;
		if (ti->len.t.byoyomi_time_max > ti->len.t.byoyomi_stones_max) {
			worst_time *= max_maintime_ratio;
		} else {
			worst_time *= MAX_SUDDEN_DEATH_RATIO;
		}
		if (worst_time < stop->worst.time)
			stop->worst.time = worst_time;
		if (stop->desired.time > stop->worst.time)
			stop->desired.time = stop->worst.time;
	}
	if (DEBUGL(1))
		fprintf(stderr, "desired %0.2f, worst %0.2f, clock [%d] %0.2f + %0.2f/%d*%d, lag %0.2f\n",
			stop->desired.time, stop->worst.time,
			ti->dim, ti->len.t.main_time,
			ti->len.t.byoyomi_time, ti->len.t.byoyomi_stones,
			ti->len.t.byoyomi_periods, net_lag);
	lag_adjust(&stop->desired.time, net_lag);
	lag_adjust(&stop->worst.time, net_lag);
}
void time_stop_conditions ( struct time_info * ti , struct board * b , int fuseki_end , int yose_start , floating_t max_maintime_ratio , struct time_stop * stop ) { assert ( ti -> period != TT_NULL ) ; if ( ti -> dim == TD_GAMES ) { if ( ti -> period == TT_TOTAL ) { ti -> period = TT_MOVE ; ti -> len . games /= board_estimated_moves_left ( b ) ; } stop -> desired . playouts = ti -> len . games ; stop -> worst . playouts = ti -> len . games ; return ; } assert ( ti -> dim == TD_WALLTIME ) ; double net_lag = MAX_NET_LAG ; net_lag += time_now ( ) - ti -> len . t . timer_start ; if ( ti -> period == TT_TOTAL && time_in_byoyomi ( ti ) ) { ti -> period = TT_MOVE ; } if ( ti -> period == TT_MOVE ) { double period_len = ti -> len . t . byoyomi_time + ti -> len . t . main_time ; stop -> worst . time = period_len ; assert ( ti -> len . t . byoyomi_stones > 0 ) ; stop -> desired . time = period_len / ti -> len . t . byoyomi_stones ; if ( stop -> desired . time >= period_len - net_lag ) { double safe_margin = RESERVED_BYOYOMI_PERCENT * stop -> desired . time / 100 ; if ( safe_margin > net_lag ) net_lag = safe_margin ; } double worst_time = stop -> desired . time * MAX_BYOYOMI_TIME_RATIO ; if ( worst_time < stop -> worst . time ) stop -> worst . time = worst_time ; stop -> desired . time *= ( 2 - MAX_BYOYOMI_TIME_RATIO ) ; } else { assert ( ti -> period == TT_TOTAL ) ; assert ( ti -> len . t . main_time > 0 ) ; int moves_left = time_stop_set_remaining ( ti , b , net_lag , stop ) ; stop -> desired . time = stop -> worst . time / moves_left ; assert ( stop -> desired . time > 0 && stop -> worst . time > 0 ) ; assert ( stop -> desired . time <= stop -> worst . time + 0.001 ) ; time_stop_phase_adjust ( b , fuseki_end , yose_start , stop ) ; double worst_time = stop -> desired . time ; if ( ti -> len . t . byoyomi_time_max > ti -> len . t . byoyomi_stones_max ) { worst_time *= max_maintime_ratio ; } else { worst_time *= MAX_SUDDEN_DEATH_RATIO ; } if ( worst_time < stop -> worst . time ) stop -> worst . time = worst_time ; if ( stop -> desired . time > stop -> worst . time ) stop -> desired . time = stop -> worst . time ; } if ( DEBUGL ( 1 ) ) fprintf ( stderr , " \n " , stop -> desired . time , stop -> worst . time , ti -> dim , ti -> len . t . main_time , ti -> len . t . byoyomi_time , ti -> len . t . byoyomi_stones , ti -> len . t . byoyomi_periods , net_lag ) ; lag_adjust ( & stop -> desired . time , net_lag ) ; lag_adjust ( & stop -> worst . time , net_lag ) ; }
Pre-process time_info for search control and sets the desired stopping conditions.
Pre - process time_info for search control and sets the desired stopping conditions .
/* We must have _some_ limits by now, be it random default values! */ /* Special-case limit by number of simulations. */ /* We force worst == desired, so note that we will NOT loop
		 * until best == winner. */ /* Minimum net lag (seconds) to be reserved in the time for move. */ // TODO: keep statistics to get good estimate of lag not just current move /* Technically, we are still in main time, but we can
		 * effectively switch to byoyomi scheduling since we
		 * have less time available than one byoyomi move takes. */ /* We are in byoyomi, or almost! */ /* The period can still include some tiny remnant of main
		 * time if we are just switching to byoyomi. */ /* Use a larger safety margin if we risk losing on time on
		 * this move; it makes no sense to have 30s byoyomi and wait
		 * until 28s to play our move). */ /* Make recommended_old == average(recommended_new, max) */ /* We are in main time. */ /* Set worst.time to all available remaining time, to be spread
		 * over returned number of moves. */ /* Allocate even slice of the remaining time for next move. */ /* Furthermore, tweak the slice based on the game phase. */ /* Put final upper bound on maximal time spent on the move.
		 * Keep enough time for sudden death (or near SD) games. */ /* Account for lag. */