Commit | Line | Data |
---|---|---|
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 "\ | |
36 | Usage :\ | |
37 | uncompress_fuseki boardsize filename c\n\ | |
38 | uncompress_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 | ||
104 | static const char *const db_output_strings[3] = | |
105 | {DB_PREAMBLE, DB_HEADER, DB_FOOTER}; | |
106 | static 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 | */ | |
117 | static int | |
118 | set_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 | ||
137 | static void | |
138 | write_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 | ||
153 | static void | |
154 | write_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 | ||
183 | int | |
184 | main(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 | */ |