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