1 #ifndef ZZGO_UCT_POLICY_GENERIC_H
2 #define ZZGO_UCT_POLICY_GENERIC_H
4 /* Some default policy routines and templates. */
8 #include "uct/internal.h"
13 struct tree_node
*uctp_generic_choose(struct uct_policy
*p
, struct tree_node
*node
, struct board
*b
, enum stone color
, coord_t exclude
);
14 void uctp_generic_winner(struct uct_policy
*p
, struct tree
*tree
, struct uct_descent
*descent
);
17 /* Some generic stitching for tree descent. */
19 #define uctd_try_node_children(tree, descent, allow_pass, parity, tenuki_d, di, urgency) \
20 /* Information abound best children. */ \
21 /* XXX: We assume board <=25x25. */ \
22 struct uct_descent dbest[BOARD_MAX_MOVES + 1] = { { .node = descent->node->children, .lnode = NULL } }; int dbests = 1; \
23 float best_urgency = -9999; \
24 /* Descent children iterator. */ \
25 struct uct_descent dci = { .node = descent->node->children, .lnode = descent->lnode ? descent->lnode->children : NULL }; \
27 for (; dci.node; dci.node = dci.node->sibling) { \
29 /* Do not consider passing early. */ \
30 if (unlikely((!allow_pass && is_pass(dci.node->coord)) || (dci.node->hints & TREE_HINT_INVALID))) \
32 /* Position dci.lnode to point at or right after the local
33 * node corresponding to dci.node. */ \
34 while (dci.lnode && dci.lnode->coord < dci.node->coord) \
35 dci.lnode = dci.lnode->sibling; \
36 /* Set up descent-further iterator. This is the public-accessible
37 * one, and usually is similar to dci. However, in case of local
38 * trees, we may keep next-candidate pointer in dci while storing
39 * actual-specimen in di. */ \
40 struct uct_descent di = dci; \
42 /* Set lnode to local tree node corresponding
43 * to node (dci.lnode, pass-lnode or NULL). */ \
44 di.lnode = tree_lnode_for_node(tree, dci.node, dci.lnode, tenuki_d); \
47 /* ...your urgency computation code goes here... */
49 #define uctd_set_best_child(di, urgency) \
50 if (urgency - best_urgency > __FLT_EPSILON__) { /* urgency > best_urgency */ \
51 best_urgency = urgency; dbests = 0; \
53 if (urgency - best_urgency > -__FLT_EPSILON__) { /* urgency >= best_urgency */ \
54 /* We want to always choose something else than a pass \
55 * in case of a tie. pass causes degenerative behaviour. */ \
56 if (dbests == 1 && is_pass(dbest[0].node->coord)) { \
59 struct uct_descent db = di; \
60 /* Make sure lnode information is meaningful. */ \
61 if (db.lnode && is_pass(db.lnode->coord)) \
63 dbest[dbests++] = db; \
67 #define uctd_get_best_child(descent) *(descent) = dbest[fast_random(dbests)];