From b8f9968cbec092c39a26f2d7465f50e465ced51a Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Tue, 10 Aug 2010 23:02:34 +0200 Subject: [PATCH] Joseki: Encapsulate dictionary in struct joseki_dict --- joseki/base.c | 32 +++++++++++++++++++++++++------- joseki/base.h | 13 +++++++++++-- joseki/joseki.c | 17 +++++++++++------ playout/moggy.c | 2 +- uct/prior.c | 2 +- zzgo.c | 2 +- 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/joseki/base.c b/joseki/base.c index 75a03ce..a7f9c97 100644 --- a/joseki/base.c +++ b/joseki/base.c @@ -8,13 +8,23 @@ #include "joseki/base.h" -struct joseki_pattern joseki_pats[1 << joseki_hash_bits]; +struct joseki_dict *jdict; -void -joseki_load(void) +struct joseki_dict * +joseki_init(int bsize) +{ + struct joseki_dict *jd = calloc(1, sizeof(*jd)); + jd->bsize = bsize; + jd->patterns = calloc(1 << joseki_hash_bits, sizeof(jd->patterns[0])); + return jd; +} + +struct joseki_dict * +joseki_load(int bsize) { - FILE *f = fopen("pachijoseki.dat", "r"); - if (!f) return; + FILE *f = fopen("pachijoseki.dat", "r"); // XXX: size-dependent + if (!f) return NULL; + struct joseki_dict *jd = joseki_init(bsize); char linebuf[1024]; while (fgets(linebuf, 1024, f)) { @@ -30,13 +40,13 @@ joseki_load(void) *cs++ = 0; int count = atoi(cs); - coord_t **ccp = &joseki_pats[h].moves[color - 1]; + coord_t **ccp = &jd->patterns[h].moves[color - 1]; assert(!*ccp); *ccp = calloc2(count + 1, sizeof(coord_t)); coord_t *cc = *ccp; while (*line) { assert(cc - *ccp < count); - coord_t *c = str2coord(line, 21 /* XXX */); + coord_t *c = str2coord(line, bsize); *cc++ = *c; coord_done(c); line += strcspn(line, " "); @@ -46,4 +56,12 @@ joseki_load(void) } fclose(f); + return jd; +} + +void +joseki_done(struct joseki_dict *jd) +{ + free(jd->patterns); + free(jd); } diff --git a/joseki/base.h b/joseki/base.h index d6939a0..2eee3eb 100644 --- a/joseki/base.h +++ b/joseki/base.h @@ -9,10 +9,19 @@ struct joseki_pattern { coord_t *moves[2]; }; +/* The joseki dictionary for given board size. */ +struct joseki_dict { + int bsize; + #define joseki_hash_bits 20 // 8M w/ 32-bit pointers #define joseki_hash_mask ((1 << joseki_hash_bits) - 1) -extern struct joseki_pattern joseki_pats[]; + struct joseki_pattern *patterns; +}; + +extern struct joseki_dict *jdict; -void joseki_load(void); +struct joseki_dict *joseki_init(int bsize); +struct joseki_dict *joseki_load(int bsize); +void joseki_done(struct joseki_dict *); #endif diff --git a/joseki/joseki.c b/joseki/joseki.c index d9a0ce7..103713d 100644 --- a/joseki/joseki.c +++ b/joseki/joseki.c @@ -20,7 +20,7 @@ struct joseki_engine { }; /* We will record the joseki positions into incrementally-built - * joseki_pats[]. */ + * jdict->patterns[]. */ static char * @@ -31,6 +31,7 @@ joseki_play(struct engine *e, struct board *b, struct move *m) if (!b->moves) { /* New game, reset state. */ j->size = board_size(b); + assert(j->size == jdict->bsize); j->discard = false; for (int i = 0; i < 16; i++) { board_resize(j->b[i], j->size - 2); @@ -87,7 +88,7 @@ joseki_play(struct engine *e, struct board *b, struct move *m) if (i & HASH_OCOLOR) color = stone_other(color); - coord_t **ccp = &joseki_pats[j->b[i]->qhash[quadrant] & joseki_hash_mask].moves[color - 1]; + coord_t **ccp = &jdict->patterns[j->b[i]->qhash[quadrant] & joseki_hash_mask].moves[color - 1]; int count = 1; if (*ccp) { @@ -122,7 +123,7 @@ joseki_genmove(struct engine *e, struct board *b, struct time_info *ti, enum sto } void -joseki_done(struct engine *e) +engine_joseki_done(struct engine *e) { struct joseki_engine *j = e->data; struct board *b = board_init(); @@ -132,10 +133,10 @@ joseki_done(struct engine *e) for (hash_t i = 0; i < 1 << joseki_hash_bits; i++) { for (int j = 0; j < 2; j++) { static const char cs[] = "bw"; - if (!joseki_pats[i].moves[j]) + if (!jdict->patterns[i].moves[j]) continue; printf("%" PRIhash " %c", i, cs[j]); - coord_t *cc = joseki_pats[i].moves[j]; + coord_t *cc = jdict->patterns[i].moves[j]; int count = 0; while (!is_pass(*cc)) { printf(" %s", coord2sstr(*cc, b)); @@ -183,6 +184,10 @@ joseki_state_init(char *arg) } } + if (jdict) + joseki_done(jdict); + jdict = joseki_init(19 + 2); // XXX + return j; } @@ -195,7 +200,7 @@ engine_joseki_init(char *arg, struct board *b) e->comment = "You cannot play Pachi with this engine, it is intended for special development use - scanning of joseki sequences fed to it within the GTP stream."; e->genmove = joseki_genmove; e->notify_play = joseki_play; - e->done = joseki_done; + e->done = engine_joseki_done; e->data = j; // clear_board does not concern us, we like to work over many games e->keep_on_clear = true; diff --git a/playout/moggy.c b/playout/moggy.c index 3a766aa..f45e179 100644 --- a/playout/moggy.c +++ b/playout/moggy.c @@ -465,7 +465,7 @@ joseki_check(struct playout_policy *p, struct board *b, enum stone to_play, stru for (int i = 0; i < 4; i++) { hash_t h = b->qhash[i] & joseki_hash_mask; - coord_t *cc = joseki_pats[h].moves[to_play]; + coord_t *cc = jdict->patterns[h].moves[to_play]; if (!cc) continue; for (; !is_pass(*cc); cc++) { if (coord_quadrant(*cc, b) != i) diff --git a/uct/prior.c b/uct/prior.c index 4e1032f..2ff1f8a 100644 --- a/uct/prior.c +++ b/uct/prior.c @@ -129,7 +129,7 @@ uct_prior_joseki(struct uct *u, struct tree_node *node, struct prior_map *map) /* Q_{joseki} */ for (int i = 0; i < 4; i++) { hash_t h = map->b->qhash[i] & joseki_hash_mask; - coord_t *cc = joseki_pats[h].moves[map->to_play - 1]; + coord_t *cc = jdict->patterns[h].moves[map->to_play - 1]; if (!cc) continue; for (; !is_pass(*cc); cc++) { if (coord_quadrant(*cc, map->b) != i) diff --git a/zzgo.c b/zzgo.c index 0ff1e45..3eaf3b3 100644 --- a/zzgo.c +++ b/zzgo.c @@ -153,7 +153,7 @@ int main(int argc, char *argv[]) if (DEBUGL(0)) fprintf(stderr, "Random seed: %d\n", seed); - joseki_load(); + jdict = joseki_load(19 + 2); // XXX struct board *b = board_init(); struct time_info ti[S_MAX]; -- 2.11.4.GIT