Updating to version 1.3, release made by Mike Vanier (mvanier@bbb.caltech.edu).
[gnushogi.git] / gnushogi / makepattern.c
blobb2e618a1635a50c053e61a55e415ce856f7f67cc
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 1, or (at your option) any
18 * 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, write to the Free
27 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
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 char *patternfile = PATTERNFILE;
41 #define is_digit(c) (((c) >= '0') && ((c) <= '9'))
42 #define is_alpha(c) ((((c) >= 'a') && ((c) <= 'z')) \
43 || (((c) >= 'A') && ((c) <= 'Z')))
44 #define eos(s) ((*s == '\0') || (*s == '\n'))
47 /* skip blanks and comments in brackets */
49 static void
50 skipbb(char **s)
52 while ((**s == ' ') || (**s == '|') || (**s == '['))
54 if (**s == '[')
56 while (**s != ']')
57 (*s)++;
60 (*s)++;
65 /* skip unsigned numbers */
67 static void
68 skipi(char **s)
70 while (is_digit(**s))
71 (*s)++;
73 skipbb(s);
77 static short
78 ScanPiece(char **s, small_short *side,
79 small_short *piece, small_short *square)
81 short isp, isw, c, r;
83 /* determine promotion status */
84 if (**s == '+')
85 isp = true, (*s)++; /* FIXME: split into two lines. */
86 else
87 isp = false;
89 /* determine side and piece */
90 for (c = 0; c < NO_PIECES; c++)
92 if ((isw = (**s == pxx[c])) || (**s == qxx[c]))
94 *piece = isp ? promoted[c] : unpromoted[c];
95 *side = isw;
96 (*s)++;
97 break;
101 if (c == NO_PIECES)
102 return 1;
104 if (**s == '*')
106 /* piece is captured */
107 (*s)++;
108 *square = NO_SQUARES + *piece;
110 else
112 /* determine column */
113 for (c = 0; c < NO_COLS; c++)
115 if (**s == cxx[c])
117 (*s)++;
118 break;
122 if (c >= NO_COLS)
123 return 1;
125 /* determine row */
126 for (r = 0; r < NO_ROWS; r++)
128 if (**s == rxx[r])
130 (*s)++;
131 break;
135 if (r >= NO_ROWS)
136 return 1;
138 /* determine square */
139 *square = r * NO_COLS + c;
142 skipbb(s);
143 return 0;
147 static short
148 ScanPattern (char *s, short *pindex)
150 small_short side, piece, square;
151 skipbb(&s); /* skip blanks and comments */
153 while (is_digit(*s))
155 pattern_data[(*pindex)++] = atoi(s);
156 skipi(&s);
159 pattern_data[(*pindex)++] = END_OF_LINKS;
160 skipbb(&s);
162 while (!eos(s))
164 if (ScanPiece(&s, &side, &piece, &square))
166 return 1;
168 else
170 pattern_data[(*pindex)++] = piece;
171 pattern_data[(*pindex)++] = (side ? -square : square);
176 pattern_data[(*pindex)++] = END_OF_FIELDS;
177 return 0;
181 void
182 ReadOpeningSequences (short *pindex)
185 FILE *fd;
186 char s[256];
187 short max_pattern = 0;
188 short max_opening_sequence = 0;
190 if ((fd = fopen (patternfile, "r")) == NULL)
191 fd = fopen ("gnushogi.pat", "r");
193 if (fd != NULL)
195 *pindex = 0;
197 while (fgets (s, 256, fd) != NULL)
199 if (*s == '#')
201 /* comment, skip line */
203 else if (is_alpha(*s))
205 if (max_opening_sequence++ > 0)
207 pattern_data[(*pindex)++] = END_OF_PATTERNS;
210 pattern_data[(*pindex)++] = ValueOfOpeningName(s);
212 else
214 if (ScanPattern(s, pindex))
216 ShowMessage("error in pattern sequence...");
217 exit(1);
219 else
221 max_pattern++;
226 pattern_data[(*pindex)++] = END_OF_PATTERNS;
227 pattern_data[(*pindex)++] = END_OF_SEQUENCES;
229 if (NOT_CURSES)
231 sprintf(s,
232 "Pattern: %d bytes for %d sequences with %d patterns.\n",
233 *pindex, max_opening_sequence, max_pattern);
234 ShowMessage(s);
236 fclose(fd);
238 else if (NOT_CURSES)
240 sprintf(s, "no pattern file '%s'", patternfile);
241 ShowMessage(s);
246 void
247 WriteOpeningSequences (short pindex)
249 FILE *fd;
250 short n = 0;
251 short max_pattern = 0;
252 short max_opening_sequence = 0;
254 fd = fopen ("pattern.inc", "w");
255 fprintf(fd, "#define MAX_PATTERN_DATA %d\n\n", pindex);
256 fprintf(fd, "small_short pattern_data[MAX_PATTERN_DATA] =\n{\n");
260 fprintf(fd, " %d,\n", pattern_data[n++]);
264 fprintf(fd, " ");
266 /* write links */
267 while (pattern_data[n] != END_OF_LINKS)
269 fprintf(fd, "%d, ", pattern_data[n++]);
272 fprintf(fd, "%d, ", pattern_data[n++]);
274 /* write pattern */
277 fprintf(fd, "%d,", pattern_data[n++]);
279 while (pattern_data[n] != END_OF_FIELDS);
281 fprintf(fd, "%d,\n", pattern_data[n++]);
282 max_pattern++;
284 while (pattern_data[n] != END_OF_PATTERNS);
286 fprintf(fd, " %d,\n", pattern_data[n++]);
287 max_opening_sequence++;
289 while (pattern_data[n] != END_OF_SEQUENCES);
291 fprintf(fd, " %d\n}; \n", pattern_data[n++]);
292 fprintf(fd, "\n#define MAX_OPENING_SEQUENCE %d\n", max_opening_sequence);
293 fprintf(fd, "\n#define MAX_PATTERN %d\n", max_pattern);
294 fclose(fd);