From a7a923896cddc621df123de6c40bbba5ad0bcd1d Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sat, 9 Mar 2013 23:05:17 +0100 Subject: [PATCH] Keep only pure libmap stuff in libmap.*, move goal tracking to tactics/goals.* Stuff in tactics/goals.* still uses libmap_ prefix. To be cleaned up. --- board.c | 2 +- libmap.c | 275 ++++--------------------------- libmap.h | 384 +++++--------------------------------------- playout.c | 2 +- playout/moggy.c | 2 +- tactics/2lib.c | 2 +- tactics/2lib.h | 2 +- tactics/Makefile | 2 +- libmap.c => tactics/goals.c | 25 +-- libmap.h => tactics/goals.h | 40 +---- tactics/nlib.c | 2 +- tactics/nlib.h | 1 + uct/policy/ucb1amaf.c | 2 +- uct/tree.c | 2 +- uct/uct.c | 2 +- 15 files changed, 94 insertions(+), 651 deletions(-) rewrite libmap.c (89%) rewrite libmap.h (94%) copy libmap.c => tactics/goals.c (91%) copy libmap.h => tactics/goals.h (91%) diff --git a/board.c b/board.c index 2788ae8..357a993 100644 --- a/board.c +++ b/board.c @@ -8,7 +8,7 @@ #include "board.h" #include "debug.h" #include "fbook.h" -#include "libmap.h" +#include "tactics/goals.h" #include "mq.h" #include "random.h" diff --git a/libmap.c b/libmap.c dissimilarity index 89% index 49a6f4c..969a9a8 100644 --- a/libmap.c +++ b/libmap.c @@ -1,241 +1,34 @@ -#include -#include -#include -#include - -#include "board.h" -#include "debug.h" -#include "libmap.h" -#include "move.h" -#include "tactics/util.h" - - -hash_t -group_to_libmap(struct board *b, group_t group) -{ - hash_t h = 0; -#define hbits (sizeof(hash_t)*CHAR_BIT) - - enum stone color = board_at(b, group); - struct group *gi = &board_group_info(b, group); - int libs = gi->libs < GROUP_REFILL_LIBS ? gi->libs : GROUP_REFILL_LIBS; - - for (int i = 0; i < libs; i++) { - hash_t hlib = hash_at(b, gi->lib[i], color); - /* Rotate the hash based on prospects of the liberty. */ - int p = immediate_liberty_count(b, gi->lib[i]) + - 4 * neighbor_count_at(b, gi->lib[i], color); - hlib = (hlib << p) | ((hlib >> (hbits - p)) & ((1<b = b; - b->libmap = lm; - lm->refcount = 1; - return lm; -} - -void -libmap_put(struct libmap_hash *lm) -{ - if (__sync_sub_and_fetch(&lm->refcount, 1) > 0) - return; - free(lm); -} - -void -libmap_queue_process(struct libmap_hash *lm, struct libmap_mq *lmqueue, struct board *b, enum stone winner) -{ - assert(lmqueue->mq.moves <= MQL); - for (unsigned int i = 0; i < lmqueue->mq.moves; i++) { - struct libmap_group *g = &lmqueue->group[i]; - struct move m = { .coord = lmqueue->mq.move[i], .color = lmqueue->color[i] }; - floating_t val; - if (libmap_config.eval == LME_LOCAL || libmap_config.eval == LME_LVALUE) { - val = board_local_value(libmap_config.eval == LME_LVALUE, b, g->group, g->goal); - - } else { assert(libmap_config.eval == LME_GLOBAL); - val = winner == g->goal ? 1.0 : 0.0; - } - libmap_add_result(lm, g->hash, m, val, 1); - } - lmqueue->mq.moves = 0; -} - -void -libmap_add_result(struct libmap_hash *lm, hash_t hash, struct move move, - floating_t result, int playouts) -{ - /* If hash line is full, replacement strategy is naive - pick the - * move with minimum move[0].stats.playouts; resolve each tie - * randomly. */ - unsigned int min_playouts = INT_MAX; hash_t min_hash = hash; - hash_t ih; - for (ih = hash; lm->hash[ih & libmap_hash_mask].hash != hash; ih++) { - // fprintf(stderr, "%"PRIhash": check %"PRIhash" (%d)\n", hash & libmap_hash_mask, ih & libmap_hash_mask, lm->hash[ih & libmap_hash_mask].moves); - if (lm->hash[ih & libmap_hash_mask].moves == 0) { - lm->hash[ih & libmap_hash_mask].hash = hash; - break; - } - if (ih >= hash + libmap_hash_maxline) { - /* Snatch the least used bucket. */ - ih = min_hash; - // fprintf(stderr, "clear %"PRIhash"\n", ih & libmap_hash_mask); - memset(&lm->hash[ih & libmap_hash_mask], 0, sizeof(lm->hash[0])); - lm->hash[ih & libmap_hash_mask].hash = hash; - break; - } - - /* Keep track of least used bucket. */ - assert(lm->hash[ih & libmap_hash_mask].moves > 0); - unsigned int hp = lm->hash[ih & libmap_hash_mask].move[0].stats.playouts; - if (hp < min_playouts || (hp == min_playouts && fast_random(2))) { - min_playouts = hp; - min_hash = ih; - } - } - - // fprintf(stderr, "%"PRIhash": use %"PRIhash" (%d)\n", hash & libmap_hash_mask, ih & libmap_hash_mask, lm->hash[ih & libmap_hash_mask].moves); - struct libmap_context *lc = &lm->hash[ih & libmap_hash_mask]; - lc->visits++; - - for (int i = 0; i < lc->moves; i++) { - if (lc->move[i].move.coord == move.coord - && lc->move[i].move.color == move.color) { - stats_add_result(&lc->move[i].stats, result, playouts); - return; - } - } - - int moves = lc->moves; // to preserve atomicity - if (moves >= GROUP_REFILL_LIBS) { - if (DEBUGL(5)) - fprintf(stderr, "(%s) too many libs\n", coord2sstr(move.coord, lm->b)); - return; - } - lc->move[moves].move = move; - stats_add_result(&lc->move[moves].stats, result, playouts); - lc->moves = ++moves; -} - -struct move_stats -libmap_board_move_stats(struct libmap_hash *lm, struct board *b, struct move move) -{ - struct move_stats tot = { .playouts = 0, .value = 0 }; - if (is_pass(move.coord)) - return tot; - assert(board_at(b, move.coord) != S_OFFBOARD); - - neighboring_groups_list(b, board_at(b, c) == S_BLACK || board_at(b, c) == S_WHITE, - move.coord, groups, groups_n, groupsbycolor_xxunused); - for (int i = 0; i < groups_n; i++) { - hash_t hash = group_to_libmap(b, groups[i]); - struct move_stats *lp = libmap_move_stats(b->libmap, hash, move); - if (!lp) continue; - stats_merge(&tot, lp); - } - - return tot; -} +#include +#include +#include +#include + +#include "board.h" +#include "debug.h" +#include "libmap.h" +#include "move.h" +#include "tactics/util.h" + + +hash_t +group_to_libmap(struct board *b, group_t group) +{ + hash_t h = 0; +#define hbits (sizeof(hash_t)*CHAR_BIT) + + enum stone color = board_at(b, group); + struct group *gi = &board_group_info(b, group); + int libs = gi->libs < GROUP_REFILL_LIBS ? gi->libs : GROUP_REFILL_LIBS; + + for (int i = 0; i < libs; i++) { + hash_t hlib = hash_at(b, gi->lib[i], color); + /* Rotate the hash based on prospects of the liberty. */ + int p = immediate_liberty_count(b, gi->lib[i]) + + 4 * neighbor_count_at(b, gi->lib[i], color); + hlib = (hlib << p) | ((hlib >> (hbits - p)) & ((1< -#include - -#include "board.h" -#include "mq.h" -#include "stats.h" - -#define LM_DEBUG if (0) - -hash_t group_to_libmap(struct board *b, group_t group); - - -/* Setup of everything libmap-related. */ - -extern struct libmap_config { - enum { - LMP_THRESHOLD, - LMP_UCB, - } pick_mode; - - /* LMP_THRESHOLD: */ - /* Preference for moves of tactical rating over this threshold - * (...or unrated moves). */ - floating_t pick_threshold; - /* In given percentage of cases, pick move regardless of its - * tactical rating.*/ - int pick_epsilon; - /* Whether to rather skip this heuristic altogether than play - * badly performing move. */ - bool avoid_bad; - - /* LMP_UCB: */ - /* Exploration coefficient for the bandit. */ - floating_t explore_p; - /* Default prior for considered moves. */ - struct move_stats prior, tenuki_prior; - - /* Whether to merge records for the same move taking care - * of different groups within the move queue. */ - bool mq_merge_groups; - /* When checking move X, defending group A by counter-attacking - * group B, whether to use A, B or A^B as liberty map. */ - enum { - LMC_DEFENSE = 1, - LMC_ATTACK = 2, - LMC_DEFENSE_ATTACK = 4, - } counterattack; - /* Whether to evaluate based on local or global result. */ - enum { - LME_LOCAL, - LME_LVALUE, - LME_GLOBAL, - } eval; - /* Whether to also try and track tenuki moves. */ - bool tenuki; -} libmap_config; - -void libmap_setup(char *arg); - - -/* Our own version of move_queue, but including liberty maps of moves. */ -/* The user will usually first create a queue of tactical goals and pick - * (using libmap_mq functions below), then add that one to libmap_hash's - * global move queue, processed at the end of the whole playout. */ - -struct libmap_group { - /* Group-relative tactical description of a move. */ - group_t group; - hash_t hash; - enum stone goal; -}; - -struct libmap_mq { - struct move_queue mq; - enum stone color[MQL]; // complements mq.move - struct libmap_group group[MQL]; -}; - -/* libmap_mq_pick() would be simple fast_random(mq.moves), but c.f. - * libmap_queue_mqpick() below. */ -static void libmap_mq_add(struct libmap_mq *q, struct move m, unsigned char tag, struct libmap_group group); -static void libmap_mq_nodup(struct libmap_mq *q); -static void libmap_mq_print(struct libmap_mq *q, struct board *b, char *label); - - -/* Tactical application - hash structure storing info about move effectivity. */ - -struct libmap_move { - struct move move; - struct move_stats stats; -}; - -struct libmap_context { - hash_t hash; - int visits; - /* We add moves in multiple threads. But at most, on conflict we will - * end up with tiny amount of misappropriated playouts. */ - int moves; - struct libmap_move move[GROUP_REFILL_LIBS]; -}; - -struct libmap_hash { - struct board *b; - /* Multiple board instances may share the same libmap hash; - * on board_copy(), libmap is shared by default, so that all - * playouts reuse libmap of the master board. refcount keeps - * track of all the libmap uses in multi-thread environment. */ - int refcount; - - /* Stored statistics. */ - /* We store statistics in a hash table without separated chains; - * if bucket is occupied, we look into the following ones, - * allowing up to libmap_hash_maxline subsequent checks. */ - /* XXX: We mishandle hashes >= UINT64_MAX - libmap_hash_maxline. */ -#define libmap_hash_bits 19 -#define libmap_hash_size (1 << libmap_hash_bits) -#define libmap_hash_mask (libmap_hash_size - 1) -#define libmap_hash_maxline 32 - struct libmap_context hash[libmap_hash_size]; -}; - -/* Get a new libmap. */ -struct libmap_hash *libmap_init(struct board *b); -/* Release libmap. Based on refcount, this will free it. */ -void libmap_put(struct libmap_hash *lm); - -/* Pick a move from @q, enqueue it in lmqueue and return its coordinate. */ -static coord_t libmap_queue_mqpick(struct libmap_hash *lm, struct libmap_mq *lmqueue, struct libmap_mq *q); -/* Record queued moves in the hashtable based on final position of b and winner's color. */ -void libmap_queue_process(struct libmap_hash *lm, struct libmap_mq *lmqueue, struct board *b, enum stone winner); -/* Add a result to the hashed statistics. */ -void libmap_add_result(struct libmap_hash *lm, hash_t hash, struct move move, floating_t result, int playouts); -/* Get libmap context of a given group. */ -static struct libmap_context *libmap_group_context(struct libmap_hash *lm, hash_t hash); -/* Get statistics of particular move in given libmap structure. */ -static struct move_stats *libmap_move_stats(struct libmap_hash *lm, hash_t hash, struct move move); -/* Get statistics of particular move on given board. */ -/* (Note that this is inherently imperfect as it does not take into account - * counter-atari moves.) */ -struct move_stats libmap_board_move_stats(struct libmap_hash *lm, struct board *b, struct move move); - - - -static inline void -libmap_mq_add(struct libmap_mq *q, struct move m, unsigned char tag, struct libmap_group group) -{ - assert(q->mq.moves < MQL); - q->mq.tag[q->mq.moves] = tag; - q->mq.move[q->mq.moves] = m.coord; - q->color[q->mq.moves] = m.color; - q->group[q->mq.moves] = group; - q->mq.moves++; -} - -static inline void -libmap_mq_nodup(struct libmap_mq *q) -{ - for (unsigned int i = 1; i < 4; i++) { - if (q->mq.moves <= i) - return; - if (q->mq.move[q->mq.moves - 1 - i] == q->mq.move[q->mq.moves - 1] - && (libmap_config.mq_merge_groups - || (q->group[q->mq.moves - 1 - i].group == q->group[q->mq.moves - 1].group - && q->group[q->mq.moves - 1 - i].hash == q->group[q->mq.moves - 1].hash - && q->group[q->mq.moves - 1 - i].goal == q->group[q->mq.moves - 1].goal))) { - q->mq.tag[q->mq.moves - 1 - i] |= q->mq.tag[q->mq.moves - 1]; - assert(q->color[q->mq.moves - 1 - i] == q->color[q->mq.moves - 1]); - q->mq.moves--; - return; - } - } -} - -static inline void -libmap_mq_print(struct libmap_mq *q, struct board *b, char *label) -{ - fprintf(stderr, "%s candidate moves: ", label); - for (unsigned int i = 0; i < q->mq.moves; i++) { - fprintf(stderr, "%s[%c:%s %"PRIhash"]", coord2sstr(q->mq.move[i], b), - /* attacker / defender */ - board_at(b, q->group[i].group) == q->group[i].goal ? 'd' : 'a', - coord2sstr(q->group[i].group, b), - q->group[i].hash & libmap_hash_mask); - struct move m = { .coord = q->mq.move[i], .color = q->color[i] }; - struct move_stats *ms = libmap_move_stats(b->libmap, q->group[i].hash, m); - if (ms) { - fprintf(stderr, "(%.3f/%d)", ms->value, ms->playouts); - } - fputc(' ', stderr); - } - fputc('\n', stderr); -} - - -static inline int -libmap_queue_mqpick_threshold(struct libmap_hash *lm, struct libmap_mq *q) -{ - /* Pick random move, up to a simple check - if a move has tactical - * rating lower than threshold, prefer another. */ - int p = fast_random(q->mq.moves); - if (fast_random(100) < libmap_config.pick_epsilon) - return p; - - bool found = false; - unsigned int pp = p; - do { - int pm = p % q->mq.moves; - struct move m = { .coord = q->mq.move[pm], .color = q->color[pm] }; - struct move_stats *ms = libmap_move_stats(lm, q->group[pm].hash, m); - if (!ms || ms->value >= libmap_config.pick_threshold) { - found = true; - break; - } - } while (++p % q->mq.moves < pp); - p %= q->mq.moves; - if (!found && libmap_config.avoid_bad) - return -1; - return p; -} - -static inline int -libmap_queue_mqpick_ucb(struct libmap_hash *lm, struct libmap_mq *q) -{ - int best_pa[BOARD_MAX_MOVES + 1], best_pn = 1; - floating_t best_urgency = -9999; - LM_DEBUG fprintf(stderr, "\tBandit: "); - - for (unsigned int p = 0; p < q->mq.moves; p++) { - struct libmap_context *lc = libmap_group_context(lm, q->group[p].hash); - - /* TODO: Consider all moves of this group, - * not just mq contents. */ - struct move m = { .coord = q->mq.move[p], .color = q->color[p] }; - struct move_stats s = !is_pass(m.coord) ? libmap_config.prior : libmap_config.tenuki_prior; - int group_visits = (lc ? lc->visits : 0) + s.playouts; - struct move_stats *ms = libmap_move_stats(lm, q->group[p].hash, m); - if (ms) stats_merge(&s, ms); - - floating_t urgency = s.value + libmap_config.explore_p * sqrt(log(group_visits) / s.playouts); - LM_DEBUG fprintf(stderr, "%s[%.3f=%.3fx(%d/%d)] ", coord2sstr(m.coord, lm->b), urgency, s.value, group_visits, s.playouts); - if (urgency > best_urgency) { - best_pn = 1; - best_pa[0] = (int) p; - best_urgency = urgency; - - } else if (urgency == best_urgency) { - best_pa[best_pn++] = (int) p; - } - } - - int best_p = best_pa[fast_random(best_pn)]; - assert(best_p >= 0); - LM_DEBUG fprintf(stderr, "\t=[%d]> %s\n", best_pn, coord2sstr(q->mq.move[best_p], lm->b)); - return best_p; -} - -static inline coord_t -libmap_queue_mqpick(struct libmap_hash *lm, struct libmap_mq *lmqueue, struct libmap_mq *q) -{ - if (!q->mq.moves) - return pass; // nothing to do - - /* Create a list of groups involved in the MQ. */ - struct libmap_group *groups[MQL]; - unsigned int groups_n = 0; - if (libmap_config.tenuki) { - for (unsigned int i = 0; i < q->mq.moves; i++) { - for (unsigned int j = 0; j < groups_n; j++) - if (q->group[i].hash == groups[j]->hash) - goto g_next_move; - groups[groups_n++] = &q->group[i]; -g_next_move:; - } - } - - /* Add tenuki move for each libmap group to the list of candidates. */ - /* XXX: Can the color vary within the queue? */ - if (libmap_config.tenuki) { - struct move tenuki = { .coord = pass, .color = q->color[0] }; - for (unsigned int i = 0; i < groups_n; i++) - libmap_mq_add(q, tenuki, 0 /* XXX */, *groups[i]); - } - - unsigned int p = 0; - if (q->mq.moves > 1) { - if (lm) { - switch (libmap_config.pick_mode) { - case LMP_THRESHOLD: - p = libmap_queue_mqpick_threshold(lm, q); - break; - case LMP_UCB: - p = libmap_queue_mqpick_ucb(lm, q); - break; - } - } else { - p = fast_random(q->mq.moves); - } - } - if (p < 0) - return pass; - - if (lm) { - struct move m = { .coord = q->mq.move[p], .color = q->color[p] }; - libmap_mq_add(lmqueue, m, q->mq.tag[p], q->group[p]); - } - - return q->mq.move[p]; -} - -static inline struct libmap_context * -libmap_group_context(struct libmap_hash *lm, hash_t hash) -{ - hash_t ih; - for (ih = hash; lm->hash[ih & libmap_hash_mask].hash != hash; ih++) { - if (lm->hash[ih & libmap_hash_mask].moves == 0) - return NULL; - if (ih >= hash + libmap_hash_maxline) - return NULL; - } - return &lm->hash[ih & libmap_hash_mask]; -} - -static inline struct move_stats * -libmap_move_stats(struct libmap_hash *lm, hash_t hash, struct move move) -{ - struct libmap_context *lc = libmap_group_context(lm, hash); - if (!lc) return NULL; - for (int i = 0; i < lc->moves; i++) { - if (lc->move[i].move.coord == move.coord - && lc->move[i].move.color == move.color) - return &lc->move[i].stats; - } - return NULL; -} - -#endif +#ifndef PACHI_LIBMAP_H +#define PACHI_LIBMAP_H + +/* "Liberty map" - description of a particular liberty structure of a group. + * The idea is that we can use this as a hash index to track local tactical + * effectivity of various moves within the particular liberty structure + * context. */ + +#include +#include + +#include "board.h" +#include "mq.h" +#include "stats.h" + +#define LM_DEBUG if (0) + + +/* Computation and representation of the libmap hash. */ + +hash_t group_to_libmap(struct board *b, group_t group); + + +/* Set of moves ("libmap context") grouped by libmap, with some statistics. */ +/* Hash structure storing info about move effectivity. */ + +struct libmap_move { + struct move move; + struct move_stats stats; +}; + +struct libmap_context { + hash_t hash; + int visits; + /* We add moves in multiple threads. But at most, on conflict we will + * end up with tiny amount of misappropriated playouts. */ + int moves; + struct libmap_move move[GROUP_REFILL_LIBS]; +}; + +#endif diff --git a/playout.c b/playout.c index 96544b0..c17473b 100644 --- a/playout.c +++ b/playout.c @@ -8,10 +8,10 @@ #include "board.h" #include "debug.h" #include "engine.h" -#include "libmap.h" #include "move.h" #include "ownermap.h" #include "playout.h" +#include "tactics/goals.h" /* Whether to set global debug level to the same as the playout * has, in case it is different. This can make sure e.g. tactical diff --git a/playout/moggy.c b/playout/moggy.c index c3a8357..48b0732 100644 --- a/playout/moggy.c +++ b/playout/moggy.c @@ -10,7 +10,6 @@ #include "board.h" #include "debug.h" #include "joseki/base.h" -#include "libmap.h" #include "mq.h" #include "pattern3.h" #include "playout.h" @@ -22,6 +21,7 @@ #include "tactics/ladder.h" #include "tactics/nakade.h" #include "tactics/selfatari.h" +#include "tactics/goals.h" #include "uct/prior.h" #define PLDEBUGL(n) DEBUGL_(p->debug_level, n) diff --git a/tactics/2lib.c b/tactics/2lib.c index 6826137..619d646 100644 --- a/tactics/2lib.c +++ b/tactics/2lib.c @@ -5,10 +5,10 @@ #define DEBUG #include "board.h" #include "debug.h" -#include "libmap.h" #include "mq.h" #include "tactics/2lib.h" #include "tactics/selfatari.h" +#include "tactics/goals.h" /* Whether to avoid capturing/atariing doomed groups (this is big diff --git a/tactics/2lib.h b/tactics/2lib.h index 511d499..3d756a3 100644 --- a/tactics/2lib.h +++ b/tactics/2lib.h @@ -5,7 +5,7 @@ * preventing atari). */ #include "board.h" -#include "libmap.h" +#include "tactics/goals.h" void can_atari_group(struct board *b, group_t group, enum stone owner, enum stone to_play, struct libmap_mq *q, int tag, struct libmap_group lmg, hash_t ca_hash, bool use_def_no_hopeless); void group_2lib_check(struct board *b, group_t group, enum stone to_play, struct libmap_mq *q, int tag, bool use_miaisafe, bool use_def_no_hopeless); diff --git a/tactics/Makefile b/tactics/Makefile index 344dde3..ca6f3a5 100644 --- a/tactics/Makefile +++ b/tactics/Makefile @@ -1,5 +1,5 @@ INCLUDES=-I.. -OBJS=1lib.o 2lib.o nlib.o ladder.o nakade.o selfatari.o util.o +OBJS=1lib.o 2lib.o nlib.o ladder.o nakade.o selfatari.o goals.o util.o all: tactics.a tactics.a: $(OBJS) diff --git a/libmap.c b/tactics/goals.c similarity index 91% copy from libmap.c copy to tactics/goals.c index 49a6f4c..032dd61 100644 --- a/libmap.c +++ b/tactics/goals.c @@ -7,33 +7,10 @@ #include "debug.h" #include "libmap.h" #include "move.h" +#include "tactics/goals.h" #include "tactics/util.h" -hash_t -group_to_libmap(struct board *b, group_t group) -{ - hash_t h = 0; -#define hbits (sizeof(hash_t)*CHAR_BIT) - - enum stone color = board_at(b, group); - struct group *gi = &board_group_info(b, group); - int libs = gi->libs < GROUP_REFILL_LIBS ? gi->libs : GROUP_REFILL_LIBS; - - for (int i = 0; i < libs; i++) { - hash_t hlib = hash_at(b, gi->lib[i], color); - /* Rotate the hash based on prospects of the liberty. */ - int p = immediate_liberty_count(b, gi->lib[i]) + - 4 * neighbor_count_at(b, gi->lib[i], color); - hlib = (hlib << p) | ((hlib >> (hbits - p)) & ((1< -#include - -#include "board.h" -#include "mq.h" -#include "stats.h" - -#define LM_DEBUG if (0) - -hash_t group_to_libmap(struct board *b, group_t group); - - -/* Setup of everything libmap-related. */ +#include "libmap.h" extern struct libmap_config { enum { @@ -65,6 +51,8 @@ extern struct libmap_config { void libmap_setup(char *arg); +/** Infrastructure for tracking moves to be confronted with the libmap hash. */ + /* Our own version of move_queue, but including liberty maps of moves. */ /* The user will usually first create a queue of tactical goals and pick * (using libmap_mq functions below), then add that one to libmap_hash's @@ -90,21 +78,7 @@ static void libmap_mq_nodup(struct libmap_mq *q); static void libmap_mq_print(struct libmap_mq *q, struct board *b, char *label); -/* Tactical application - hash structure storing info about move effectivity. */ - -struct libmap_move { - struct move move; - struct move_stats stats; -}; - -struct libmap_context { - hash_t hash; - int visits; - /* We add moves in multiple threads. But at most, on conflict we will - * end up with tiny amount of misappropriated playouts. */ - int moves; - struct libmap_move move[GROUP_REFILL_LIBS]; -}; +/** Global storage of all the libmap contexts encountered. */ struct libmap_hash { struct board *b; diff --git a/tactics/nlib.c b/tactics/nlib.c index 8a6de48..3e05b84 100644 --- a/tactics/nlib.c +++ b/tactics/nlib.c @@ -5,11 +5,11 @@ #define DEBUG #include "board.h" #include "debug.h" -#include "libmap.h" #include "mq.h" #include "tactics/2lib.h" #include "tactics/nlib.h" #include "tactics/selfatari.h" +#include "tactics/goals.h" void diff --git a/tactics/nlib.h b/tactics/nlib.h index 3e2c8f8..9d6dfe2 100644 --- a/tactics/nlib.h +++ b/tactics/nlib.h @@ -5,6 +5,7 @@ #include "board.h" #include "debug.h" +#include "tactics/goals.h" struct move_queue; diff --git a/uct/policy/ucb1amaf.c b/uct/policy/ucb1amaf.c index f7a0f7a..94ac9c0 100644 --- a/uct/policy/ucb1amaf.c +++ b/uct/policy/ucb1amaf.c @@ -7,9 +7,9 @@ #include "board.h" #include "debug.h" -#include "libmap.h" #include "move.h" #include "random.h" +#include "tactics/goals.h" #include "tactics/util.h" #include "uct/internal.h" #include "uct/tree.h" diff --git a/uct/tree.c b/uct/tree.c index 587ad28..2a94930 100644 --- a/uct/tree.c +++ b/uct/tree.c @@ -10,9 +10,9 @@ #include "board.h" #include "debug.h" #include "engine.h" -#include "libmap.h" #include "move.h" #include "playout.h" +#include "tactics/goals.h" #include "tactics/util.h" #include "timeinfo.h" #include "uct/internal.h" diff --git a/uct/uct.c b/uct/uct.c index bad4e10..ca49c64 100644 --- a/uct/uct.c +++ b/uct/uct.c @@ -11,13 +11,13 @@ #include "board.h" #include "gtp.h" #include "chat.h" -#include "libmap.h" #include "move.h" #include "mq.h" #include "joseki/base.h" #include "playout.h" #include "playout/moggy.h" #include "playout/light.h" +#include "tactics/goals.h" #include "tactics/util.h" #include "timeinfo.h" #include "uct/dynkomi.h" -- 2.11.4.GIT