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