Update maintainership info in AUTHORS.
[gnushogi.git] / gnushogi / makepattern.c
blob0d510d929cf833a8203667d8c7c8a48b58244019
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 static char *patternfile = PATTERNFILE;
41 small_short pattern_data[MAX_PATTERN_DATA];
43 /* minimal ShowMessage to avoid dependency on extraneous display code */
44 void
45 ShowMessage(char *s)
47 printf("%s\n", s);
50 #define is_digit(c) (((c) >= '0') && ((c) <= '9'))
51 #define is_alpha(c) ((((c) >= 'a') && ((c) <= 'z')) \
52 || (((c) >= 'A') && ((c) <= 'Z')))
53 #define eos(s) ((*s == '\0') || (*s == '\n'))
56 /* skip blanks and comments in brackets */
58 static void
59 skipbb(char **s)
61 while ((**s == ' ') || (**s == '|') || (**s == '['))
63 if (**s == '[')
65 while (**s != ']')
66 (*s)++;
69 (*s)++;
74 /* skip unsigned numbers */
76 static void
77 skipi(char **s)
79 while (is_digit(**s))
80 (*s)++;
82 skipbb(s);
86 static short
87 ScanPiece(char **s, small_short *side,
88 small_short *piece, small_short *square)
90 short isp, isw, c, r;
92 /* determine promotion status */
93 if (**s == '+')
94 isp = true, (*s)++; /* FIXME: split into two lines. */
95 else
96 isp = false;
98 /* determine side and piece */
99 for (c = 0; c < NO_PIECES; c++)
101 if ((isw = (**s == pxx[c])) || (**s == qxx[c]))
103 *piece = isp ? promoted[c] : unpromoted[c];
104 *side = isw;
105 (*s)++;
106 break;
110 if (c == NO_PIECES)
111 return 1;
113 if (**s == '*')
115 /* piece is captured */
116 (*s)++;
117 *square = NO_SQUARES + *piece;
119 else
121 /* determine column */
122 for (c = 0; c < NO_COLS; c++)
124 if (**s == cxx[c])
126 (*s)++;
127 break;
131 if (c >= NO_COLS)
132 return 1;
134 /* determine row */
135 for (r = 0; r < NO_ROWS; r++)
137 if (**s == rxx[r])
139 (*s)++;
140 break;
144 if (r >= NO_ROWS)
145 return 1;
147 /* determine square */
148 *square = r * NO_COLS + c;
151 skipbb(s);
152 return 0;
156 static short
157 ScanPattern (char *s, short *pindex)
159 small_short side, piece, square;
160 skipbb(&s); /* skip blanks and comments */
162 while (is_digit(*s))
164 pattern_data[(*pindex)++] = atoi(s);
165 skipi(&s);
168 pattern_data[(*pindex)++] = END_OF_LINKS;
169 skipbb(&s);
171 while (!eos(s))
173 if (ScanPiece(&s, &side, &piece, &square))
175 return 1;
177 else
179 pattern_data[(*pindex)++] = piece;
180 pattern_data[(*pindex)++] = (side ? -square : square);
185 pattern_data[(*pindex)++] = END_OF_FIELDS;
186 return 0;
190 void
191 ReadOpeningSequences (short *pindex)
193 FILE *fd;
194 char s[256];
195 short max_pattern = 0;
196 short max_opening_sequence = 0;
198 if ((fd = fopen (patternfile, "r")) == NULL)
199 fd = fopen ("gnushogi.pat", "r");
201 if (fd != NULL)
203 *pindex = 0;
205 while (fgets (s, 256, fd) != NULL)
207 if (*s == '#')
209 /* comment, skip line */
211 else if (is_alpha(*s))
213 if (max_opening_sequence++ > 0)
215 pattern_data[(*pindex)++] = END_OF_PATTERNS;
218 pattern_data[(*pindex)++] = ValueOfOpeningName(s);
220 else
222 if (ScanPattern(s, pindex))
224 ShowMessage("error in pattern sequence...");
225 exit(1);
227 else
229 max_pattern++;
234 pattern_data[(*pindex)++] = END_OF_PATTERNS;
235 pattern_data[(*pindex)++] = END_OF_SEQUENCES;
237 sprintf(s,
238 "Pattern: %d bytes for %d sequences with %d patterns.\n",
239 *pindex, max_opening_sequence, max_pattern);
240 ShowMessage(s);
242 fclose(fd);
243 } else {
244 sprintf(s, "no pattern file '%s'", patternfile);
245 ShowMessage(s);
250 void
251 WriteOpeningSequences (short pindex)
253 FILE *fd;
254 short n = 0;
255 short max_pattern = 0;
256 short max_opening_sequence = 0;
258 fd = fopen ("pattern.inc", "w");
259 fprintf(fd, "#define MAX_PATTERN_DATA %d\n\n", pindex);
260 fprintf(fd, "small_short pattern_data[MAX_PATTERN_DATA] =\n{\n");
264 fprintf(fd, " %d,\n", pattern_data[n++]);
268 fprintf(fd, " ");
270 /* write links */
271 while (pattern_data[n] != END_OF_LINKS)
273 fprintf(fd, "%d, ", pattern_data[n++]);
276 fprintf(fd, "%d, ", pattern_data[n++]);
278 /* write pattern */
281 fprintf(fd, "%d,", pattern_data[n++]);
283 while (pattern_data[n] != END_OF_FIELDS);
285 fprintf(fd, "%d,\n", pattern_data[n++]);
286 max_pattern++;
288 while (pattern_data[n] != END_OF_PATTERNS);
290 fprintf(fd, " %d,\n", pattern_data[n++]);
291 max_opening_sequence++;
293 while (pattern_data[n] != END_OF_SEQUENCES);
295 fprintf(fd, " %d\n}; \n", pattern_data[n++]);
296 fprintf(fd, "\n#define MAX_OPENING_SEQUENCE %d\n", max_opening_sequence);
297 fprintf(fd, "\n#define MAX_PATTERN %d\n", max_pattern);
298 fclose(fd);