Updated README: Equal sign not required with `--mode` flag.
[sgk-go] / patterns / uncompress_fuseki.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#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <assert.h>
28#include "board.h"
29#include "liberty.h"
30#include "hash.h"
31#include "gg_utils.h"
32
33#define BUFSIZE 160
34
35#define USAGE "\
36Usage :\
37uncompress_fuseki boardsize filename c\n\
38uncompress_fuseki boardsize filename db\n\
39"
40
41#define DB_PREAMBLE "\
42# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n\
43# This is GNU Go, a Go program. Contact gnugo@gnu.org, or see #\n\
44# http://www.gnu.org/software/gnugo/ for more information. #\n\
45# #\n\
46# Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 #\n\
47# 2008 and 2009 by the Free Software Foundation. #\n\
48# #\n\
49# This program is free software; you can redistribute it and/or #\n\
50# modify it under the terms of the GNU General Public License as #\n\
51# published by the Free Software Foundation - version 3 #\n\
52# or (at your option) any later version. #\n\
53# #\n\
54# This program is distributed in the hope that it will be useful, #\n\
55# but WITHOUT ANY WARRANTY; without even the implied warranty of #\n\
56# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #\n\
57# GNU General Public License in file COPYING for more details. #\n\
58# #\n\
59# You should have received a copy of the GNU General Public #\n\
60# License along with this program; if not, write to the Free #\n\
61# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, #\n\
62# Boston, MA 02111, USA. #\n\
63# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n\
64# This file is automatically generated by uncompress_fuseki. Do #\n\
65# not edit it directly. Instead, edit the corresponding .dbz file. #\n\
66# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n\
67\n\n\
68"
69
70#define DB_HEADER "# Fuseki patternsboardsize %d\nattribute_map value_only\n\n"
71#define DB_FOOTER ""
72
73#define C_PREAMBLE "\
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 and 2006 *\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\
96\n#include <stdio.h> /* for NULL */\n\
97#include \"liberty.h\"\n\
98#include \"patterns.h\"\n\n\
99"
100
101#define C_HEADER "struct fullboard_pattern fuseki%d[] = {\n"
102#define C_FOOTER "};\n"
103
104static const char *const db_output_strings[3] =
105 {DB_PREAMBLE, DB_HEADER, DB_FOOTER};
106static const char *const c_output_strings[3] =
107 {C_PREAMBLE, C_HEADER, C_FOOTER};
108
109#define PREAMBLE 0
110#define HEADER 1
111#define FOOTER 2
112
113
114/* Place a stone (or move mark) on the internal board. The board point
115 * is sgf encoded.
116 */
117static int
118set_boards(char board[MAX_BOARD + 2][MAX_BOARD + 2],
119 Intersection board1d[BOARDSIZE],
120 char *stones, char color, int boardsize)
121{
122 int i = stones[1] - 'a' + 1;
123 int j = stones[0] - 'a' + 1;
124 if (stones[0] != 't') {
125 assert(i > 0 && i < boardsize + 2);
126 board[i][j] = color;
127 if (color == 'O')
128 board1d[POS(i - 1, j - 1)] = WHITE;
129 else if (color == 'X')
130 board1d[POS(i - 1, j - 1)] = BLACK;
131 return POS(i - 1, j - 1);
132 }
133 else
134 return NO_MOVE;
135}
136
137static void
138write_pattern(char *name, char board[MAX_BOARD + 2][MAX_BOARD + 2],
139 int value, int boardsize)
140{
141 int i, j;
142 /* Output the uncompressed pattern. */
143 printf("Pattern %s\n\n", name);
144 for (i = 0; i <= boardsize + 1; i++) {
145 for (j = 0; j <= boardsize + 1; j++)
146 printf("%c", board[i][j]);
147 printf("\n");
148 }
149 printf("\n:8,-,value(%d)\n\n\n", value);
150}
151
152
153static void
154write_pattern_c_code(char *name, Intersection board1d[BOARDSIZE],
155 int move_pos, int value, int boardsize, int patlen)
156{
157 int k;
158 Hash_data pattern_hash;
159
160 /* Compute hash. */
161 hashdata_recalc(&pattern_hash, board1d, NO_MOVE);
162 printf(" {{{");
163 for (k = 0; k < NUM_HASHVALUES; k++) {
164 printf("0x%lx", pattern_hash.hashval[k]);
165 if (k < NUM_HASHVALUES - 1)
166 printf(",");
167 }
168 if (name)
169 printf("}},%d,\"%s\",%d,%d},\n", patlen, name,
170 OFFSET(I(move_pos) - (boardsize-1)/2,
171 J(move_pos) - (boardsize-1)/2),
172 value);
173 else
174 printf("}},-1,NULL,0,0},\n");
175}
176
177
178
179#define DB_OUTPUT 1
180#define C_OUTPUT 2
181
182
183int
184main(int argc, char *argv[])
185{
186 const char *filename;
187 FILE *input_FILE;
188 const char *const *output_strings;
189 int mode;
190 int move_pos;
191 char line[BUFSIZE];
192 char name[BUFSIZE];
193 char stones[BUFSIZE];
194 int value;
195 char board[MAX_BOARD + 2][MAX_BOARD + 2];
196 Intersection board1d[BOARDSIZE];
197 int boardsize;
198 int i, j, k;
199 int pos;
200 char color;
201
202 /* Check number of arguments. */
203 if (argc != 4) {
204 fprintf(stderr, USAGE);
205 return EXIT_FAILURE;
206 }
207
208 boardsize = atoi(argv[1]);
209 filename = argv[2];
210 if (strncmp(argv[3], "c", 2) == 0) {
211 mode = C_OUTPUT;
212 output_strings = c_output_strings;
213 set_random_seed(HASH_RANDOM_SEED);
214 hash_init();
215 }
216 else if (strncmp(argv[3], "db", 3) == 0) {
217 mode = DB_OUTPUT;
218 output_strings = db_output_strings;
219 }
220 else {
221 fprintf(stderr, USAGE);
222 return EXIT_FAILURE;
223 }
224
225 assert(boardsize > 0);
226 if (boardsize > MAX_BOARD) {
227 printf(output_strings[PREAMBLE]);
228 printf(output_strings[HEADER], boardsize);
229 printf(output_strings[FOOTER]);
230 return EXIT_SUCCESS;
231 }
232
233
234 input_FILE = fopen(filename, "r");
235 if (!input_FILE) {
236 fprintf(stderr, "uncompress_fuseki: Cannot open file %s\n", filename);
237 return EXIT_FAILURE;
238 }
239
240 /* Initialize the corners of the internal board description. */
241 board[0][0] = '+';
242 board[0][boardsize + 1] = '+';
243 board[boardsize + 1][0] = '+';
244 board[boardsize + 1][boardsize + 1] = '+';
245
246 /* Initialize the sides of the internal board description. */
247 for (k = 1; k <= boardsize; k++) {
248 board[0][k] = '-';
249 board[boardsize + 1][k] = '-';
250 board[k][0] = '|';
251 board[k][boardsize + 1] = '|';
252 }
253
254 printf(output_strings[PREAMBLE]);
255 printf(output_strings[HEADER], boardsize);
256
257
258 /* Loop over the lines of the compressed database.
259 * Each line is one pattern.
260 */
261 while (fgets(line, BUFSIZE, input_FILE)) {
262 int num_stones = 0;
263 /* Clear the internal board. */
264 for (i = 1; i <= boardsize; i++)
265 for (j = 1; j <= boardsize; j++)
266 board[i][j] = '.';
267
268 /* Initialize private 1D-board. */
269 for (pos = 0; pos < BOARDSIZE; pos++)
270 if (I(pos) >= 0 && I(pos) < boardsize
271 && J(pos) >= 0 && J(pos) < boardsize)
272 board1d[pos] = EMPTY;
273 else
274 board1d[pos] = GRAY;
275
276 /* Assume a line from copyright notice if misformed and
277 * silently ignore it.
278 */
279 if (sscanf(line, "%s %d %s", name, &value, stones) != 3)
280 continue;
281
282 /* The first point in the stones list is the move to be played. */
283 move_pos = set_boards(board, board1d, stones, '*', boardsize);
284
285 /* Then follows alternating X and O stones. */
286 color = 'X';
287 for (k = 2; k < (int) strlen(stones); k += 2) {
288 pos = set_boards(board, board1d, stones + k, color, boardsize);
289 if (I(pos) >= 0 && I(pos) < boardsize
290 && J(pos) >= 0 && J(pos) < boardsize)
291 num_stones++;
292 if (color == 'X')
293 color = 'O';
294 else
295 color = 'X';
296 }
297
298 if (mode == DB_OUTPUT)
299 write_pattern(name, board, value, boardsize);
300 else
301 write_pattern_c_code(name, board1d, move_pos, value, boardsize,
302 num_stones);
303 }
304
305 /* Add a dummy pattern to mark the end of the array. This can't be
306 * done statically in the footer since NUM_HASHVALUES may vary.
307 */
308 if (mode == C_OUTPUT)
309 write_pattern_c_code(NULL, board1d, NO_MOVE, 0, boardsize, -1);
310
311 printf(output_strings[FOOTER]);
312
313 return EXIT_SUCCESS;
314}
315
316
317/*
318 * Local Variables:
319 * tab-width: 8
320 * c-basic-offset: 2
321 * End:
322 */