From 6ddb91fdef57564cd44638265876c815c000d4da Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sun, 8 Jan 2012 20:43:12 +0100 Subject: [PATCH] UCT pattern prior: Implement exceedingly naive pattern-based prior --- uct/internal.h | 12 ++++++++++++ uct/prior.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/uct/internal.h b/uct/internal.h index c1f6880..516ef1d 100644 --- a/uct/internal.h +++ b/uct/internal.h @@ -6,6 +6,9 @@ #include "debug.h" #include "move.h" #include "ownermap.h" +#include "pattern.h" +#include "patternsp.h" +#include "patternprob.h" #include "playout.h" #include "stats.h" @@ -15,6 +18,7 @@ struct uct_policy; struct uct_prior; struct uct_dynkomi; struct uct_pluginset; +struct uct_pattern; struct joseki_dict; /* How big proportion of ownermap counts must be of one color to consider @@ -23,6 +27,13 @@ struct joseki_dict; /* How many games to consider at minimum before judging groups. */ #define GJ_MINGAMES 500 +/* TODO: Generalize this for other engines too. */ +struct uct_pattern { + struct pattern_config pc; + pattern_spec ps; + struct pattern_pdict *pd; +}; + /* Internal engine state. */ struct uct { int debug_level; @@ -93,6 +104,7 @@ struct uct { struct uct_prior *prior; struct uct_pluginset *plugins; struct joseki_dict *jdict; + struct uct_pattern pat; /* Used within frame of single genmove. */ struct board_ownermap ownermap; diff --git a/uct/prior.c b/uct/prior.c index ca4f236..62d32f5 100644 --- a/uct/prior.c +++ b/uct/prior.c @@ -26,7 +26,7 @@ struct uct_prior { * 50 playouts per source; in practice, esp. with RAVE, about 6 * playouts per source seems best. */ int eqex; - int even_eqex, policy_eqex, b19_eqex, eye_eqex, ko_eqex, plugin_eqex, joseki_eqex; + int even_eqex, policy_eqex, b19_eqex, eye_eqex, ko_eqex, plugin_eqex, joseki_eqex, pattern_eqex; int cfgdn; int *cfgd_eqex; }; @@ -142,6 +142,26 @@ uct_prior_joseki(struct uct *u, struct tree_node *node, struct prior_map *map) } void +uct_prior_pattern(struct uct *u, struct tree_node *node, struct prior_map *map) +{ + /* Q_{pattern} */ + if (!u->pat.pd) + return; + + struct board *b = map->b; + struct pattern pats[b->flen]; + floating_t probs[b->flen]; + pattern_rate_moves(&u->pat.pc, &u->pat.ps, u->pat.pd, b, map->to_play, pats, probs); + + for (int f = 0; f < b->flen; f++) { + if (isnan(probs[f])) + continue; + assert(!is_pass(b->f[f])); + add_prior_value(map, b->f[f], 1.0, sqrt(probs[f]) * u->prior->pattern_eqex); + } +} + +void uct_prior(struct uct *u, struct tree_node *node, struct prior_map *map) { if (u->prior->even_eqex) @@ -158,6 +178,8 @@ uct_prior(struct uct *u, struct tree_node *node, struct prior_map *map) uct_prior_cfgd(u, node, map); if (u->prior->joseki_eqex) uct_prior_joseki(u, node, map); + if (u->prior->pattern_eqex) + uct_prior_pattern(u, node, map); if (u->prior->plugin_eqex) plugin_prior(u->plugins, node, map, u->prior->plugin_eqex); } @@ -222,6 +244,12 @@ uct_prior_init(char *arg, struct board *b, struct uct *u) p->eye_eqex = atoi(optval); } else if (!strcasecmp(optname, "ko") && optval) { p->ko_eqex = atoi(optval); + } else if (!strcasecmp(optname, "pattern") && optval) { + /* Pattern-based prior eqex. */ + /* Note that this prior is still going to be + * used only if you have downloaded or + * generated the pattern files! */ + p->pattern_eqex = atoi(optval); } else if (!strcasecmp(optname, "plugin") && optval) { /* Unlike others, this is just a *recommendation*. */ p->plugin_eqex = atoi(optval); @@ -238,6 +266,7 @@ uct_prior_init(char *arg, struct board *b, struct uct *u) if (p->eye_eqex < 0) p->eye_eqex = p->eqex * -p->eye_eqex / 100; if (p->ko_eqex < 0) p->ko_eqex = p->eqex * -p->ko_eqex / 100; if (p->joseki_eqex < 0) p->joseki_eqex = p->eqex * -p->joseki_eqex / 100; + if (p->pattern_eqex < 0) p->pattern_eqex = p->eqex * -p->pattern_eqex / 100; if (p->plugin_eqex < 0) p->plugin_eqex = p->eqex * -p->plugin_eqex / 100; if (p->cfgdn < 0) { @@ -252,6 +281,15 @@ uct_prior_init(char *arg, struct board *b, struct uct *u) exit(1); } + if (p->pattern_eqex) { + u->pat.pc = DEFAULT_PATTERN_CONFIG; + u->pat.pc.spat_dict = spatial_dict_init(false, false); + memcpy(&u->pat.ps, PATTERN_SPEC_MATCH_DEFAULT, sizeof(pattern_spec)); + if (u->pat.pc.spat_dict) { + u->pat.pd = pattern_pdict_init(NULL, &u->pat.pc); + } + } + return p; } -- 2.11.4.GIT