Merge branch 'maint'
[gnushogi.git] / gnushogi / makepattern.c
blobcf869e270d4f633b644b6d1fcf5d519ed8844e18
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
8 * GNU SHOGI is based on GNU CHESS
10 * Copyright (c) 1988, 1989, 1990 John Stanback
11 * Copyright (c) 1992 Free Software Foundation
13 * This file is part of GNU SHOGI.
15 * GNU Shogi is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 3 of the License,
18 * or (at your option) any later version.
20 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * for more details.
25 * You should have received a copy of the GNU General Public License along
26 * with GNU Shogi; see the file COPYING. If not, see
27 * <http://www.gnu.org/licenses/>.
28 * ----------------------------------------------------------------------
32 #include "gnushogi.h"
33 #include "pattern.h"
35 #define MAX_PATTERN_DATA 5000
36 #define MAX_OPENING_SEQUENCE 20
37 #define MAX_PATTERN 200
39 static char *patternfile = PATTERNFILE;
40 small_short pattern_data[MAX_PATTERN_DATA];
42 /* minimal ShowMessage to avoid dependency on extraneous display code */
43 static void
44 Dummy_ShowMessage(char *s)
46 printf("%s\n", s);
48 static struct display dummydsp = {
49 .ShowMessage = Dummy_ShowMessage,
51 struct display *dsp = &dummydsp;
53 #define is_digit(c) (((c) >= '0') && ((c) <= '9'))
54 #define is_alpha(c) ((((c) >= 'a') && ((c) <= 'z')) \
55 || (((c) >= 'A') && ((c) <= 'Z')))
56 #define eos(s) ((*s == '\0') || (*s == '\n'))
59 /* skip blanks and comments in brackets */
61 static void
62 skipbb(char **s)
64 while ((**s == ' ') || (**s == '|') || (**s == '['))
66 if (**s == '[')
68 while (**s != ']')
69 (*s)++;
72 (*s)++;
77 /* skip unsigned numbers */
79 static void
80 skipi(char **s)
82 while (is_digit(**s))
83 (*s)++;
85 skipbb(s);
89 static short
90 ScanPiece(char **s, small_short *side,
91 small_short *piece, small_short *square)
93 short isp, isw, c, r;
95 /* determine promotion status */
96 if (**s == '+')
97 isp = true, (*s)++; /* FIXME: split into two lines. */
98 else
99 isp = false;
101 /* determine side and piece */
102 for (c = 0; c < NO_PIECES; c++)
104 if ((isw = (**s == pxx[c])) || (**s == qxx[c]))
106 *piece = isp ? promoted[c] : unpromoted[c];
107 *side = isw;
108 (*s)++;
109 break;
113 if (c == NO_PIECES)
114 return 1;
116 if (**s == '*')
118 /* piece is captured */
119 (*s)++;
120 *square = NO_SQUARES + *piece;
122 else
124 /* determine column */
125 for (c = 0; c < NO_COLS; c++)
127 if (**s == cxx[c])
129 (*s)++;
130 break;
134 if (c >= NO_COLS)
135 return 1;
137 /* determine row */
138 for (r = 0; r < NO_ROWS; r++)
140 if (**s == rxx[r])
142 (*s)++;
143 break;
147 if (r >= NO_ROWS)
148 return 1;
150 /* determine square */
151 *square = r * NO_COLS + c;
154 skipbb(s);
155 return 0;
159 static short
160 ScanPattern (char *s, short *pindex)
162 small_short side, piece, square;
163 skipbb(&s); /* skip blanks and comments */
165 while (is_digit(*s))
167 pattern_data[(*pindex)++] = atoi(s);
168 skipi(&s);
171 pattern_data[(*pindex)++] = END_OF_LINKS;
172 skipbb(&s);
174 while (!eos(s))
176 if (ScanPiece(&s, &side, &piece, &square))
178 return 1;
180 else
182 pattern_data[(*pindex)++] = piece;
183 pattern_data[(*pindex)++] = (side ? -square : square);
188 pattern_data[(*pindex)++] = END_OF_FIELDS;
189 return 0;
193 void
194 ReadOpeningSequences (short *pindex)
196 FILE *fd;
197 char s[256];
198 short max_pattern = 0;
199 short max_opening_sequence = 0;
201 if ((fd = fopen (patternfile, "r")) == NULL)
202 fd = fopen ("gnushogi.pat", "r");
204 if (fd != NULL)
206 *pindex = 0;
208 while (fgets (s, 256, fd) != NULL)
210 if (*s == '#')
212 /* comment, skip line */
214 else if (is_alpha(*s))
216 if (max_opening_sequence++ > 0)
218 pattern_data[(*pindex)++] = END_OF_PATTERNS;
221 pattern_data[(*pindex)++] = ValueOfOpeningName(s);
223 else
225 if (ScanPattern(s, pindex))
227 dsp->ShowMessage("error in pattern sequence...");
228 exit(1);
230 else
232 max_pattern++;
237 pattern_data[(*pindex)++] = END_OF_PATTERNS;
238 pattern_data[(*pindex)++] = END_OF_SEQUENCES;
240 sprintf(s,
241 "Pattern: %d bytes for %d sequences with %d patterns.\n",
242 *pindex, max_opening_sequence, max_pattern);
243 dsp->ShowMessage(s);
245 fclose(fd);
246 } else {
247 sprintf(s, "no pattern file '%s'", patternfile);
248 dsp->ShowMessage(s);
253 void
254 WriteOpeningSequences (short pindex)
256 FILE *fd;
257 short n = 0;
258 short max_pattern = 0;
259 short max_opening_sequence = 0;
261 fd = fopen ("pattern.inc", "w");
262 fprintf(fd, "#define MAX_PATTERN_DATA %d\n\n", pindex);
263 fprintf(fd, "small_short pattern_data[MAX_PATTERN_DATA] =\n{\n");
267 fprintf(fd, " %d,\n", pattern_data[n++]);
271 fprintf(fd, " ");
273 /* write links */
274 while (pattern_data[n] != END_OF_LINKS)
276 fprintf(fd, "%d, ", pattern_data[n++]);
279 fprintf(fd, "%d, ", pattern_data[n++]);
281 /* write pattern */
284 fprintf(fd, "%d,", pattern_data[n++]);
286 while (pattern_data[n] != END_OF_FIELDS);
288 fprintf(fd, "%d,\n", pattern_data[n++]);
289 max_pattern++;
291 while (pattern_data[n] != END_OF_PATTERNS);
293 fprintf(fd, " %d,\n", pattern_data[n++]);
294 max_opening_sequence++;
296 while (pattern_data[n] != END_OF_SEQUENCES);
298 fprintf(fd, " %d\n}; \n", pattern_data[n++]);
299 fprintf(fd, "\n#define MAX_OPENING_SEQUENCE %d\n", max_opening_sequence);
300 fprintf(fd, "\n#define MAX_PATTERN %d\n", max_pattern);
301 fclose(fd);