Restore SIGINT for stopping gnushogi when thinking.
[gnushogi.git] / gnushogi / init.c
1 /*
2  * FILE: init.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 #if defined HAVE_GETTIMEOFDAY
35 #include <sys/time.h>
36 #endif
37
38 #include <signal.h>
39
40 #include "pattern.h"
41
42 /****************************************
43  *     A variety of global flags.
44  ****************************************/
45
46 /*
47  * If hard_time_limit is nonzero, exceeding the time limit means
48  * losing the game.
49  */
50
51 short hard_time_limit = 1;
52 short barebones       = 0;  /* Suppress printing of statistics
53                              * (mainly for xshogi). */
54 #ifdef LIST_ON_EXIT
55 short nolist          = 0;  /* List the game after exit. */
56 #else
57 short nolist          = 1;  /* Don't list the game after exit. */
58 #endif
59
60 /*
61  * The default display type can be DISPLAY_RAW, DISPLAY_CURSES,
62  * or DISPLAY_X; the default is DISPLAY_X to make life easier for xshogi.
63  */
64
65 display_t display_type = DISPLAY_X;
66
67 unsigned int ttbllimit;
68
69 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
70
71
72 #define max(a, b) (((a) < (b))?(b):(a))
73 #define odd(a) ((a) & 1)
74
75
76 const small_short piece_of_ptype[NO_PTYPE_PIECES] =
77 {
78     pawn, lance, knight, silver, gold, bishop, rook, pbishop, prook, king,
79     pawn, lance, knight, silver, gold
80 };
81
82
83 const small_short side_of_ptype[NO_PTYPE_PIECES] =
84 {
85     black, black, black, black, black, black, black, black, black, black,
86     white, white, white, white, white
87 };
88
89 #ifdef SAVE_NEXTPOS
90 const small_short psweep[NO_PTYPE_PIECES] =
91 {
92     false, true, false, false, false, true, true, true, true, false,
93     false, true, false, false, false
94 };
95 #endif
96
97 const small_short sweep[NO_PIECES] =
98 {
99     false, false, true, false, false, false, true, true,
100     false, false, false, false, true, true, false
101 };
102
103
104 #if !defined EXTLANGFILE
105
106 char *CP[CPSIZE] =
107
108 {
109 /* 000: eng: */ "",
110 #ifdef LANGFILE
111 #include LANGFILE
112 #else
113 #include "gnushogi.lng"
114 #endif
115 };
116
117 #else
118
119 char *CP[CPSIZE];
120
121 #endif
122
123
124 /*
125  * Determine the minimum number of moves for a piece from
126  * square "f" to square "t". If the piece cannot reach "t",
127  * the count is set to CANNOT_REACH.
128  */
129
130 #define csquare(sq) ((side == black) ? sq : (NO_SQUARES - 1 - sq))
131 #define crow(sq) row(csquare(sq))
132 #define ccol(sq) column(csquare(sq))
133
134 short
135 ptype_distance(short ptyp, short f, short t)
136 {
137     short side, piece;
138     short colf, colt, rowf, rowt, dcol, drow;
139
140     if (f == t)
141         return 0;
142
143     piece = piece_of_ptype[ptyp];
144     side  = side_of_ptype[ptyp];
145
146     dcol = (colt = ccol(t)) - (colf = ccol(f));
147     drow = (rowt = crow(t)) - (rowf = crow(f));
148
149     switch (piece)
150     {
151     case pawn:
152         if ((dcol != 0) || (drow < 1))
153             return CANNOT_REACH;
154         else
155             return drow;
156
157     case lance:
158         if ((dcol != 0) || (drow < 1))
159             return CANNOT_REACH;
160         else
161             return 1;
162
163     case knight:
164         if (odd(drow) || (odd(drow / 2) != odd(dcol)))
165             return CANNOT_REACH;
166         else if ((drow == 0) || ((drow / 2) < abs(dcol)))
167             return CANNOT_REACH;
168         else
169             return (drow / 2);
170
171     case silver:
172         if (drow > 0)
173         {
174             if (odd(drow) == odd(dcol))
175             {
176                 return max(abs(drow), abs(dcol));
177             }
178             else
179             {
180                 if (abs(dcol) <= drow)
181                     return drow;
182                 else
183                     return (max(abs(drow), abs(dcol)) + 1);
184             }
185         }
186         else
187         {
188             if (odd(drow) == odd(dcol))
189                 return (max(abs(drow), abs(dcol)));
190             else
191                 return (max(abs(drow) + 1, abs(dcol)) + 1);
192         };
193
194     case gold:
195     case ppawn:
196     case pknight:
197     case plance:
198     case psilver:
199         if (abs(dcol) == 0)
200             return (abs(drow));
201         else if (drow >= 0)
202             return max(drow, abs(dcol));
203         else
204             return (abs(dcol) - drow);
205
206     case bishop:
207         if (odd(dcol) != odd(drow))
208             return CANNOT_REACH;
209         else
210             return ((abs(dcol) == abs(drow)) ? 1 : 2);
211
212     case pbishop:
213         if (odd(dcol) != odd(drow))
214         {
215             if ((abs(dcol) <= 1) && (abs(drow) <= 1))
216                 return 1;
217             else if (abs(abs(dcol) - abs(drow)) == 1)
218                 return 2;
219             else
220                 return 3;
221         }
222         else
223         {
224             return ((abs(dcol) == abs(drow)) ? 1 : 2);
225         }
226
227     case rook:
228         if ((dcol == 0) || (drow == 0))
229             return 1;
230         else
231             return 2;
232
233     case prook:
234         if ((dcol == 0) || (drow == 0))
235             return 1;
236         else if ((abs(dcol) == 1) && (abs(drow) == 1))
237             return 1;
238         else
239             return 2;
240
241     case king:
242         return max(abs(drow), abs(dcol));
243
244     default:
245         /* should never occur */
246         return (CANNOT_REACH);
247     }
248 }
249
250
251 #ifdef SAVE_DISTDATA
252 short
253 distance(short a, short b)
254 {
255     return (short)computed_distance(a, b);
256 }
257 #else
258 short
259 distance(short a, short b)
260 {
261     return (use_distdata
262             ? (short)(*distdata)[(int)a][(int)b]
263             : (short)computed_distance(a, b));
264 }
265 #endif
266
267
268 #ifdef SAVE_PTYPE_DISTDATA
269 short
270 piece_distance(short side, short piece, short f, short t)
271 {
272     return ((f > NO_SQUARES)
273             ? (short)1
274             : (short)ptype_distance(ptype[side][piece], f, t));
275 }
276 #else
277 short
278 piece_distance(short side, short piece, short f, short t)
279 {
280     return ((f > NO_SQUARES)
281             ? (short)1
282             : (use_ptype_distdata
283                ? (short)(*ptype_distdata[ptype[side][piece]])[f][t]
284                : (short)ptype_distance(ptype[side][piece], f, t)));
285 }
286 #endif
287
288
289 void
290 Initialize_dist(void)
291 {
292     short a, b, d, di, ptyp;
293 #ifndef SAVE_DISTDATA
294     for (a = 0; a < NO_SQUARES; a++)
295     {
296         for (b = 0; b < NO_SQUARES; b++)
297         {
298             d = abs(column(a) - column(b));
299             di = abs(row(a) - row(b));
300             (*distdata)[a][b] = (small_short)((d > di) ? d : di);
301         }
302     }
303 #endif
304 #ifndef SAVE_PTYPE_DISTDATA
305     for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
306     {
307         for (a = 0; a < NO_SQUARES; a++)
308             for (b = 0; b < NO_SQUARES; b++)
309                 (*ptype_distdata[ptyp])[a][b] = ptype_distance(ptyp, a, b);
310     }
311 #endif
312 }
313
314
315 /*
316  * nextpos[ptype][from-square], nextdir[ptype][from-square] gives vector
317  * of positions reachable from from-square in ppos with ptype such that the
318  * sequence
319  *
320  *     ppos = nextpos[ptype][from-square];
321  *     pdir = nextdir[ptype][from-square];
322  *     u = ppos[sq];
323  *
324  *     do
325  *     {
326  *         u = ppos[u];
327  *
328  *         if(color[u] != neutral)
329  *             u = pdir[u];
330  *     }
331  *     while (sq != u);
332  *
333  * will generate the sequence of all squares reachable from sq.
334  *
335  * If the path is blocked u = pdir[sq] will generate the continuation of the
336  * sequence in other directions.
337  */
338
339
340 /*
341  * ptype is used to separate black and white pawns, like this; ptyp =
342  * ptype[side][piece] piece can be used directly in nextpos/nextdir when
343  * generating moves for pieces that are not white pawns.
344  */
345
346 const small_short ptype[2][NO_PIECES] =
347 {
348     {
349         ptype_no_piece, ptype_pawn,  ptype_lance,  ptype_knight,
350         ptype_silver,   ptype_gold,  ptype_bishop, ptype_rook,
351         ptype_gold,     ptype_gold,  ptype_gold,   ptype_gold,
352         ptype_pbishop,  ptype_prook, ptype_king
353     },
354     {
355         ptype_no_piece, ptype_wpawn, ptype_wlance, ptype_wknight,
356         ptype_wsilver,  ptype_wgold, ptype_bishop, ptype_rook,
357         ptype_wgold,    ptype_wgold, ptype_wgold,  ptype_wgold,
358         ptype_pbishop,  ptype_prook, ptype_king
359     },
360 };
361
362 const small_short promoted[NO_PIECES] =
363 {
364     no_piece, ppawn, plance, pknight, psilver, gold, pbishop, prook,
365     ppawn, plance, pknight, psilver, pbishop, prook, king
366 };
367
368 const small_short unpromoted[NO_PIECES] =
369 {
370     no_piece, pawn, lance, knight, silver, gold, bishop, rook,
371     pawn, lance, knight, silver, bishop, rook, king
372 };
373
374 const small_short is_promoted[NO_PIECES] =
375 {
376     false, false, false, false, false, false, false, false,
377     true, true, true, true, true, true, false
378 };
379
380 /* data used to generate nextpos/nextdir */
381 #if !defined SAVE_NEXTPOS
382 static
383 #endif
384 const small_short direc[NO_PTYPE_PIECES][8] =
385 {
386     {  11,   0,   0,   0,   0,   0,   0,   0 },   /*  0 ptype_pawn    */
387     {  11,   0,   0,   0,   0,   0,   0,   0 },   /*  1 ptype_lance   */
388     {  21,  23,   0,   0,   0,   0,   0,   0 },   /*  2 ptype_knight  */
389     {  10,  11,  12, -12, -10,   0,   0,   0 },   /*  3 ptype_silver  */
390     {  10,  11,  12,  -1,   1, -11,   0,   0 },   /*  4 ptype_gold    */
391     {  10,  12, -12, -10,   0,   0,   0,   0 },   /*  5 ptype_bishop  */
392     {  11,  -1,   1, -11,   0,   0,   0,   0 },   /*  6 ptype_rook    */
393     {  10,  12, -12, -10,  11,  -1,   1, -11 },   /*  7 ptype_pbishop */
394     {  11,  -1,   1, -11,  10,  12, -12, -10 },   /*  8 ptype_prook   */
395     {  10,  11,  12,  -1,   1, -12, -11, -10 },   /*  9 ptype_king    */
396     { -11,   0,   0,   0,   0,   0,   0,   0 },   /* 10 ptype_wpawn   */
397     { -11,   0,   0,   0,   0,   0,   0,   0 },   /* 11 ptype_wlance  */
398     { -21, -23,   0,   0,   0,   0,   0,   0 },   /* 12 ptype_wknight */
399     { -10, -11, -12,  12,  10,   0,   0,   0 },   /* 13 ptype_wsilver */
400     { -10, -11, -12,   1,  -1,  11,   0,   0 }
401 };  /* 14 ptype_wgold */
402
403
404 small_short diagonal(short d)
405 {
406   return (abs(d) == (NO_COLS+1) || abs(d) == (NO_COLS+3));
407 }
408
409
410 static const small_short max_steps[NO_PTYPE_PIECES] =
411 {
412     1, 8, 1, 1, 1, 8, 8, 8, 8, 1, 1, 8, 1, 1, 1
413 };
414
415
416 const small_short nunmap[(NO_COLS + 2)*(NO_ROWS + 4)] =
417 {
418     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
419     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
420     -1,  0,  1,  2,  3,  4,  5,  6,  7,  8, -1,
421     -1,  9, 10, 11, 12, 13, 14, 15, 16, 17, -1,
422     -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1,
423     -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
424     -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1,
425     -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1,
426     -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1,
427     -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, -1,
428     -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, -1,
429     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
430     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
431 };
432
433
434 const small_short inunmap[NO_SQUARES] =
435 {
436      23,  24,  25,  26,  27,  28,  29,  30,  31,
437      34,  35,  36,  37,  38,  39,  40,  41,  42,
438      45,  46,  47,  48,  49,  50,  51,  52,  53,
439      56,  57,  58,  59,  60,  61,  62,  63,  64,
440      67,  68,  69,  70,  71,  72,  73,  74,  75,
441      78,  79,  80,  81,  82,  83,  84,  85,  86,
442      89,  90,  91,  92,  93,  94,  95,  96,  97,
443     100, 101, 102, 103, 104, 105, 106, 107, 108,
444     111, 112, 113, 114, 115, 116, 117, 118, 119
445 };
446
447
448 int InitFlag = false;
449
450
451 #if defined SAVE_NEXTPOS
452
453 short
454 next_direction(short ptyp, short *d, short sq)
455 {
456     short delta, to, sfrom = inunmap[sq];
457
458     do
459     {
460         (*d)++;
461         if (*d >= 8)
462             return sq;
463
464         delta = direc[ptyp][*d];
465         if (delta == 0)
466             return sq;
467
468         to = nunmap[sfrom + delta];
469     }
470     while (to < 0);
471
472     return to;
473 }
474
475
476 short
477 next_position(short ptyp, short *d, short sq, short u)
478 {
479     if (*d < 4 && psweep[ptyp])
480     {
481         short to = nunmap[inunmap[u] + direc[ptyp][*d]];
482
483         if (to < 0)
484             return next_direction(ptyp, d, sq);
485         else
486             return to;
487     }
488     else
489     {
490         return next_direction(ptyp, d, sq);
491     }
492 }
493
494
495 short
496 first_direction(short ptyp, short *d, short sq)
497 {
498     *d = -1;
499     return next_direction(ptyp, d, sq);
500 }
501
502 #else
503
504 /*
505  * This procedure pre-calculates all moves for every piece from every
506  * square.  This data is stored in nextpos/nextdir and used later in the
507  * move generation routines.
508  */
509
510 void
511 Initialize_moves(void)
512 {
513     short ptyp, po, p0, d, di, s, delta;
514     unsigned char *ppos, *pdir;
515     short dest[8][9];
516     short sorted[9];
517     short steps[8];
518     short fpo = inunmap[0], tpo = 1 + inunmap[NO_SQUARES-1];
519
520     /* pre-fill nextpos and nextdir with source position, probably so
521      * (color[u] == neutral) stops to match once all moves have been seen
522      */
523     for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
524     {
525         for (po = 0; po < NO_SQUARES; po++)
526         {
527             for (p0 = 0; p0 < NO_SQUARES; p0++)
528             {
529                 (*nextpos[ptyp])[po][p0] = (unsigned char)po;
530                 (*nextdir[ptyp])[po][p0] = (unsigned char)po;
531             }
532         }
533     }
534
535     for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
536     {
537         for (po = fpo; po < tpo; po++)
538         {
539             if (nunmap[po] >= (small_short)0)
540             {
541                 ppos = (*nextpos[ptyp])[nunmap[po]];
542                 pdir = (*nextdir[ptyp])[nunmap[po]];
543
544                 /* dest is a function of direction and steps */
545                 for (d = 0; d < 8; d++)
546                 {
547                     dest[d][0] = nunmap[po];
548                     delta = direc[ptyp][d];
549
550                     if (delta != 0)
551                     {
552                         p0 = po;
553
554                         for (s = 0; s < max_steps[ptyp]; s++)
555                         {
556                             p0 = p0 + delta;
557
558                             /*
559                              * break if (off board) or (promoted rooks
560                              * wishes to move two steps diagonal) or
561                              * (promoted bishops wishes to move two steps
562                              * non-diagonal)
563                              */
564                             if ((nunmap[p0] < (small_short)0)
565                                 || ((ptyp == ptype_prook)
566                                     && (s > 0)
567                                     && diagonal(delta))
568                                 || ((ptyp == ptype_pbishop)
569                                     && (s > 0)
570                                     && !diagonal(delta)))
571                                 break;
572                             else
573                                 dest[d][s] = nunmap[p0];
574                         }
575                     }
576                     else
577                     {
578                         s = 0;
579                     }
580
581                     /*
582                      * Sort dest in number of steps order; currently no sort
583                      * is done due to compatibility with the move generation
584                      * order in old gnuchess.
585                      */
586
587                     steps[d] = s;
588
589                     for (di = d; s > 0 && di > 0; di--)
590                     {
591                         if (steps[sorted[di - 1]] == 0) /* should be: < s */
592                             sorted[di] = sorted[di - 1];
593                         else
594                             break;
595                     }
596
597                     sorted[di] = d;
598                 }
599
600                 /*
601                  * update nextpos/nextdir
602                  */
603
604                 p0 = nunmap[po];
605                 pdir[p0] = (unsigned char)dest[sorted[0]][0];
606
607                 for (d = 0; d < 8; d++)
608                 {
609                     for (s = 0; s < steps[sorted[d]]; s++)
610                     {
611                         ppos[p0] = (unsigned char)dest[sorted[d]][s];
612                         p0 = dest[sorted[d]][s];
613
614                         if (d < 7)
615                             pdir[p0] = (unsigned char)dest[sorted[d + 1]][0];
616
617                         /*
618                          * else is already initialized
619                          */
620                     }
621                 }
622             }
623         }
624     }
625 }
626
627 #endif
628
629
630
631 /*
632  * Reset the board and other variables to start a new game.
633  */
634
635 void
636 NewGame(void)
637 {
638     short l, c, p, max_opening_sequence;
639 #ifdef HAVE_GETTIMEOFDAY
640     struct timeval tv;
641 #endif
642     compptr = oppptr = 0;
643     stage = 0;
644     stage2 = -1;    /* the game is not yet started */
645     flag.illegal = flag.mate = flag.post = flag.quit
646         = flag.reverse = flag.bothsides = flag.onemove = flag.force
647         = false;
648     flag.material = flag.coords = flag.hash = flag.easy
649         = flag.beep = flag.rcptr
650         = true;
651     flag.stars  = flag.shade = flag.back = flag.musttimeout = false;
652     flag.gamein = false;
653     flag.rv     = true;
654
655     mycnt1 = mycnt2 = 0;
656     GenCnt = NodeCnt = et0 = dither =  XCmore = 0;
657     znodes = ZNODES;
658     WAwindow = WAWNDW;
659     WBwindow = WBWNDW;
660     BAwindow = BAWNDW;
661     BBwindow = BBWNDW;
662     xwndw = BXWNDW;
663
664     if (!MaxSearchDepth)
665         MaxSearchDepth = MAXDEPTH - 1;
666
667     contempt = 0;
668     GameCnt = 0;
669     Game50 = 1;
670     CptrFlag[0] = TesujiFlag[0] = false;
671     hint = OPENING_HINT;
672     ZeroRPT();
673     GameType[0] = GameType[1] = UNKNOWN;
674     Pscore[0] = Tscore[0] = (SCORE_LIMIT + 3000);
675     opponent = player = black;
676     computer = white;
677
678     for (l = 0; l < TREE; l++)
679         Tree[l].f = Tree[l].t = 0;
680
681     gsrand((unsigned int) 1);
682
683     if (!InitFlag)
684     {
685         for (c = black; c <= white; c++)
686         {
687             for (p = pawn; p <= king; p++)
688             {
689                 for (l = 0; l < NO_SQUARES; l++)
690                 {
691                     (*hashcode)[c][p][l].key
692                          = (((unsigned long) urand()));
693                     (*hashcode)[c][p][l].key
694                         += (((unsigned long) urand()) << 16);
695                     (*hashcode)[c][p][l].bd
696                          = (((unsigned long) urand()));
697                     (*hashcode)[c][p][l].bd
698                         += (((unsigned long) urand()) << 16);
699 #if SIZEOF_LONG == 8  /* 64-bit long i.e. 8 bytes */
700                     (*hashcode)[c][p][l].key
701                         += (((unsigned long) urand()) << 32);
702                     (*hashcode)[c][p][l].key
703                         += (((unsigned long) urand()) << 48);
704                     (*hashcode)[c][p][l].bd
705                         += (((unsigned long) urand()) << 32);
706                     (*hashcode)[c][p][l].bd
707                         += (((unsigned long) urand()) << 48);
708 #endif
709                 }
710             }
711         }
712
713         for (c = black; c <= white; c++)
714         {
715             for (p = pawn; p <= king; p++)
716             {
717                 for (l = 0; l < MAX_CAPTURED; l++)
718                 {
719                     (*drop_hashcode)[c][p][l].key
720                          = (((unsigned long) urand()));
721                     (*drop_hashcode)[c][p][l].key
722                         += (((unsigned long) urand()) << 16);
723                     (*drop_hashcode)[c][p][l].bd
724                          = (((unsigned long) urand()));
725                     (*drop_hashcode)[c][p][l].bd
726                         += (((unsigned long) urand()) << 16);
727 #if SIZEOF_LONG == 8  /* 64-bit long i.e. 8 bytes */
728                     (*drop_hashcode)[c][p][l].key
729                         += (((unsigned long) urand()) << 32);
730                     (*drop_hashcode)[c][p][l].key
731                         += (((unsigned long) urand()) << 48);
732                     (*drop_hashcode)[c][p][l].bd
733                         += (((unsigned long) urand()) << 32);
734                     (*drop_hashcode)[c][p][l].bd
735                         += (((unsigned long) urand()) << 48);
736 #endif
737                 }
738             }
739         }
740     }
741
742     for (l = 0; l < NO_SQUARES; l++)
743     {
744         board[l] = Stboard[l];
745         color[l] = Stcolor[l];
746         Mvboard[l] = 0;
747     }
748
749     ClearCaptured();
750     ClearScreen();
751     InitializeStats();
752
753 #ifdef HAVE_GETTIMEOFDAY
754     gettimeofday(&tv, NULL);
755     time0 = tv.tv_sec*100 + tv.tv_usec/10000;
756 #else
757     time0 = time((long *) 0);
758 #endif
759
760     /* resetting reference time */
761     ElapsedTime(COMPUTE_AND_INIT_MODE);
762     flag.regularstart = true;
763     Book = BOOKFAIL;
764
765     if (!InitFlag)
766     {
767         char sx[256];
768         strcpy(sx, CP[169]);
769
770         if (TCflag)
771             SetTimeControl();
772         else if (MaxResponseTime == 0)
773             SelectLevel(sx);
774
775         UpdateDisplay(0, 0, 1, 0);
776         GetOpenings();
777         GetOpeningPatterns(&max_opening_sequence);
778
779         InitFlag = true;
780     }
781
782 #if ttblsz
783     if (TTadd)
784     {
785         ZeroTTable();
786         TTadd = 0;
787     }
788 #endif /* ttblsz */
789
790     hashbd = hashkey = 0;
791     return;
792 }
793
794
795
796 int
797 Initialize_data(void)
798 {
799     size_t n;
800     int i;
801     char buffer[60];
802     int doit = true;
803
804     {
805         small_short x = -1;
806
807         if (x >= 0)
808         {
809             ShowMessage("datatype 'small_short' is unsigned; "
810                         "check gnushogi.h\n");
811             return 1;
812         }
813     }
814
815     n = sizeof(struct leaf) * (size_t)TREE;
816     Tree = malloc(n);
817
818     if (!Tree)
819     {
820         sprintf(buffer, "Cannot allocate %ld bytes for search tree",
821                 (long)n);
822         ShowMessage(buffer);
823         return 1;
824     }
825
826     n = sizeof(hashcode_array);
827     hashcode = malloc(n);
828
829     if (!hashcode)
830     {
831         sprintf(buffer, "Cannot allocate %ld bytes for hashcode", (long)n);
832         ShowMessage(buffer);
833         return 1;
834     }
835
836     n = sizeof(drop_hashcode_array);
837     drop_hashcode = malloc(n);
838
839     if (!drop_hashcode)
840     {
841         sprintf(buffer,
842                 "Cannot allocate %ld bytes for drop_hashcode",
843                 (long)n);
844         ShowMessage(buffer);
845         return 1;
846     }
847
848     n = sizeof(struct GameRec) * (size_t)(MAXMOVES + MAXDEPTH);
849     GameList = malloc(n);
850
851     if (!GameList)
852     {
853         sprintf(buffer,
854                 "Cannot allocate %ld bytes for game record",
855                 (long)n);
856         ShowMessage(buffer);
857         return 1;
858     }
859
860 #if !defined SAVE_NEXTPOS
861     n = sizeof(next_array);
862
863     for (i = 0; i < NO_PTYPE_PIECES; i++)
864     {
865         nextdir[i] = use_nextpos ? malloc(n) : NULL;
866
867         if (!nextdir[i])
868         {
869             if (use_nextpos)
870             {
871                 sprintf(buffer, "cannot allocate %ld space for nextdir %d",
872                         (long)(n), i);
873                 ShowMessage(buffer);
874             }
875
876             nextdir[i] = NULL;
877             use_nextpos = false;
878         }
879
880         nextpos[i] = use_nextpos ? malloc(n) : NULL;
881
882         if (!nextpos[i])
883         {
884             if (use_nextpos)
885             {
886                 sprintf(buffer, "cannot allocate %ld space for nextpos %d",
887                         (long)(n), i);
888                 ShowMessage(buffer);
889             }
890
891             use_nextpos = false;
892         }
893     }
894
895     if (!use_nextpos)
896     {
897         return 1;
898     }
899 #endif
900
901     n = sizeof(value_array);
902     value = malloc(n);
903
904     if (!value)
905     {
906         ShowMessage("cannot allocate value space");
907         return 1;
908     }
909
910     n = sizeof(fscore_array);
911     fscore = malloc(n);
912
913     if (!fscore)
914     {
915         ShowMessage("cannot allocate fscore space");
916         return 1;
917     }
918
919 #if defined HISTORY
920     n = sizeof_history;
921     history = malloc(n);
922
923     if (!history)
924     {
925         sprintf(buffer, "Cannot allocate %ld bytes for history table",
926                 (long)sizeof_history);
927         ShowMessage(buffer);
928         use_history = false;
929     }
930 #endif
931
932 #if defined CACHE
933     n = sizeof(struct etable) * (size_t)ETABLE;
934
935     for (i = 0; i < 2; i++)
936     {
937         etab[i] = use_etable ? malloc(n) : 0;
938
939         if (!etab[i])
940         {
941             sprintf(buffer, "Cannot allocate %ld bytes for cache table %ld",
942                     (long)n, (long)i);
943             ShowMessage(buffer);
944             use_etable = false;
945         }
946     }
947 #endif
948
949 #if ttblsz
950
951     if (rehash < 0)
952         rehash = MAXrehash;
953
954     n = sizeof(struct hashentry)*(ttblsize + rehash);
955
956     while (doit && ttblsize > MINTTABLE)
957     {
958         ttable[0] = malloc(n);  /* FIXME: cast to the correct type. */
959         ttable[1] = ttable[0] ? malloc(n) : NULL;
960
961         if (!ttable[0] || !ttable[1])
962         {
963             if (!ttable[0])
964                 free(ttable[0]);
965
966             if (!ttable[1])
967                 free(ttable[1]);
968
969             ttblsize = ttblsize >> 1;
970             n = sizeof(struct hashentry) * (ttblsize + rehash);
971         }
972         else
973         {
974             doit = false;
975         }
976     }
977
978     if (ttblsize <= MINTTABLE)
979     {
980         use_ttable = false;
981     }
982
983     if (use_ttable)
984     {
985         /* CHECKME: is the precedence here correct? */
986         /* ttbllimit = ttblsize << 1 - ttblsize >> 2; */
987         ttbllimit = (ttblsize << 1) - (ttblsize >> 2);
988     }
989     else
990     {
991         sprintf(buffer, "Cannot allocate %ld bytes for transposition table",
992                 (long)(2 * n));
993         ShowMessage(buffer);
994         ttable[0] = ttable[1] = NULL;
995     }
996 #endif /* ttblsz */
997
998 #if !defined SAVE_DISTDATA
999     n = sizeof(distdata_array);
1000     distdata = malloc(n);
1001
1002     if (!distdata)
1003     {
1004         ShowMessage("cannot allocate distdata space...");
1005         use_distdata = false;
1006     }
1007 #endif
1008
1009 #if !defined SAVE_PTYPE_DISTDATA
1010     n = sizeof(distdata_array);
1011
1012     for (i = 0; i < NO_PTYPE_PIECES; i++)
1013     {
1014         ptype_distdata[i] = use_ptype_distdata ? malloc(n) : 0;
1015
1016         if (!ptype_distdata[i])
1017         {
1018             sprintf(buffer,
1019                     "cannot allocate %ld bytes for ptype_distdata %d...",
1020                     (long)n, i);
1021             use_ptype_distdata = false;
1022         }
1023     }
1024 #endif
1025
1026     return 0;
1027 }
1028
1029
1030 #if defined EXTLANGFILE
1031
1032 #ifdef OLDLANGFILE
1033
1034 void
1035 InitConst(char *lang)
1036 {
1037     FILE *constfile;
1038     char s[256];
1039     char sl[5];
1040     char buffer[120];
1041     int len, entry;
1042     char *p, *q;
1043     constfile = fopen(LANGFILE, "r");
1044
1045     if (!constfile)
1046     {
1047         ShowMessage("NO LANGFILE");
1048         exit(1);
1049     }
1050
1051     while (fgets(s, sizeof(s), constfile))
1052     {
1053         if (s[0] == '!')
1054             continue;
1055
1056         len = strlen(s);
1057
1058         for (q = &s[len]; q > &s[8]; q--)
1059             if (*q == '}')
1060                 break;
1061
1062         if (q == &s[8])
1063         {
1064             ShowMessage("{ error in cinstfile");
1065             exit(1);
1066         }
1067
1068         *q = '\0';
1069
1070         if ((s[3] != ':') || (s[7] != ':') || (s[8] != '{'))
1071         {
1072             sprintf(buffer, "Langfile format error %s", s);
1073             ShowMessage(buffer);
1074             exit(1);
1075         }
1076
1077         s[3] = s[7] = '\0';
1078
1079         if (lang == NULL)
1080         {
1081             lang = sl;
1082             strcpy(sl, &s[4]);
1083         }
1084
1085         if (strcmp(&s[4], lang))
1086             continue;
1087
1088         entry = atoi(s);
1089
1090         if ((entry < 0) || (entry >= CPSIZE))
1091         {
1092             ShowMessage("Langfile number error");
1093             exit(1);
1094         }
1095
1096         for (q = p = &s[9]; *p; p++)
1097         {
1098             if (*p != '\\')
1099             {
1100                 *q++ = *p;
1101             }
1102             else if (*(p + 1) == 'n')
1103             {
1104                 *q++ = '\n';
1105                 p++;
1106             }
1107         }
1108
1109         *q = '\0';
1110
1111         if ((entry < 0) || (entry > 255))
1112         {
1113             sprintf(buffer, "Langfile error %d\n", entry);
1114             ShowMessage(buffer);
1115             exit(0);
1116         }
1117
1118         CP[entry] = (char *)GLOBAL_ALLOC((unsigned) strlen(&s[9]) + 1);
1119
1120         if (CP[entry] == NULL)
1121         {
1122             char buffer[80];
1123             sprintf(buffer, "CP MALLOC, entry %d", entry);
1124             perror(buffer);
1125             exit(0);
1126         }
1127
1128         strcpy(CP[entry], &s[9]);
1129     }
1130
1131     fclose(constfile);
1132 }
1133
1134 #else
1135
1136 void
1137 InitConst(char *lang)
1138 {
1139     FILE *constfile;
1140     char s[256];
1141     char sl[5];
1142     char buffer[120];
1143     int len, entry;
1144     char *p, *q;
1145     constfile = fopen(LANGFILE, "r");
1146
1147     if (!constfile)
1148     {
1149         ShowMessage("NO LANGFILE");
1150         exit(1);
1151     }
1152
1153     while (fgets(s, sizeof(s), constfile))
1154     {
1155         if (s[0] == '!')
1156             continue;
1157
1158         len = strlen(s);
1159
1160         if ((len > 3) && (s[3] == ':') || (len > 7) && (s[7] == ':'))
1161         {
1162             ShowMessage("old Langfile error");
1163             exit(1);
1164         }
1165
1166         if (len <= 15)
1167         {
1168             ShowMessage("length error in Langfile");
1169             exit(1);
1170         }
1171
1172         for (q = &s[len]; q > &s[15]; q--)
1173         {
1174             if (*q == '"')
1175                 break;
1176         }
1177
1178         if (q == &s[15])
1179         {
1180             ShowMessage("\" error in Langfile");
1181             exit(1);
1182         }
1183
1184         *q = '\0';
1185
1186         if ((s[6] != ':') || (s[10] != ':') || (s[15] != '"'))
1187         {
1188             sprintf(buffer, "Langfile format error %s", s);
1189             ShowMessage(buffer);
1190             exit(1);
1191         }
1192
1193         s[6] = s[10] = '\0';
1194
1195         if (lang == NULL)
1196         {
1197             lang = sl;
1198             strcpy(sl, &s[7]);
1199         }
1200
1201         if (strcmp(&s[7], lang))
1202             continue;
1203
1204         entry = atoi(&s[3]);
1205
1206         if ((entry < 0) || (entry >= CPSIZE))
1207         {
1208             ShowMessage("Langfile number error");
1209             exit(1);
1210         }
1211
1212         for (q = p = &s[16]; *p; p++)
1213         {
1214             if (*p != '\\')
1215             {
1216                 *q++ = *p;
1217             }
1218             else if (*(p + 1) == 'n')
1219             {
1220                 *q++ = '\n';
1221                 p++;
1222             }
1223         }
1224
1225         *q = '\0';
1226
1227         if ((entry < 0) || (entry > 255))
1228         {
1229             sprintf(buffer, "Langfile error %d\n", entry);
1230             ShowMessage(buffer);
1231             exit(0);
1232         }
1233
1234         CP[entry] = (char *)GLOBAL_ALLOC((unsigned)strlen(&s[16]) + 1);
1235
1236         if (CP[entry] == NULL)
1237         {
1238             char buffer[80];
1239             sprintf(buffer, "CP MALLOC, entry %d", entry);
1240             perror(buffer);
1241             exit(0);
1242         }
1243
1244         strcpy(CP[entry], &s[16]);
1245     }
1246
1247     fclose(constfile);
1248 }
1249
1250 #endif
1251
1252 #endif
1253
1254
1255 int
1256 InitMain(void)
1257 {
1258     gsrand(starttime = ((unsigned int)time((long *)0)));    /* init urand */
1259
1260 #if ttblsz
1261     ttblsize = ttblsz;
1262     rehash = -1;
1263 #endif /* ttblsz */
1264
1265     if (Initialize_data() != 0)
1266         return 1;
1267
1268 #if defined EXTLANGFILE
1269     InitConst(Lang);
1270 #endif
1271
1272     strcpy(ColorStr[0], CP[118]);
1273     strcpy(ColorStr[1], CP[119]);
1274
1275     XC = 0;
1276     MaxResponseTime = 0;
1277
1278     if (XSHOGI)
1279     {
1280         signal(SIGINT, TerminateSearch);
1281
1282         TCmoves      = 40;
1283         TCminutes    = 5;
1284         TCseconds    = 0;
1285         TCadd        = 0;
1286
1287         TCflag       = true;
1288         OperatorTime = 0;
1289         barebones    = 1;
1290     }
1291     else
1292     {
1293         TCflag       = false;
1294         OperatorTime = 0;
1295         barebones    = 0;
1296     }
1297
1298     Initialize();
1299     Initialize_dist();
1300     Initialize_eval();
1301 #if !defined SAVE_NEXTPOS
1302     Initialize_moves();
1303 #endif
1304
1305     NewGame();
1306
1307     flag.easy = ahead;
1308     flag.hash = hash;
1309
1310     if (xwin)
1311         xwndw = atoi(xwin);
1312
1313 #ifdef HASHFILE
1314     hashfile = NULL;
1315 #endif
1316
1317 #if ttblsz
1318 #ifdef HASHFILE
1319     hashfile = fopen(HASHFILE, RWA_ACC);
1320
1321     if (hashfile)
1322     {
1323         fseek(hashfile, 0L, SEEK_END);
1324         filesz = ftell(hashfile) / sizeof(struct fileentry) - 1 - MAXrehash;
1325         hashmask = filesz >> 1;
1326         hashbase = hashmask + 1;
1327     }
1328 #endif /* HASHFILE */
1329 #endif /* ttblsz */
1330
1331     savefile[0] = '\0';
1332     listfile[0] = '\0';
1333
1334     return 0;
1335 }
1336
1337
1338 void
1339 ExitMain(void)
1340 {
1341 #if ttblsz
1342 #ifdef HASHFILE
1343     if (hashfile)
1344         fclose(hashfile);
1345 #endif /* HASHFILE */
1346 #endif /* ttblsz */
1347
1348     ExitShogi();
1349 }
1350