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