1 #ifndef ZZGO_PATTERNSP_H
2 #define ZZGO_PATTERNSP_H
4 /* Matching of spatial pattern features. */
10 /* Spatial stone configuration pattern features - like pattern3 handles
11 * 3x3-area, this handles general N-area (where N is distance in
12 * gridcular metric). These routines define the dictionary of spatial
13 * configurations (accessible by zobrist hashes or indices) and related
14 * data structures; eventually, they support the FEAT_SPATIAL pattern
15 * feature implementation in the General Pattern Matcher (pattern.[ch]). */
17 /* Maximum spatial pattern diameter. */
18 #define MAX_PATTERN_DIST 10
19 /* Maximum number of points in spatial pattern (upper bound).
20 * TODO: Better upper bound to save more data. */
21 #define MAX_PATTERN_AREA (MAX_PATTERN_DIST*MAX_PATTERN_DIST)
23 /* For each encountered configuration of stones, we keep it "spelled out"
24 * in the spatial dictionary records, index them and refer just the indices
25 * in the feature payloads. This achieves several things:
26 * * We can handle patterns of arbitrary length.
27 * * We can recognize isomorphous configurations (color reversions,
28 * rotations) within the dataset.
29 * * We can visualise patterns corresponding to chosen features.
31 * Thus, it goes like this:
33 * +----------------+ +----------------+
34 * | struct pattern | - | struct feature |
35 * +----------------+ | payload id |
41 * +-----------------------------------------+
42 * | struct spatial_dict spatials[] hash[] |
43 * +-----------------------------------------+
51 /* Spatial record - single stone configuration. */
54 /* Gridcular radius of matched pattern. */
56 /* The points; each point is two bits, corresponding
57 * to {enum stone}. Points are ordered in gridcular-defined
58 * spiral from middle to the edge; the dictionary file has
59 * a comment describing the ordering at the top. */
60 char points
[MAX_PATTERN_AREA
/ 4];
61 #define spatial_point_at(s, i) (((s).points[(i) / 4] >> (((i) % 4) * 2)) & 3)
64 /* Fill up the spatial record from @m vincinity, up to full distance
65 * given by pattern config. */
66 struct pattern_config
;
67 void spatial_from_board(struct pattern_config
*pc
, struct spatial
*s
, struct board
*b
, struct move
*m
);
69 /* Compute hash of given spatial pattern. */
70 hash_t
spatial_hash(int rotation
, struct spatial
*s
);
72 /* Convert given spatial pattern to string. */
73 char *spatial2str(struct spatial
*s
);
75 /* Mapping from point sequence to coordinate offsets (to determine
76 * coordinates relative to pattern center). */
77 struct ptcoord
{ short x
, y
; } ptcoords
[MAX_PATTERN_AREA
];
78 /* For each radius, starting index in ptcoords[]. */
79 int ptind
[MAX_PATTERN_DIST
+ 2];
80 /* Zobrist hashes used for points in patterns. */
81 #define PTH__ROTATIONS 8
82 hash_t pthashes
[PTH__ROTATIONS
][MAX_PATTERN_AREA
][S_MAX
];
85 /* Spatial dictionary - collection of stone configurations. */
87 /* Two ways of lookup: (i) by index (ii) by hash of the configuration. */
89 /* Indexed base store */
90 int nspatials
; /* Number of records. */
91 struct spatial
*spatials
; /* Actual records. */
93 /* Hashed access; all isomorphous configurations
95 #define spatial_hash_bits 24 // ~64mib array
96 #define spatial_hash_mask ((1 << spatial_hash_bits) - 1)
97 /* Maps to spatials[] indices. The hash function
98 * used is zobrist hashing with fixed values. */
99 uint32_t hash
[1 << spatial_hash_bits
];
100 /* Auxiliary collision counter, for statistics. */
104 /* Initializes spatial dictionary, pre-loading existing records from
105 * default filename if exists. If will_append is true, it will not
106 * complain about non-existing file and initialize the dictionary anyway. */
107 struct spatial_dict
*spatial_dict_init(bool will_append
);
109 /* Lookup specified spatial pattern in the dictionary; return index
110 * of the pattern. If the pattern is not found, 0 will be returned. */
111 int spatial_dict_get(struct spatial_dict
*dict
, int dist
, hash_t h
);
113 /* Store specified spatial pattern in the dictionary if it is not known yet.
114 * Returns pattern id. Note that the pattern is NOT written to the underlying
115 * file automatically. */
116 int spatial_dict_put(struct spatial_dict
*dict
, struct spatial
*s
, hash_t
);
119 /* Spatial dictionary file manipulation. */
121 /* Loading routine is not exported, it is called automatically within
122 * spatial_dict_init(). */
124 /* Default spatial dict filename to use. */
125 extern const char *spatial_dict_filename
;
127 /* Write comment lines describing the dictionary (e.g. point order
128 * in patterns) to given file. */
129 void spatial_dict_writeinfo(struct spatial_dict
*dict
, FILE *f
);
131 /* Append specified spatial pattern to the given file. */
132 void spatial_write(struct spatial
*s
, int id
, FILE *f
);