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