Bool transition: do not scanf directly into would-be bools.
[gnushogi.git] / gnushogi / makepattern.c
blob8b377d65e4a70f090dd27ec320a91a82c0936fe5
1 /*
2 * FILE: makepattern.c
4 * ----------------------------------------------------------------------
5 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
7 * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
9 * GNU SHOGI is based on GNU CHESS
11 * Copyright (c) 1988, 1989, 1990 John Stanback
12 * Copyright (c) 1992 Free Software Foundation
14 * This file is part of GNU SHOGI.
16 * GNU Shogi is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 3 of the License,
19 * or (at your option) any later version.
21 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 * for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with GNU Shogi; see the file COPYING. If not, see
28 * <http://www.gnu.org/licenses/>.
29 * ----------------------------------------------------------------------
33 #include "gnushogi.h"
34 #include "pattern.h"
36 #define MAX_PATTERN_DATA 5000
37 #define MAX_OPENING_SEQUENCE 20
38 #define MAX_PATTERN 200
40 bool xboard = false;
42 small_short pattern_data[MAX_PATTERN_DATA];
44 /* minimal ShowMessage to avoid dependency on extraneous display code */
45 static void
46 Dummy_ShowMessage(char *format, ...)
48 va_list ap;
49 va_start(ap, format);
50 vprintf(format, ap);
51 va_end(ap);
53 static struct display dummydsp = {
54 .ShowMessage = Dummy_ShowMessage,
56 struct display *dsp = &dummydsp;
58 #define is_digit(c) (((c) >= '0') && ((c) <= '9'))
59 #define is_alpha(c) ((((c) >= 'a') && ((c) <= 'z')) \
60 || (((c) >= 'A') && ((c) <= 'Z')))
61 #define eos(s) ((*s == '\0') || (*s == '\n'))
64 /* skip blanks and comments in brackets */
66 static void
67 skipbb(char **s)
69 while ((**s == ' ') || (**s == '|') || (**s == '['))
71 if (**s == '[')
73 while (**s != ']')
74 (*s)++;
77 (*s)++;
82 /* skip unsigned numbers */
84 static void
85 skipi(char **s)
87 while (is_digit(**s))
88 (*s)++;
90 skipbb(s);
94 static short
95 ScanPiece(char **s, small_short *side,
96 small_short *piece, small_short *square)
98 bool isp;
99 short isw, c, r;
101 /* determine promotion status */
102 if (**s == '+')
103 isp = true, (*s)++; /* FIXME: split into two lines. */
104 else
105 isp = false;
107 /* determine side and piece */
108 for (c = 0; c < NO_PIECES; c++)
110 if ((isw = (**s == pxx[c])) || (**s == qxx[c]))
112 *piece = isp ? promoted[c] : unpromoted[c];
113 *side = isw;
114 (*s)++;
115 break;
119 if (c == NO_PIECES)
120 return 1;
122 if (**s == '*')
124 /* piece is captured */
125 (*s)++;
126 *square = NO_SQUARES + *piece;
128 else
130 /* determine column */
131 for (c = 0; c < NO_COLS; c++)
133 if (**s == COL_NAME(c))
135 (*s)++;
136 break;
140 if (c >= NO_COLS)
141 return 1;
143 /* determine row */
144 for (r = 0; r < NO_ROWS; r++)
146 if (**s == ROW_NAME(r))
148 (*s)++;
149 break;
153 if (r >= NO_ROWS)
154 return 1;
156 /* determine square */
157 *square = r * NO_COLS + c;
160 skipbb(s);
161 return 0;
165 static short
166 ScanPattern (char *s, short *pindex)
168 small_short side, piece, square;
169 skipbb(&s); /* skip blanks and comments */
171 while (is_digit(*s))
173 pattern_data[(*pindex)++] = atoi(s);
174 skipi(&s);
177 pattern_data[(*pindex)++] = END_OF_LINKS;
178 skipbb(&s);
180 while (!eos(s))
182 if (ScanPiece(&s, &side, &piece, &square))
184 return 1;
186 else
188 pattern_data[(*pindex)++] = piece;
189 pattern_data[(*pindex)++] = (side ? -square : square);
194 pattern_data[(*pindex)++] = END_OF_FIELDS;
195 return 0;
199 void
200 ReadOpeningSequences (short *pindex, const char* patternfile)
202 FILE *fd;
203 char s[256];
204 short max_pattern = 0;
205 short max_opening_sequence = 0;
207 fd = fopen (patternfile, "r");
209 if (fd == NULL) {
210 sprintf(s, "no pattern file '%s'", patternfile);
211 dsp->ShowMessage(s);
212 return;
215 *pindex = 0;
217 while (fgets (s, 256, fd) != NULL)
219 if (*s == '#')
221 /* comment, skip line */
223 else if (is_alpha(*s))
225 if (max_opening_sequence++ > 0)
227 pattern_data[(*pindex)++] = END_OF_PATTERNS;
230 pattern_data[(*pindex)++] = ValueOfOpeningName(s);
232 else
234 if (ScanPattern(s, pindex))
236 dsp->ShowMessage("error in pattern sequence...");
237 exit(1);
239 else
241 max_pattern++;
246 pattern_data[(*pindex)++] = END_OF_PATTERNS;
247 pattern_data[(*pindex)++] = END_OF_SEQUENCES;
249 sprintf(s,
250 "Pattern: %d bytes for %d sequences with %d patterns.\n",
251 *pindex, max_opening_sequence, max_pattern);
252 dsp->ShowMessage(s);
254 fclose(fd);
258 void
259 WriteOpeningSequences (short pindex, const char* patternincfile)
261 FILE *fd;
262 short n = 0;
263 short max_pattern = 0;
264 short max_opening_sequence = 0;
266 fd = fopen (patternincfile, "w");
267 fprintf(fd, "#define MAX_PATTERN_DATA %d\n\n", pindex);
268 fprintf(fd, "small_short pattern_data[MAX_PATTERN_DATA] =\n{\n");
272 fprintf(fd, " %d,\n", pattern_data[n++]);
276 fprintf(fd, " ");
278 /* write links */
279 while (pattern_data[n] != END_OF_LINKS)
281 fprintf(fd, "%d, ", pattern_data[n++]);
284 fprintf(fd, "%d, ", pattern_data[n++]);
286 /* write pattern */
289 fprintf(fd, "%d,", pattern_data[n++]);
291 while (pattern_data[n] != END_OF_FIELDS);
293 fprintf(fd, "%d,\n", pattern_data[n++]);
294 max_pattern++;
296 while (pattern_data[n] != END_OF_PATTERNS);
298 fprintf(fd, " %d,\n", pattern_data[n++]);
299 max_opening_sequence++;
301 while (pattern_data[n] != END_OF_SEQUENCES);
303 fprintf(fd, " %d\n}; \n", pattern_data[n++]);
304 fprintf(fd, "\n#define MAX_OPENING_SEQUENCE %d\n", max_opening_sequence);
305 fprintf(fd, "\n#define MAX_PATTERN %d\n", max_pattern);
306 fclose(fd);