Changing license to GPL3 (and bumping version to 1.4.0).
[gnushogi.git] / gnushogi / makepattern.c
blob397f79950661a7c87e57b5dcedd8083f66bdf3c1
1 /*
2 * FILE: makepattern.c
4 * ----------------------------------------------------------------------
6 * Copyright (c) 2012 Free Software Foundation
8 * GNU SHOGI is based on GNU CHESS
10 * This file is part of GNU SHOGI.
12 * GNU Shogi is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 3 of the License,
15 * or (at your option) any later version.
17 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with GNU Shogi; see the file COPYING. If not, see
24 * <http://www.gnu.org/licenses/>.
25 * ----------------------------------------------------------------------
29 #include "gnushogi.h"
30 #include "pattern.h"
32 #define MAX_PATTERN_DATA 5000
33 #define MAX_OPENING_SEQUENCE 20
34 #define MAX_PATTERN 200
36 char *patternfile = PATTERNFILE;
38 #define is_digit(c) (((c) >= '0') && ((c) <= '9'))
39 #define is_alpha(c) ((((c) >= 'a') && ((c) <= 'z')) \
40 || (((c) >= 'A') && ((c) <= 'Z')))
41 #define eos(s) ((*s == '\0') || (*s == '\n'))
44 /* skip blanks and comments in brackets */
46 static void
47 skipbb(char **s)
49 while ((**s == ' ') || (**s == '|') || (**s == '['))
51 if (**s == '[')
53 while (**s != ']')
54 (*s)++;
57 (*s)++;
62 /* skip unsigned numbers */
64 static void
65 skipi(char **s)
67 while (is_digit(**s))
68 (*s)++;
70 skipbb(s);
74 static short
75 ScanPiece(char **s, small_short *side,
76 small_short *piece, small_short *square)
78 short isp, isw, c, r;
80 /* determine promotion status */
81 if (**s == '+')
82 isp = true, (*s)++; /* FIXME: split into two lines. */
83 else
84 isp = false;
86 /* determine side and piece */
87 for (c = 0; c < NO_PIECES; c++)
89 if ((isw = (**s == pxx[c])) || (**s == qxx[c]))
91 *piece = isp ? promoted[c] : unpromoted[c];
92 *side = isw;
93 (*s)++;
94 break;
98 if (c == NO_PIECES)
99 return 1;
101 if (**s == '*')
103 /* piece is captured */
104 (*s)++;
105 *square = NO_SQUARES + *piece;
107 else
109 /* determine column */
110 for (c = 0; c < NO_COLS; c++)
112 if (**s == cxx[c])
114 (*s)++;
115 break;
119 if (c >= NO_COLS)
120 return 1;
122 /* determine row */
123 for (r = 0; r < NO_ROWS; r++)
125 if (**s == rxx[r])
127 (*s)++;
128 break;
132 if (r >= NO_ROWS)
133 return 1;
135 /* determine square */
136 *square = r * NO_COLS + c;
139 skipbb(s);
140 return 0;
144 static short
145 ScanPattern (char *s, short *pindex)
147 small_short side, piece, square;
148 skipbb(&s); /* skip blanks and comments */
150 while (is_digit(*s))
152 pattern_data[(*pindex)++] = atoi(s);
153 skipi(&s);
156 pattern_data[(*pindex)++] = END_OF_LINKS;
157 skipbb(&s);
159 while (!eos(s))
161 if (ScanPiece(&s, &side, &piece, &square))
163 return 1;
165 else
167 pattern_data[(*pindex)++] = piece;
168 pattern_data[(*pindex)++] = (side ? -square : square);
173 pattern_data[(*pindex)++] = END_OF_FIELDS;
174 return 0;
178 void
179 ReadOpeningSequences (short *pindex)
182 FILE *fd;
183 char s[256];
184 short max_pattern = 0;
185 short max_opening_sequence = 0;
187 if ((fd = fopen (patternfile, "r")) == NULL)
188 fd = fopen ("gnushogi.pat", "r");
190 if (fd != NULL)
192 *pindex = 0;
194 while (fgets (s, 256, fd) != NULL)
196 if (*s == '#')
198 /* comment, skip line */
200 else if (is_alpha(*s))
202 if (max_opening_sequence++ > 0)
204 pattern_data[(*pindex)++] = END_OF_PATTERNS;
207 pattern_data[(*pindex)++] = ValueOfOpeningName(s);
209 else
211 if (ScanPattern(s, pindex))
213 ShowMessage("error in pattern sequence...");
214 exit(1);
216 else
218 max_pattern++;
223 pattern_data[(*pindex)++] = END_OF_PATTERNS;
224 pattern_data[(*pindex)++] = END_OF_SEQUENCES;
226 if (NOT_CURSES)
228 sprintf(s,
229 "Pattern: %d bytes for %d sequences with %d patterns.\n",
230 *pindex, max_opening_sequence, max_pattern);
231 ShowMessage(s);
233 fclose(fd);
235 else if (NOT_CURSES)
237 sprintf(s, "no pattern file '%s'", patternfile);
238 ShowMessage(s);
243 void
244 WriteOpeningSequences (short pindex)
246 FILE *fd;
247 short n = 0;
248 short max_pattern = 0;
249 short max_opening_sequence = 0;
251 fd = fopen ("pattern.inc", "w");
252 fprintf(fd, "#define MAX_PATTERN_DATA %d\n\n", pindex);
253 fprintf(fd, "small_short pattern_data[MAX_PATTERN_DATA] =\n{\n");
257 fprintf(fd, " %d,\n", pattern_data[n++]);
261 fprintf(fd, " ");
263 /* write links */
264 while (pattern_data[n] != END_OF_LINKS)
266 fprintf(fd, "%d, ", pattern_data[n++]);
269 fprintf(fd, "%d, ", pattern_data[n++]);
271 /* write pattern */
274 fprintf(fd, "%d,", pattern_data[n++]);
276 while (pattern_data[n] != END_OF_FIELDS);
278 fprintf(fd, "%d,\n", pattern_data[n++]);
279 max_pattern++;
281 while (pattern_data[n] != END_OF_PATTERNS);
283 fprintf(fd, " %d,\n", pattern_data[n++]);
284 max_opening_sequence++;
286 while (pattern_data[n] != END_OF_SEQUENCES);
288 fprintf(fd, " %d\n}; \n", pattern_data[n++]);
289 fprintf(fd, "\n#define MAX_OPENING_SEQUENCE %d\n", max_opening_sequence);
290 fprintf(fd, "\n#define MAX_PATTERN %d\n", max_pattern);
291 fclose(fd);