15 static struct tree_node
*
16 tree_init_node(coord_t coord
)
18 struct tree_node
*n
= calloc(1, sizeof(*n
));
24 tree_init(struct board
*board
)
26 struct tree
*t
= calloc(1, sizeof(*t
));
27 /* The root PASS move is only virtual, we never play it. */
28 t
->root
= tree_init_node(pass
);
35 tree_done_node(struct tree_node
*n
)
37 struct tree_node
*ni
= n
->children
;
39 struct tree_node
*nj
= ni
->sibling
;
47 tree_done(struct tree
*t
)
49 tree_done_node(t
->root
);
55 tree_node_dump(struct tree
*tree
, struct tree_node
*node
, int l
)
57 for (int i
= 0; i
< l
; i
++) fputc(' ', stderr
);
58 fprintf(stderr
, "[%s] %f (%d playouts)\n", coord2sstr(node
->coord
, tree
->board
), node
->value
, node
->playouts
);
60 /* Print nodes sorted by #playouts. */
62 struct tree_node
*nbox
[1000]; int nboxl
= 0;
63 for (struct tree_node
*ni
= node
->children
; ni
; ni
= ni
->sibling
)
64 if (ni
->playouts
> 200)
69 for (int i
= 0; i
< nboxl
; i
++)
70 if (nbox
[i
] && (best
< 0 || nbox
[i
]->playouts
> nbox
[best
]->playouts
))
74 tree_node_dump(tree
, nbox
[best
], l
+ 1);
80 tree_dump(struct tree
*tree
)
82 tree_node_dump(tree
, tree
->root
, 0);
87 tree_expand_node(struct tree
*t
, struct tree_node
*node
)
89 assert(!node
->children
);
91 struct tree_node
*ni
= tree_init_node(pass
);
92 ni
->parent
= node
; node
->children
= ni
;
94 /* The loop excludes the offboard margin. */
95 for (int i
= 1; i
< t
->board
->size
; i
++) {
96 for (int j
= 1; j
< t
->board
->size
; j
++) {
97 struct tree_node
*nj
= tree_init_node(coord_xy_otf(i
, j
, t
->board
));
98 nj
->parent
= node
; ni
->sibling
= nj
; ni
= nj
;
104 tree_delete_node(struct tree_node
*node
)
107 struct tree_node
*ni
= node
->parent
;
108 if (ni
->children
== node
) {
109 ni
->children
= node
->sibling
;
112 while (ni
->sibling
!= node
)
114 ni
->sibling
= node
->sibling
;
118 assert(!node
->children
);
123 tree_leaf_node(struct tree_node
*node
)
125 return !(node
->children
);
129 tree_best_child(struct tree_node
*node
)
131 struct tree_node
*nbest
= node
->children
;
132 for (struct tree_node
*ni
= node
->children
; ni
; ni
= ni
->sibling
)
133 // we compare playouts and choose the best-explored
134 // child; comparing values is more brittle
135 if (ni
->playouts
> nbest
->playouts
)
142 tree_uct_descend(struct tree
*tree
, struct tree_node
*node
, int parity
)
144 float xpl
= log(node
->playouts
) * tree
->explore_p
;
146 struct tree_node
*nbest
= node
->children
;
147 float best_urgency
= -9999;
148 for (struct tree_node
*ni
= node
->children
; ni
; ni
= ni
->sibling
) {
150 float xpl_loc
= (ni
->value
- ni
->value
* ni
->value
);
151 if (parity
< 0) xpl_loc
= 1 - xpl_loc
;
152 xpl_loc
+= sqrt(xpl
/ ni
->playouts
);
153 if (xpl_loc
> 1.0/4) xpl_loc
= 1.0/4;
154 float urgency
= ni
->value
* parity
+ sqrt(xpl
* xpl_loc
/ ni
->playouts
);
156 float urgency
= ni
->value
* parity
+ sqrt(xpl
/ ni
->playouts
);
158 if (urgency
> best_urgency
) {
159 best_urgency
= urgency
;
167 tree_uct_update(struct tree_node
*node
, int result
)
169 for (; node
; node
= node
->parent
) {
171 node
->wins
+= result
;
172 node
->value
= (float)node
->wins
/ node
->playouts
;