10 #include "uct/dynkomi.h"
11 #include "uct/internal.h"
16 uct_dynkomi_generic_done(struct uct_dynkomi
*d
)
18 if (d
->data
) free(d
->data
);
23 /* NONE dynkomi strategy - never fiddle with komi values. */
26 uct_dynkomi_init_none(struct uct
*u
, char *arg
, struct board
*b
)
28 struct uct_dynkomi
*d
= calloc(1, sizeof(*d
));
32 d
->done
= uct_dynkomi_generic_done
;
36 fprintf(stderr
, "uct: Dynkomi method none accepts no arguments\n");
44 /* LINEAR dynkomi strategy - Linearly Decreasing Handicap Compensation. */
45 /* At move 0, we impose extra komi of handicap_count*handicap_value, then
46 * we linearly decrease this extra komi throughout the game down to 0
49 struct dynkomi_linear
{
56 uct_dynkomi_linear_permove(struct uct_dynkomi
*d
, struct board
*b
, struct tree
*tree
)
58 struct dynkomi_linear
*l
= d
->data
;
59 if (b
->moves
>= l
->moves
)
62 float base_komi
= board_effective_handicap(b
, l
->handicap_value
);
63 float extra_komi
= base_komi
* (l
->moves
- b
->moves
) / l
->moves
;
68 uct_dynkomi_linear_persim(struct uct_dynkomi
*d
, struct board
*b
, struct tree
*tree
, struct tree_node
*node
)
70 struct dynkomi_linear
*l
= d
->data
;
72 return tree
->extra_komi
;
73 /* We don't reuse computed value from tree->extra_komi,
74 * since we want to use value correct for this node depth.
75 * This also means the values will stay correct after
77 return uct_dynkomi_linear_permove(d
, b
, tree
);
81 uct_dynkomi_init_linear(struct uct
*u
, char *arg
, struct board
*b
)
83 struct uct_dynkomi
*d
= calloc(1, sizeof(*d
));
85 d
->permove
= uct_dynkomi_linear_permove
;
86 d
->persim
= uct_dynkomi_linear_persim
;
87 d
->done
= uct_dynkomi_generic_done
;
89 struct dynkomi_linear
*l
= calloc(1, sizeof(*l
));
92 if (board_size(b
) - 2 >= 19)
94 l
->handicap_value
= 7;
97 char *optspec
, *next
= arg
;
100 next
+= strcspn(next
, ":");
101 if (*next
) { *next
++ = 0; } else { *next
= 0; }
103 char *optname
= optspec
;
104 char *optval
= strchr(optspec
, '=');
105 if (optval
) *optval
++ = 0;
107 if (!strcasecmp(optname
, "moves") && optval
) {
108 /* Dynamic komi in handicap game; linearly
109 * decreases to basic settings until move
111 l
->moves
= atoi(optval
);
112 } else if (!strcasecmp(optname
, "handicap_value") && optval
) {
113 /* Point value of single handicap stone,
114 * for dynkomi computation. */
115 l
->handicap_value
= atoi(optval
);
116 } else if (!strcasecmp(optname
, "rootbased")) {
117 /* If set, the extra komi applied will be
118 * the same for all simulations within a move,
119 * instead of being same for all simulations
120 * within the tree node. */
121 l
->rootbased
= !optval
|| atoi(optval
);
123 fprintf(stderr
, "uct: Invalid dynkomi argument %s or missing value\n", optname
);