pattern_eq(): Introduce
[pachi/t.git] / pattern.h
blob65fb438e8f19dfd15058332775040de22a8ea7e3
1 #ifndef PACHI_PATTERN_H
2 #define PACHI_PATTERN_H
4 /* Matching of multi-featured patterns. */
6 #include "board.h"
7 #include "move.h"
9 /* When someone says "pattern", you imagine a configuration of stones in given
10 * area (e.g. as matched very efficiently by pattern3 in case of 3x3 area).
11 * However, we use a richer definition of pattern, where this is merely one
12 * pattern _feature_. Another features may be is-a-selfatari, is-a-capture,
13 * number of liberties, distance from last move, etc. */
15 /* Each feature is represented by its id and an optional 32-bit payload;
16 * when matching, discrete (id,payload) pairs are considered. */
18 /* This is heavily influenced by (Coulom, 2007), of course. In addition,
19 * the work of van der Werf, de Groot, Stern et al. and possibly others
20 * inspired this pattern matcher. */
21 /* TODO: Try completely separate ko / no-ko features. And many other
22 * features described in the literature. */
24 /* See the HACKING file for another description of the pattern matcher and
25 * instructions on how to harvest and inspect patterns. */
27 /* If you add a payload bit for a feature, don't forget to update the value
28 * in feature_info. */
29 enum feature_id {
30 /* Implemented: */
32 /* Simple capture move. */
33 /* Payload: [bit0] Capturing laddered group? */
34 #define PF_CAPTURE_LADDER 0
35 /* [bit2] Enables our atari group get more libs? */
36 #define PF_CAPTURE_ATARIDEF 1
37 /* [bit3] Capturing ko? */
38 #define PF_CAPTURE_KO 2
39 /* [bit4] Single-stone group? */
40 #define PF_CAPTURE_1STONE 3
41 /* [bit5] Unsafe move for opponent? */
42 #define PF_CAPTURE_TRAPPED 4
43 /* [bit6] Preventing connection to an outside group. */
44 #define PF_CAPTURE_CONNECTION 5
45 FEAT_CAPTURE,
47 /* Atari escape (extension). */
48 /* Payload: [bit0] Escaping with laddered group? */
49 #define PF_AESCAPE_LADDER 0
50 /* [bit1] Single-stone group? */
51 #define PF_AESCAPE_1STONE 1
52 /* [bit2] Unsafe move for us? */
53 #define PF_AESCAPE_TRAPPED 2
54 /* [bit3] Connecting out to an outside group. */
55 #define PF_AESCAPE_CONNECTION 3
56 FEAT_AESCAPE,
58 /* Self-atari move. */
59 /* Payload: [bit0] Matched by trivial definition? */
60 /* [bit1] Matched by complex definition? (tries to be aware of nakade, throwins, ...) */
61 #define PF_SELFATARI_STUPID 0
62 #define PF_SELFATARI_SMART 1
63 FEAT_SELFATARI,
65 /* Atari move. */
66 /* Payload: [bit0] The atari'd group gets laddered? */
67 #define PF_ATARI_LADDER 0
68 /* [bit1] Playing ko? */
69 #define PF_ATARI_KO 1
70 FEAT_ATARI,
72 /* Border distance. */
73 /* Payload: The distance - "line number". Only up to 4. */
74 FEAT_BORDER,
76 /* Continuity. */
77 /* Payload: [bit0] The move is in 8-neighborhood of last move. */
78 FEAT_CONTIGUITY,
80 /* Spatial configuration of stones in certain board area,
81 * with black to play. */
82 /* Payload: Index in the spatial_dict. */
83 FEAT_SPATIAL,
85 /* TODO: MC owner, playing ko, #liberties, #libs of opponent, ... */
87 FEAT_MAX
90 struct feature {
91 enum feature_id id;
92 uint32_t payload;
95 struct pattern {
96 /* Pattern (matched) is set of features. */
97 int n;
98 #define FEATURES 32
99 struct feature f[FEATURES];
102 struct spatial_dict;
103 struct pattern_config {
104 /* FEAT_BORDER: Generate features only up to this board distance. */
105 int bdist_max;
107 /* FEAT_SPATIAL: Generate patterns only for these sizes (gridcular).
108 * TODO: Special-case high values to match larger areas or the
109 * whole board. */
110 int spat_min, spat_max;
111 /* Produce only a single spatial feature per pattern, corresponding
112 * to the largest matched spatial pattern. */
113 bool spat_largest;
114 /* The spatial patterns dictionary used by FEAT_SPATIAL. */
115 struct spatial_dict *spat_dict;
117 extern struct pattern_config DEFAULT_PATTERN_CONFIG;
119 /* The pattern_spec[] specifies which features to tests for;
120 * highest bit controls whether to test for the feature at all,
121 * then for bitmap features (except FEAT_SPATIAL) the rest
122 * of the bits controls various PF tests; for non-bitmap
123 * features, you will need to tweak the patternconfig to
124 * fine-tune them. */
125 typedef uint16_t pattern_spec[FEAT_MAX];
126 /* Match (almost?) all supported features. */
127 extern pattern_spec PATTERN_SPEC_MATCH_DEFAULT;
130 /* Append feature to string. */
131 char *feature2str(char *str, struct feature *f);
132 /* Convert string to feature, return pointer after the featurespec. */
133 char *str2feature(char *str, struct feature *f);
134 /* Get name of given feature. */
135 char *feature_name(enum feature_id f);
136 /* Get number of possible payload values associated with the feature. */
137 int feature_payloads(struct pattern_config *pc, enum feature_id f);
139 /* Append pattern as feature spec string. */
140 char *pattern2str(char *str, struct pattern *p);
141 /* Convert string to pattern, return pointer after the patternspec. */
142 char *str2pattern(char *str, struct pattern *p);
143 /* Compare two patterns for equality. Assumes fixed feature order. */
144 static bool pattern_eq(struct pattern *p1, struct pattern *p2);
146 /* Initialize p and fill it with features matched by the
147 * given board move. */
148 void pattern_match(struct pattern_config *pc, pattern_spec ps, struct pattern *p, struct board *b, struct move *m);
151 static inline bool
152 pattern_eq(struct pattern *p1, struct pattern *p2)
154 if (p1->n != p2->n) return false;
155 for (int i = 0; i < p1->n; i++)
156 if (p1->f[i].id != p2->f[i].id || p1->f[i].payload != p2->f[i].payload)
157 return false;
158 return true;
161 #endif