Give 0 or negative rave bonus to ko threats before taking the ko.
[pachi/peepo.git] / patternplay / patternplay.c
blobfb12c7053d56cfb2f7ef54ced27fd4302e4c2705
1 #include <assert.h>
2 #include <stdio.h>
3 #include <stdlib.h>
5 #include "board.h"
6 #include "debug.h"
7 #include "engine.h"
8 #include "move.h"
9 #include "patternplay/patternplay.h"
10 #include "pattern.h"
11 #include "patternsp.h"
12 #include "patternprob.h"
13 #include "random.h"
16 /* Internal engine state. */
17 struct patternplay {
18 int debug_level;
20 struct pattern_setup pat;
24 static coord_t *
25 patternplay_genmove(struct engine *e, struct board *b, struct time_info *ti, enum stone color, bool pass_all_alive)
27 struct patternplay *pp = e->data;
29 struct pattern pats[b->flen];
30 floating_t probs[b->flen];
31 pattern_rate_moves(&pp->pat, b, color, pats, probs);
33 int best = 0;
34 for (int f = 0; f < b->flen; f++) {
35 if (pp->debug_level >= 5 && probs[f] >= 0.001) {
36 char s[256]; pattern2str(s, &pats[f]);
37 fprintf(stderr, "\t%s: %.3f %s\n", coord2sstr(b->f[f], b), probs[f], s);
39 if (probs[f] > probs[best])
40 best = f;
43 return coord_copy(b->f[best]);
46 void
47 patternplay_evaluate(struct engine *e, struct board *b, struct time_info *ti, floating_t *vals, enum stone color)
49 struct patternplay *pp = e->data;
51 struct pattern pats[b->flen];
52 floating_t total = pattern_rate_moves(&pp->pat, b, color, pats, vals);
54 #if 0
55 /* Rescale properly. */
56 for (int f = 0; f < b->flen; f++) {
57 probs[f] /= total;
59 #endif
61 if (pp->debug_level >= 4) {
62 for (int f = 0; f < b->flen; f++) {
63 if (vals[f] >= 0.001) {
64 char s[256]; pattern2str(s, &pats[f]);
65 fprintf(stderr, "\t%s: %.3f %s\n", coord2sstr(b->f[f], b), vals[f], s);
72 struct patternplay *
73 patternplay_state_init(char *arg)
75 struct patternplay *pp = calloc2(1, sizeof(struct patternplay));
76 bool pat_setup = false;
78 pp->debug_level = debug_level;
80 if (arg) {
81 char *optspec, *next = arg;
82 while (*next) {
83 optspec = next;
84 next += strcspn(next, ",");
85 if (*next) { *next++ = 0; } else { *next = 0; }
87 char *optname = optspec;
88 char *optval = strchr(optspec, '=');
89 if (optval) *optval++ = 0;
91 if (!strcasecmp(optname, "debug")) {
92 if (optval)
93 pp->debug_level = atoi(optval);
94 else
95 pp->debug_level++;
97 } else if (!strcasecmp(optname, "patterns") && optval) {
98 patterns_init(&pp->pat, optval, false, true);
99 pat_setup = true;
101 } else {
102 fprintf(stderr, "patternplay: Invalid engine argument %s or missing value\n", optname);
103 exit(EXIT_FAILURE);
108 if (!pat_setup)
109 patterns_init(&pp->pat, NULL, false, true);
111 return pp;
114 struct engine *
115 engine_patternplay_init(char *arg, struct board *b)
117 struct patternplay *pp = patternplay_state_init(arg);
118 struct engine *e = calloc2(1, sizeof(struct engine));
119 e->name = "PatternPlay Engine";
120 e->comment = "I select moves blindly according to learned patterns. I won't pass as long as there is a place on the board where I can play. When we both pass, I will consider all the stones on the board alive.";
121 e->genmove = patternplay_genmove;
122 e->evaluate = patternplay_evaluate;
123 e->data = pp;
125 return e;