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