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