Stop hardcoding filenames inside pat2inc, use commandline parameters.
[gnushogi.git] / gnushogi / main.c
1 /*
2  * FILE: main.c
3  *
4  * ----------------------------------------------------------------------
5  * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6  * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
7  *
8  * GNU SHOGI is based on GNU CHESS
9  *
10  * Copyright (c) 1988, 1989, 1990 John Stanback
11  * Copyright (c) 1992 Free Software Foundation
12  *
13  * This file is part of GNU SHOGI.
14  *
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.
19  *
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.
24  *
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  * ----------------------------------------------------------------------
29  *
30  */
31
32 #include "gnushogi.h"
33
34 #include <signal.h>
35
36
37 void print_arglist(int argc, char **argv)
38 {
39     int i;
40
41     for (i = 0; i < argc; i++)
42         printf("argv[%d] = %s\n", i, argv[i]);
43
44     printf("\n");
45 }
46
47
48 int
49 main (int argc, char **argv)
50 {
51     /*
52      * Process command-line arguments.
53      */
54
55     /* Get rid of the program name. */
56
57     argc--;
58     argv++;
59
60     /* CHECKME: get rid of the '+' syntax? */
61
62     while ((argc > 0) && ((argv[0][0] == '-') || (argv[0][0] == '+')))
63     {
64         switch (argv[0][1])
65         {
66         case 'a':
67             /* Need the "+" syntax here... */
68             ahead = ((argv[0][0] == '-') ? false : true);
69             break;
70
71
72         case 'b':
73             argc--;
74             argv++;
75
76             if (argc > 0)
77             {
78                 bookfile = argv[0];
79 #ifdef BINBOOK
80                 binbookfile = NULL;
81 #endif
82             }
83             break;
84
85 #ifdef BINBOOK
86         case 'B':
87             argc--;
88             argv++;
89             if (argc > 0)
90                 binbookfile = argv[0];
91             break;
92 #endif
93
94 #ifdef HAVE_LIBCURSES
95         case 'C':
96             /* Curses interface. */
97             display_type = DISPLAY_CURSES;
98             dsp = &curses_display;
99             break;
100 #endif
101
102         case 'h':
103             /* Need the "+" syntax here... */
104             hash = ((argv[0][0] == '-') ? false : true);
105             break;
106
107         case 'l':
108             argc--;
109             argv++;
110
111             if (argc > 0)
112                 Lang = argv[0];
113             break;
114
115         case 'L':
116             argc--;
117             argv++;
118
119             if (argc > 0)
120                 strcpy(listfile, argv[0]);
121             break;
122
123         case 's':
124             argc--;
125             argv++;
126
127             if (argc > 0)
128                 strcpy(savefile, argv[0]);
129             break;
130
131         case 'P':
132             argc--;
133             argv++;
134
135             if (argc > 0)
136                 bookmaxply = atoi(argv[0]);
137             break;
138
139         case 'R':
140             /* Raw text interface. */
141             display_type = DISPLAY_RAW;
142             dsp = &raw_display;
143             break;
144
145         case 'S':
146             argc--;
147             argv++;
148
149             if (argc > 0)
150                 booksize = atoi(argv[0]);
151             break;
152
153 #if ttblsz
154         case 'r':
155             argc--;
156             argv++;
157
158             if (argc > 0)
159                 rehash = atoi(argv[0]);
160             if (rehash > MAXrehash)
161                 rehash = MAXrehash;
162             break;
163
164         case 'T':
165             argc--;
166             argv++;
167
168             if (argc > 0)
169                 ttblsize = atoi(argv[0]);
170             if (ttblsize <= MINTTABLE)
171                 ttblsize = (MINTTABLE) + 1;
172             break;
173
174 #ifdef HASHFILE
175         case 'c':   /* Create or test persistent transposition table. */
176             argc--;
177             argv++;
178
179             if (argc > 0)
180                 filesz = atoi(argv[0]);
181             else
182                 filesz = vfilesz;
183
184             if ((filesz > 0) && (filesz < 24))
185                 filesz = (1 << filesz) - 1 + MAXrehash;
186             else
187                 filesz = filesz + MAXrehash;
188
189             if ((hashfile = fopen(HASHFILE, RWA_ACC)) == NULL)
190                 hashfile = fopen(HASHFILE, WA_ACC);
191
192             if (hashfile != NULL)
193             {
194                 long j;
195                 struct fileentry n;
196
197                 fputs("Filling transposition file, wait!\n", stdout);
198                 n.f = n.t = 0;
199                 n.flags = 0;
200                 n.depth = 0;
201                 n.sh = n.sl = 0;
202
203                 for (j = 0; j < filesz + 1; j++)
204                     fwrite(&n, sizeof(struct fileentry), 1, hashfile);
205
206                 fclose(hashfile);
207             }
208             else
209             {
210                 printf("Create failed for %s\n", HASHFILE);
211             }
212
213             return 0;
214
215         case 't':   /* Create or test persistent transposition table. */
216             hashfile = fopen(HASHFILE, RWA_ACC);
217
218             if (hashfile)
219             {
220                 fseek(hashfile, 0L, SEEK_END);
221                 filesz = (ftell(hashfile) / (sizeof(struct fileentry))) - 1;
222             }
223
224             if (hashfile != NULL)
225             {
226                 long i, j;
227                 int nr[MAXDEPTH];
228                 struct fileentry n;
229
230                 fputs("Counting transposition file entries, wait!\n", stdout);
231
232                 for (i = 0; i < MAXDEPTH; i++)
233                     nr[i] = 0;
234
235                 fseek(hashfile, 0L, SEEK_END);
236                 i = ftell(hashfile) / (sizeof(struct fileentry));
237                 fseek(hashfile, 0L, SEEK_SET);
238
239                 for (j = 0; j < i + 1; j++)
240                 {
241                     fread(&n, sizeof(struct fileentry), 1, hashfile);
242
243                     if (n.depth > MAXDEPTH)
244                     {
245                         printf("ERROR\n");
246                         exit(1);
247                     }
248
249                     if (n.depth)
250                     {
251                         nr[n.depth]++;
252                         nr[0]++;
253                     }
254                 }
255
256                 printf("The file contains %d entries out of max %ld\n", nr[0], i);
257
258                 for (j = 1; j < MAXDEPTH; j++)
259                     printf("%d ", nr[j]);
260
261                 printf("\n");
262             }
263
264             return 0;
265
266 #endif /* HASHFILE */
267 #endif /* ttblsz */
268
269         case 'v':
270             fprintf(stderr, "gnushogi version %s\n", PACKAGE_VERSION);
271             exit(1);
272
273
274         case 'X':
275             /* X interface. */
276             display_type = DISPLAY_X;
277             dsp = &raw_display;
278             break;
279
280         case 'x':
281             argc--;
282             argv++;
283
284             if (argc > 0)
285                 xwin = argv[0];
286             break;
287
288         default:
289             fputs("Usage: gnushogi [-a] [-t] [-c size] [-s savefile][-l listfile] [-x xwndw]\n", stderr);
290             exit(1);
291         }
292
293         argc--;
294         argv++;
295     }
296
297     if (argc == 2)
298     {
299         char *p;
300
301         MaxResponseTime = 100L * strtol(argv[1], &p, 10);
302
303         if (*p == ':')
304         {
305             MaxResponseTime = 60L * MaxResponseTime +
306                 100L * strtol(++p, (char **) NULL, 10);
307         }
308
309         TCflag    = false;
310         TCmoves   = 0;
311         TCminutes = 0;
312         TCseconds = 0;
313     }
314
315     if (argc >= 3)
316     {
317         char *p;
318
319         if (argc > 9)
320         {
321             printf("Time Control Error\n");
322             exit(1);
323         }
324
325         TCmoves   = atoi(argv[1]);
326         TCminutes = (short)strtol(argv[2], &p, 10);
327
328         if (*p == ':')
329             TCseconds = (short)strtol(p + 1, (char **) NULL, 10);
330         else
331             TCseconds = 0;
332
333         TCflag = true;
334         argc -= 3;
335         argv += 3;
336
337         while (argc > 1)
338         {
339             XCmoves[XC]   = atoi(argv[0]);
340             XCminutes[XC] = (short)strtol(argv[1], &p, 10);
341
342             if (*p == ':')
343                 XCseconds[XC] = (short)strtol(p + 1, (char **) NULL, 10);
344             else
345                 XCseconds[XC] = 0;
346
347             if (XCmoves[XC] && (XCminutes[XC] || XCseconds[XC]))
348                 XC++;
349             else
350             {
351                 printf("Time Control Error\n");
352                 exit(1);
353             }
354
355             argc -= 2;
356             argv += 2;
357         }
358
359         if (argc)
360         {
361             /*
362              * If we got here, there are unknown arguments, so issue
363              * an error message and quit.
364              */
365
366             printf("Invalid command-line arguments:\n");
367             print_arglist(argc, argv);
368             exit(1);
369         }
370     }
371
372     if (InitMain() != 0)
373         exit(1);
374
375     while (!flag.quit)
376     {
377         oppptr = (oppptr + 1) % MINGAMEIN;
378
379         if (flag.bothsides && !flag.mate)
380             SelectMove(opponent, FOREGROUND_MODE);
381         else
382             InputCommand(NULL);
383
384         if (opponent == white)
385         {
386             if (flag.gamein || TCadd)
387             {
388                 TimeCalc();
389             }
390             else if (TimeControl.moves[opponent] == 0)
391             {
392                 if (XC)
393                 {
394                     if (XCmore < XC)
395                     {
396                         TCmoves   = XCmoves[XCmore];
397                         TCminutes = XCminutes[XCmore];
398                         TCseconds = XCseconds[XCmore];
399                         XCmore++;
400                     }
401                 }
402
403                 SetTimeControl();
404             }
405         }
406
407         compptr = (compptr + 1) % MINGAMEIN;
408
409         if (!(flag.quit || flag.mate || flag.force))
410         {
411 #ifdef INTERRUPT_TEST
412             printf("starting search...\n");
413 #endif
414             SelectMove(computer, FOREGROUND_MODE);
415
416             if (computer == white)
417             {
418                 if (flag.gamein)
419                 {
420                     TimeCalc();
421                 }
422                 else if (TimeControl.moves[computer] == 0)
423                 {
424                     if (XC)
425                     {
426                         if (XCmore < XC)
427                         {
428                             TCmoves = XCmoves[XCmore];
429                             TCminutes = XCminutes[XCmore];
430                             TCseconds = XCseconds[XCmore];
431                             XCmore++;
432                         }
433                     }
434
435                     SetTimeControl();
436                 }
437             }
438         }
439     }
440
441     ExitMain();
442
443     return 0;
444 }
445
446