From 820d7de221489f2d4277c6a1c99f4682dda620c1 Mon Sep 17 00:00:00 2001 From: Jean-loup Gailly Date: Sat, 25 Dec 2010 12:57:13 +0100 Subject: [PATCH] UCT engine: Allow spending more time on a single move --- distributed/distributed.c | 3 ++- montecarlo/montecarlo.c | 2 +- timeinfo.c | 20 ++++++++++---------- timeinfo.h | 3 ++- uct/internal.h | 1 + uct/search.c | 2 +- uct/uct.c | 5 +++++ 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/distributed/distributed.c b/distributed/distributed.c index 50ed721..ea9066b 100644 --- a/distributed/distributed.c +++ b/distributed/distributed.c @@ -266,6 +266,7 @@ genmoves_args(char *args, enum stone color, int played, /* Time control is mostly done by the slaves, so we use default values here. */ #define FUSEKI_END 20 #define YOSE_START 40 +#define MAX_MAINTIME_RATIO 3.0 /* In the ascii reply to genmoves, each slave sends absolute counts * including contributions from other slaves. For human display @@ -290,7 +291,7 @@ distributed_genmove(struct engine *e, struct board *b, struct time_info *ti, if (ti->period == TT_NULL) *ti = default_ti; struct time_stop stop; - time_stop_conditions(ti, b, FUSEKI_END, YOSE_START, &stop); + time_stop_conditions(ti, b, FUSEKI_END, YOSE_START, MAX_MAINTIME_RATIO, &stop); struct time_info saved_ti = *ti; /* Combined move stats from all slaves, only for children diff --git a/montecarlo/montecarlo.c b/montecarlo/montecarlo.c index 50df996..bdda4a4 100644 --- a/montecarlo/montecarlo.c +++ b/montecarlo/montecarlo.c @@ -90,7 +90,7 @@ montecarlo_genmove(struct engine *e, struct board *b, struct time_info *ti, enum ti->len.games = MC_GAMES; } struct time_stop stop; - time_stop_conditions(ti, b, 20, 40, &stop); + time_stop_conditions(ti, b, 20, 40, 3.0, &stop); /* resign when the hope for win vanishes */ coord_t top_coord = resign; diff --git a/timeinfo.c b/timeinfo.c index c791c39..6c4542b 100644 --- a/timeinfo.c +++ b/timeinfo.c @@ -24,11 +24,10 @@ /* Reserve 15% of byoyomi time as safety margin if risk of losing on time */ #define RESERVED_BYOYOMI_PERCENT 15 -/* For safety, use at most 3 times the desired time on a single move - * in main time, 2 times in sudden death and 1.1 times in byoyomi. */ -#define MAX_MAIN_TIME_EXTENSION 3.0 -#define MAX_SUDDEN_DEATH_EXTENSION 2.0 -#define MAX_BYOYOMI_TIME_EXTENSION 1.1 +/* For safety, use at most 2 times the desired time on a single move + * in sudden death and 1.1 times in byoyomi. */ +#define MAX_SUDDEN_DEATH_RATIO 2.0 +#define MAX_BYOYOMI_TIME_RATIO 1.1 bool time_parse(struct time_info *ti, char *s) @@ -334,7 +333,8 @@ lag_adjust(double *time, double net_lag) /* 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, struct time_stop *stop) +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) { /* We must have _some_ limits by now, be it random default values! */ assert(ti->period != TT_NULL); @@ -391,10 +391,10 @@ time_stop_conditions(struct time_info *ti, struct board *b, int fuseki_end, int } /* Make recommended_old == average(recommended_new, max) */ - double worst_time = stop->desired.time * MAX_BYOYOMI_TIME_EXTENSION; + 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_EXTENSION); + stop->desired.time *= (2 - MAX_BYOYOMI_TIME_RATIO); } else { assert(ti->period == TT_TOTAL); /* We are in main time. */ @@ -416,9 +416,9 @@ time_stop_conditions(struct time_info *ti, struct board *b, int fuseki_end, int * Keep enough time for sudden death (or near SD) games. */ double worst_time = stop->desired.time; if (ti->len.t.byoyomi_time_max > ti->len.t.byoyomi_stones_max) { - worst_time *= MAX_MAIN_TIME_EXTENSION; + worst_time *= max_maintime_ratio; } else { - worst_time *= MAX_SUDDEN_DEATH_EXTENSION; + worst_time *= MAX_SUDDEN_DEATH_RATIO; } if (worst_time < stop->worst.time) stop->worst.time = worst_time; diff --git a/timeinfo.h b/timeinfo.h index c8f7bc5..c02ab85 100644 --- a/timeinfo.h +++ b/timeinfo.h @@ -110,6 +110,7 @@ struct time_stop { }; /* fuseki_end and yose_start are percentages of expected game length. */ -void time_stop_conditions(struct time_info *ti, struct board *b, int fuseki_end, int yose_start, struct time_stop *stop); +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); #endif diff --git a/uct/internal.h b/uct/internal.h index 84d8bc7..64614a4 100644 --- a/uct/internal.h +++ b/uct/internal.h @@ -29,6 +29,7 @@ struct uct { int games, gamelen; floating_t resign_threshold, sure_win_threshold; double best2_ratio, bestr_ratio; + floating_t max_maintime_ratio; bool pass_all_alive; bool territory_scoring; int expand_p; diff --git a/uct/search.c b/uct/search.c index 461e175..f974494 100644 --- a/uct/search.c +++ b/uct/search.c @@ -192,7 +192,7 @@ uct_search_start(struct uct *u, struct board *b, enum stone color, if (ti) { if (ti->period == TT_NULL) *ti = default_ti; - time_stop_conditions(ti, b, u->fuseki_end, u->yose_start, &s->stop); + time_stop_conditions(ti, b, u->fuseki_end, u->yose_start, u->max_maintime_ratio, &s->stop); } /* Fire up the tree search thread manager, which will in turn diff --git a/uct/uct.c b/uct/uct.c index e435525..b37a749 100644 --- a/uct/uct.c +++ b/uct/uct.c @@ -546,6 +546,7 @@ uct_state_init(char *arg, struct board *b) // 2.5 is clearly too much, but seems to compensate well for overly stern time allocations. // TODO: Further tuning and experiments with better time allocation schemes. u->best2_ratio = 2.5; + u->max_maintime_ratio = 3.0; u->val_scale = 0.04; u->val_points = 40; u->dynkomi_interval = 1000; @@ -781,6 +782,10 @@ uct_state_init(char *arg, struct board *b) * best,best_best_child values delta * is more than bestr_ratio. */ u->bestr_ratio = atof(optval); + } else if (!strcasecmp(optname, "max_maintime_ratio") && optval) { + /* If set and while not in byoyomi, prolong simulating no more than + * max_maintime_ratio times the normal desired thinking time. */ + u->max_maintime_ratio = atof(optval); } else if (!strcasecmp(optname, "fuseki_end") && optval) { /* At the very beginning it's not worth thinking * too long because the playout evaluations are -- 2.11.4.GIT