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