Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / patterns / mkeyes.c
CommitLineData
7eeb782e
AT
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
2 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
3 * http://www.gnu.org/software/gnugo/ for more information. *
4 * *
5 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
6 * 2008 and 2009 by the Free Software Foundation. *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation - version 3 or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License in file COPYING for more details. *
17 * *
18 * You should have received a copy of the GNU General Public *
19 * License along with this program; if not, write to the Free *
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21 * Boston, MA 02111, USA. *
22\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
23
24/* Compile the eye database. This produces eyes.c. */
25
26/* see also eyes.db, eyes.h and engine/optics.c */
27
28
29#define MAXLINE 80
30#define MAXDIMEN 20
31#define MAXSIZE 20
32#define MAXPATNO 800
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <ctype.h>
38#include <assert.h>
39
40#include "eyes.h"
41
42
43int
44main(void)
45{
46 char line[MAXLINE];
47 int patno = 0;
48 int p;
49 char vertex[MAXDIMEN][MAXDIMEN];
50 signed char marginal[MAXDIMEN][MAXDIMEN];
51 signed char edge[MAXDIMEN][MAXDIMEN];
52 unsigned char flags[MAXDIMEN][MAXDIMEN];
53 int neighbors[MAXSIZE];
54 int k, l, h;
55 int m = 0, n = 0;
56 int vi[MAXSIZE];
57 int vj[MAXSIZE];
58 int eye_number[MAXPATNO];
59 int esize[MAXPATNO];
60 int msize[MAXPATNO];
61 int value_a[MAXPATNO];
62 int value_b[MAXPATNO];
63 int value_c[MAXPATNO];
64 int value_d[MAXPATNO];
65 int ends[MAXPATNO];
66 int two_neighbors[MAXPATNO];
67 int three_neighbors[MAXPATNO];
68 int num_attacks = 0;
69 int num_defenses = 0;
70 int debug = 0;
71 int fatal_errors = 0;
72
73 printf("\
74/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\\n\
75 * This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *\n\
76 * http://www.gnu.org/software/gnugo/ for more information. *\n\
77 * *\n\
78 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 and 2007 *\n\
79 * by the Free Software Foundation. *\n\
80 * *\n\
81 * This program is free software; you can redistribute it and/or *\n\
82 * modify it under the terms of the GNU General Public License as *\n\
83 * published by the Free Software Foundation - version 3 *\n\
84 * or (at your option) any later version *\n\
85 * *\n\
86 * This program is distributed in the hope that it will be useful, *\n\
87 * but WITHOUT ANY WARRANTY; without even the implied warranty of *\n\
88 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\n\
89 * GNU General Public License in file COPYING for more details. *\n\
90 * *\n\
91 * You should have received a copy of the GNU General Public *\n\
92 * License along with this program; if not, write to the Free *\n\
93 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *\n\
94 * Boston, MA 02111, USA. *\n\
95\\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n");
96
97 printf("/* This file is automatically generated by mkeyes. Do not\n");
98 printf(" * edit it directly. Instead, edit the eye shape database.\n");
99 printf(" */\n\n");
100 printf("#include <stdio.h> /* for NULL */\n");
101 printf("#include \"eyes.h\"\n\n");
102
103 memset(ends, 0, sizeof(ends));
104 memset(two_neighbors, 0, sizeof(two_neighbors));
105 memset(three_neighbors, 0, sizeof(three_neighbors));
106 memset(esize, 0, sizeof(esize));
107
108 while (fgets(line, MAXLINE, stdin) && !fatal_errors) {
109 int last = strlen(line) - 1;
110
111 if (line[last] != '\n') {
112 fprintf(stderr, "mkeyes: line truncated: %s\n", line);
113 return 1;
114 }
115
116 /* remove trailing whitespace */
117 for (last--; last >= 0 && isspace((int) line[last]); last--) {
118 line[last] = '\n';
119 line[last+1] = '\0';
120 }
121
122 /* New pattern. */
123 if (sscanf(line, "Pattern %d", &p)) {
124 eye_number[patno] = p;
125 if (patno > 0 && eye_number[patno] <= eye_number[patno-1]) {
126 fprintf(stderr, "mkeyes: Pattern %d out of sequence\n",
127 eye_number[patno]);
128 return 1;
129 }
130 if (debug)
131 fprintf(stderr, "parsing pattern %d\n", eye_number[patno]);
132
133 memset(vertex, 0, sizeof(vertex));
134 memset(marginal, 0, sizeof(marginal));
135 memset(edge, 0, sizeof(edge));
136 memset(flags, 0, sizeof(flags));
137
138 m = 0;
139 esize[patno] = 0;
140 msize[patno] = 0;
141 num_attacks = 0;
142 num_defenses = 0;
143 continue;
144 }
145
146 /* Empty line or comment line, skip. */
147 if (strncmp("#", line, 1) == 0 || strncmp("\n", line, 1) == 0)
148 continue;
149
150 if (strncmp(":", line, 1) != 0) {
151 /* diagram line. */
152 for (n = 0; n < MAXDIMEN && strncmp("\n", line + n, 1); n++) {
153 /* space, harmless CR, or corner symbol */
154 if (line[n] == ' ' || line[n] == '\r' || line[n] == '+')
155 continue;
156
157 /* vertical edge */
158 if (line[n] == '|') {
159 if (n == 0)
160 edge[m][n+1]++;
161 else
162 edge[m][n-1]++;
163 continue;
164 }
165
166 /* horizontal edge */
167 if (line[n] == '-') {
168 if (m == 0)
169 edge[m+1][n]++;
170 else
171 edge[m-1][n]++;
172 continue;
173 }
174
175 /* All other symbols. */
176 vi[esize[patno]] = m;
177 vj[esize[patno]] = n;
178 vertex[m][n] = line[n];
179 if (debug)
180 fprintf(stderr, "%c", line[n]);
181 switch (line[n])
182 {
183 case '.':
184 marginal[m][n] = 0;
185 flags[m][n] = CAN_BE_EMPTY;
186 break;
187
188 case '!':
189 msize[patno]++;
190 marginal[m][n] = 1;
191 flags[m][n] = CAN_BE_EMPTY;
192 break;
193
194 case '@':
195 msize[patno]++;
196 marginal[m][n] = 1;
197 flags[m][n] = CAN_BE_EMPTY | EYE_DEFENSE_POINT | EYE_ATTACK_POINT;
198 num_attacks++;
199 num_defenses++;
200 break;
201
202 case '$':
203 msize[patno]++;
204 marginal[m][n] = 1;
205 flags[m][n] = CAN_CONTAIN_STONE;
206 break;
207
208 case '(':
209 msize[patno]++;
210 marginal[m][n] = 1;
211 flags[m][n] = CAN_BE_EMPTY | EYE_ATTACK_POINT;
212 num_attacks++;
213 break;
214
215 case ')':
216 msize[patno]++;
217 marginal[m][n] = 1;
218 flags[m][n] = CAN_BE_EMPTY | EYE_DEFENSE_POINT;
219 num_defenses++;
220 break;
221
222 case 'x':
223 marginal[m][n] = 0;
224 flags[m][n] = CAN_BE_EMPTY | CAN_CONTAIN_STONE;
225 break;
226
227 case '*':
228 marginal[m][n] = 0;
229 flags[m][n] = CAN_BE_EMPTY | EYE_ATTACK_POINT | EYE_DEFENSE_POINT;
230 num_attacks++;
231 num_defenses++;
232 break;
233
234 case '<':
235 marginal[m][n] = 0;
236 flags[m][n] = CAN_BE_EMPTY | EYE_ATTACK_POINT;
237 num_attacks++;
238 break;
239
240 case '>':
241 marginal[m][n] = 0;
242 flags[m][n] = CAN_BE_EMPTY | EYE_DEFENSE_POINT;
243 num_defenses++;
244 break;
245
246 case 'X':
247 marginal[m][n] = 0;
248 flags[m][n] = CAN_CONTAIN_STONE;
249 break;
250
251 default:
252 fprintf(stderr,
253 "mkeyes: invalid character %c in pattern %d\n",
254 line[n], eye_number[patno]);
255 fatal_errors++;
256 break;
257 }
258 esize[patno]++;
259 }
260 m++;
261 if (debug)
262 fprintf(stderr, "\n");
263 }
264 else {
265 /* Colon line. */
266 sscanf(line, ":%1d%1d%1d%1d", &value_a[patno], &value_b[patno],
267 &value_c[patno], &value_d[patno]);
268 if (debug)
269 fprintf(stderr, "value=%d%d%d%d\n", value_a[patno], value_b[patno],
270 value_c[patno], value_d[patno]);
271
272 if (value_b[patno] != value_c[patno]) {
273 if (num_attacks == 0 || num_defenses == 0) {
274 fprintf(stderr,
275 "mkeyes: missing attack or defense point in pattern %d\n",
276 eye_number[patno]);
277 fatal_errors++;
278 }
279 }
280
281 if (value_b[patno] == value_c[patno]) {
282 if (num_attacks > 0 || num_defenses > 0) {
283 fprintf(stderr,
284 "mkeyes: attack or defense point in settled pattern %d\n",
285 eye_number[patno]);
286 fatal_errors++;
287 }
288 }
289
290 printf("static struct eye_vertex eye%d[] = {\n", eye_number[patno]);
291
292 for (l = 0; l < esize[patno]; l++) {
293 int ni[4];
294 int nj[4];
295 int nb[4];
296 int mx[MAXDIMEN][MAXDIMEN];
297 int count = 0;
298 int i = vi[l];
299 int j = vj[l];
300
301 memset(mx, -1, sizeof(mx));
302
303 neighbors[l] = 0;
304
305 for (h = 0; h < 4; h++) {
306 ni[h] = -1;
307 nj[h] = -1;
308 nb[h] = -1;
309 }
310
311 mx[i][j] = 0;
312
313 if (i > 0 && vertex[i-1][j]) {
314 ni[neighbors[l]] = i-1;
315 nj[neighbors[l]] = j;
316 neighbors[l]++;
317 count++;
318 mx[i-1][j] = l;
319 }
320
321 if (i < MAXDIMEN-1 && vertex[i+1][j]) {
322 ni[neighbors[l]] = i+1;
323 nj[neighbors[l]] = j;
324 neighbors[l]++;
325 count++;
326 mx[i+1][j] = l;
327 }
328
329 if (j > 0 && vertex[i][j-1]) {
330 ni[neighbors[l]] = i;
331 nj[neighbors[l]] = j-1;
332 neighbors[l]++;
333 mx[i][j-1] = l;
334 }
335
336 if (j < MAXDIMEN-1 && vertex[i][j+1]) {
337 ni[neighbors[l]] = i;
338 nj[neighbors[l]] = j+1;
339 neighbors[l]++;
340 mx[i][j+1] = l;
341 }
342
343
344 if (neighbors[l] == 1)
345 ends[patno]++;
346 else if (neighbors[l] == 2)
347 two_neighbors[patno]++;
348 else if (neighbors[l] == 3)
349 three_neighbors[patno]++;
350
351 for (h = 0; h < esize[patno]; h++) {
352
353 for (k = 0; k < 4; k++)
354 if (ni[k] != -1 && vi[h] == ni[k] && vj[h] == nj[k])
355 nb[k] = h;
356 }
357
358
359 printf(" {%d, %d, %2d, %d, {%2d, %2d, %2d, %2d}}",
360 marginal[i][j], (int) edge[i][j], (int) flags[i][j],
361 neighbors[l], nb[0], nb[1], nb[2], nb[3]);
362
363 if (l < esize[patno]-1)
364 printf(",\n");
365 else
366 printf("\n};\n\n");
367 }
368
369 patno++;
370 if (patno >= MAXPATNO) {
371 fprintf(stderr,
372 "mkeyes: Too many eye patterns. Increase MAXPATNO in mkeyes.c\n");
373 fatal_errors++;
374 }
375 }
376 }
377
378
379 printf("\nstruct eye_graph graphs[] = {\n");
380 for (l = 0; l < patno; l++) {
381
382 printf(" {eye%d, %d, %d, %d, %d, %d, %d, {%d, %d, %d, %d}}",
383 eye_number[l], eye_number[l], esize[l], msize[l], ends[l],
384 two_neighbors[l], three_neighbors[l],
385 value_a[l], value_b[l], value_c[l], value_d[l]);
386 if (l < patno-1)
387 printf(",\n");
388 else
389 printf(",\n {NULL, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0}}\n};\n");
390 }
391
392 if (fatal_errors) {
393 printf("\n\n#error in eye database. Rebuild.\n\n");
394 }
395
396 return fatal_errors;
397}
398
399/*
400 * Local Variables:
401 * tab-width: 8
402 * c-basic-offset: 2
403 * End:
404 */