Updating to version 1.3, release made by Mike Vanier (mvanier@bbb.caltech.edu).
[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 1, or (at your option) any
18  * 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, write to the Free
27  * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
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[piece][from-square], nextdir[piece][from-square] gives vector
317  * of positions reachable from from-square in ppos with piece such that the
318  * sequence
319  *
320  *     ppos = nextpos[piece][from-square];
321  *     pdir = nextdir[piece][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) == 10 || abs(d) == 12);
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 = 23, tpo = 120;
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(SIGINT, 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