9 #include "patternplay/patternplay.h"
11 #include "patternsp.h"
12 #include "patternprob.h"
16 /* Internal engine state. */
20 struct pattern_config pc
;
22 struct pattern_pdict
*pd
;
26 /* Evaluate patterns for all available moves. Stores found patterns
27 * to pats[b->flen] and normalized probability of each pattern (or NaN
28 * in case of no match) to probs[b->flen]. */
30 rate_moves(struct pattern_config
*pc
, pattern_spec
*ps
, struct pattern_pdict
*pd
,
31 struct board
*b
, enum stone color
,
32 struct pattern
*pats
, floating_t
*probs
)
34 /* First pass: Gather probabilities. */
36 for (int f
= 0; f
< b
->flen
; f
++) {
39 struct move mo
= { .coord
= b
->f
[f
], .color
= color
};
40 if (is_pass(mo
.coord
))
42 if (!board_is_valid_move(b
, &mo
))
45 pattern_match(pc
, *ps
, &pats
[f
], b
, &mo
);
46 floating_t prob
= pattern_prob(pd
, &pats
[f
]);
53 /* Second pass: Rescale. */
54 for (int f
= 0; f
< b
->flen
; f
++) {
60 patternplay_genmove(struct engine
*e
, struct board
*b
, struct time_info
*ti
, enum stone color
, bool pass_all_alive
)
62 struct patternplay
*pp
= e
->data
;
64 struct pattern pats
[b
->flen
];
65 floating_t probs
[b
->flen
];
66 rate_moves(&pp
->pc
, &pp
->ps
, pp
->pd
, b
, color
, pats
, probs
);
69 for (int f
= 0; f
< b
->flen
; f
++) {
70 if (pp
->debug_level
>= 5 && probs
[f
] > 0) {
71 char s
[256]; pattern2str(s
, &pats
[f
]);
72 fprintf(stderr
, "\t%s: %.3f %s\n", coord2sstr(b
->f
[f
], b
), probs
[f
], s
);
74 if (probs
[f
] > probs
[best
])
78 return coord_copy(b
->f
[best
]);
82 patternplay_evaluate(struct engine
*e
, struct board
*b
, struct time_info
*ti
, floating_t
*vals
, enum stone color
)
84 struct patternplay
*pp
= e
->data
;
86 struct pattern pats
[b
->flen
];
87 rate_moves(&pp
->pc
, &pp
->ps
, pp
->pd
, b
, color
, pats
, vals
);
89 if (pp
->debug_level
>= 4) {
90 for (int f
= 0; f
< b
->flen
; f
++) {
92 char s
[256]; pattern2str(s
, &pats
[f
]);
93 fprintf(stderr
, "\t%s: %.3f %s\n", coord2sstr(b
->f
[f
], b
), vals
[f
], s
);
101 patternplay_state_init(char *arg
)
103 struct patternplay
*pp
= calloc2(1, sizeof(struct patternplay
));
105 pp
->debug_level
= debug_level
;
106 pp
->pc
= DEFAULT_PATTERN_CONFIG
;
107 pp
->pc
.spat_dict
= spatial_dict_init(false);
108 memcpy(&pp
->ps
, PATTERN_SPEC_MATCH_DEFAULT
, sizeof(pattern_spec
));
111 char *optspec
, *next
= arg
;
114 next
+= strcspn(next
, ",");
115 if (*next
) { *next
++ = 0; } else { *next
= 0; }
117 char *optname
= optspec
;
118 char *optval
= strchr(optspec
, '=');
119 if (optval
) *optval
++ = 0;
121 if (!strcasecmp(optname
, "debug")) {
123 pp
->debug_level
= atoi(optval
);
127 /* See pattern.h:pattern_config for description and
128 * pattern.c:DEFAULT_PATTERN_CONFIG for default values
129 * of the following options. */
130 } else if (!strcasecmp(optname
, "bdist_max") && optval
) {
131 pp
->pc
.bdist_max
= atoi(optval
);
132 } else if (!strcasecmp(optname
, "spat_min") && optval
) {
133 pp
->pc
.spat_min
= atoi(optval
);
134 } else if (!strcasecmp(optname
, "spat_max") && optval
) {
135 pp
->pc
.spat_max
= atoi(optval
);
136 } else if (!strcasecmp(optname
, "spat_largest")) {
137 pp
->pc
.spat_largest
= !optval
|| atoi(optval
);
140 fprintf(stderr
, "patternplay: Invalid engine argument %s or missing value\n", optname
);
146 pp
->pd
= pattern_pdict_init(NULL
, &pp
->pc
);
152 engine_patternplay_init(char *arg
, struct board
*b
)
154 struct patternplay
*pp
= patternplay_state_init(arg
);
155 struct engine
*e
= calloc2(1, sizeof(struct engine
));
156 e
->name
= "PatternPlay Engine";
157 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.";
158 e
->genmove
= patternplay_genmove
;
159 e
->evaluate
= patternplay_evaluate
;