Finally get rid of that highly non-standard use of SIGINT.
[gnushogi.git] / gnushogi / init.c
blob7b9663b24356353ad3c0d0673e21eadd903f0052
1 /*
2 * FILE: init.c
4 * ----------------------------------------------------------------------
5 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
8 * GNU SHOGI is based on GNU CHESS
10 * Copyright (c) 1988, 1989, 1990 John Stanback
11 * Copyright (c) 1992 Free Software Foundation
13 * This file is part of GNU SHOGI.
15 * GNU Shogi is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 3 of the License,
18 * or (at your option) any later version.
20 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
21 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * for more details.
25 * You should have received a copy of the GNU General Public License along
26 * with GNU Shogi; see the file COPYING. If not, see
27 * <http://www.gnu.org/licenses/>.
28 * ----------------------------------------------------------------------
32 #include "gnushogi.h"
34 #if defined HAVE_GETTIMEOFDAY
35 #include <sys/time.h>
36 #endif
38 #include <signal.h>
40 #include "pattern.h"
42 /****************************************
43 * A variety of global flags.
44 ****************************************/
47 * If hard_time_limit is nonzero, exceeding the time limit means
48 * losing the game.
51 short hard_time_limit = 1;
52 short barebones = 0; /* Suppress printing of statistics
53 * (mainly for xshogi). */
54 #ifdef LIST_ON_EXIT
55 short nolist = 0; /* List the game after exit. */
56 #else
57 short nolist = 1; /* Don't list the game after exit. */
58 #endif
61 * The default display type can be DISPLAY_RAW, DISPLAY_CURSES,
62 * or DISPLAY_X; the default is DISPLAY_X to make life easier for xshogi.
65 display_t display_type = DISPLAY_X;
67 unsigned int ttbllimit;
69 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
72 #define max(a, b) (((a) < (b))?(b):(a))
73 #define odd(a) ((a) & 1)
76 const small_short piece_of_ptype[NO_PTYPE_PIECES] =
78 pawn, lance, knight, silver, gold, bishop, rook, pbishop, prook, king,
79 pawn, lance, knight, silver, gold
83 const small_short side_of_ptype[NO_PTYPE_PIECES] =
85 black, black, black, black, black, black, black, black, black, black,
86 white, white, white, white, white
89 #ifdef SAVE_NEXTPOS
90 const small_short psweep[NO_PTYPE_PIECES] =
92 false, true, false, false, false, true, true, true, true, false,
93 false, true, false, false, false
95 #endif
97 const small_short sweep[NO_PIECES] =
99 false, false, true, false, false, false, true, true,
100 false, false, false, false, true, true, false
104 #if !defined EXTLANGFILE
106 char *CP[CPSIZE] =
109 /* 000: eng: */ "",
110 #ifdef LANGFILE
111 #include LANGFILE
112 #else
113 #include "gnushogi.lng"
114 #endif
117 #else
119 char *CP[CPSIZE];
121 #endif
125 * Determine the minimum number of moves for a piece from
126 * square "f" to square "t". If the piece cannot reach "t",
127 * the count is set to CANNOT_REACH.
130 #define csquare(sq) ((side == black) ? sq : (NO_SQUARES - 1 - sq))
131 #define crow(sq) row(csquare(sq))
132 #define ccol(sq) column(csquare(sq))
134 short
135 ptype_distance(short ptyp, short f, short t)
137 short side, piece;
138 short colf, colt, rowf, rowt, dcol, drow;
140 if (f == t)
141 return 0;
143 piece = piece_of_ptype[ptyp];
144 side = side_of_ptype[ptyp];
146 dcol = (colt = ccol(t)) - (colf = ccol(f));
147 drow = (rowt = crow(t)) - (rowf = crow(f));
149 switch (piece)
151 case pawn:
152 if ((dcol != 0) || (drow < 1))
153 return CANNOT_REACH;
154 else
155 return drow;
157 case lance:
158 if ((dcol != 0) || (drow < 1))
159 return CANNOT_REACH;
160 else
161 return 1;
163 case knight:
164 if (odd(drow) || (odd(drow / 2) != odd(dcol)))
165 return CANNOT_REACH;
166 else if ((drow == 0) || ((drow / 2) < abs(dcol)))
167 return CANNOT_REACH;
168 else
169 return (drow / 2);
171 case silver:
172 if (drow > 0)
174 if (odd(drow) == odd(dcol))
176 return max(abs(drow), abs(dcol));
178 else
180 if (abs(dcol) <= drow)
181 return drow;
182 else
183 return (max(abs(drow), abs(dcol)) + 1);
186 else
188 if (odd(drow) == odd(dcol))
189 return (max(abs(drow), abs(dcol)));
190 else
191 return (max(abs(drow) + 1, abs(dcol)) + 1);
194 case gold:
195 case ppawn:
196 case pknight:
197 case plance:
198 case psilver:
199 if (abs(dcol) == 0)
200 return (abs(drow));
201 else if (drow >= 0)
202 return max(drow, abs(dcol));
203 else
204 return (abs(dcol) - drow);
206 case bishop:
207 if (odd(dcol) != odd(drow))
208 return CANNOT_REACH;
209 else
210 return ((abs(dcol) == abs(drow)) ? 1 : 2);
212 case pbishop:
213 if (odd(dcol) != odd(drow))
215 if ((abs(dcol) <= 1) && (abs(drow) <= 1))
216 return 1;
217 else if (abs(abs(dcol) - abs(drow)) == 1)
218 return 2;
219 else
220 return 3;
222 else
224 return ((abs(dcol) == abs(drow)) ? 1 : 2);
227 case rook:
228 if ((dcol == 0) || (drow == 0))
229 return 1;
230 else
231 return 2;
233 case prook:
234 if ((dcol == 0) || (drow == 0))
235 return 1;
236 else if ((abs(dcol) == 1) && (abs(drow) == 1))
237 return 1;
238 else
239 return 2;
241 case king:
242 return max(abs(drow), abs(dcol));
244 default:
245 /* should never occur */
246 return (CANNOT_REACH);
251 #ifdef SAVE_DISTDATA
252 short
253 distance(short a, short b)
255 return (short)computed_distance(a, b);
257 #else
258 short
259 distance(short a, short b)
261 return (use_distdata
262 ? (short)(*distdata)[(int)a][(int)b]
263 : (short)computed_distance(a, b));
265 #endif
268 #ifdef SAVE_PTYPE_DISTDATA
269 short
270 piece_distance(short side, short piece, short f, short t)
272 return ((f > NO_SQUARES)
273 ? (short)1
274 : (short)ptype_distance(ptype[side][piece], f, t));
276 #else
277 short
278 piece_distance(short side, short piece, short f, short t)
280 return ((f > NO_SQUARES)
281 ? (short)1
282 : (use_ptype_distdata
283 ? (short)(*ptype_distdata[ptype[side][piece]])[f][t]
284 : (short)ptype_distance(ptype[side][piece], f, t)));
286 #endif
289 void
290 Initialize_dist(void)
292 short a, b, d, di, ptyp;
293 #ifndef SAVE_DISTDATA
294 for (a = 0; a < NO_SQUARES; a++)
296 for (b = 0; b < NO_SQUARES; b++)
298 d = abs(column(a) - column(b));
299 di = abs(row(a) - row(b));
300 (*distdata)[a][b] = (small_short)((d > di) ? d : di);
303 #endif
304 #ifndef SAVE_PTYPE_DISTDATA
305 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
307 for (a = 0; a < NO_SQUARES; a++)
308 for (b = 0; b < NO_SQUARES; b++)
309 (*ptype_distdata[ptyp])[a][b] = ptype_distance(ptyp, a, b);
311 #endif
316 * nextpos[ptype][from-square], nextdir[ptype][from-square] gives vector
317 * of positions reachable from from-square in ppos with ptype such that the
318 * sequence
320 * ppos = nextpos[ptype][from-square];
321 * pdir = nextdir[ptype][from-square];
322 * u = ppos[sq];
324 * do
326 * u = ppos[u];
328 * if(color[u] != neutral)
329 * u = pdir[u];
331 * while (sq != u);
333 * will generate the sequence of all squares reachable from sq.
335 * If the path is blocked u = pdir[sq] will generate the continuation of the
336 * sequence in other directions.
341 * ptype is used to separate black and white pawns, like this; ptyp =
342 * ptype[side][piece] piece can be used directly in nextpos/nextdir when
343 * generating moves for pieces that are not white pawns.
346 const small_short ptype[2][NO_PIECES] =
349 ptype_no_piece, ptype_pawn, ptype_lance, ptype_knight,
350 ptype_silver, ptype_gold, ptype_bishop, ptype_rook,
351 ptype_gold, ptype_gold, ptype_gold, ptype_gold,
352 ptype_pbishop, ptype_prook, ptype_king
355 ptype_no_piece, ptype_wpawn, ptype_wlance, ptype_wknight,
356 ptype_wsilver, ptype_wgold, ptype_bishop, ptype_rook,
357 ptype_wgold, ptype_wgold, ptype_wgold, ptype_wgold,
358 ptype_pbishop, ptype_prook, ptype_king
362 const small_short promoted[NO_PIECES] =
364 no_piece, ppawn, plance, pknight, psilver, gold, pbishop, prook,
365 ppawn, plance, pknight, psilver, pbishop, prook, king
368 const small_short unpromoted[NO_PIECES] =
370 no_piece, pawn, lance, knight, silver, gold, bishop, rook,
371 pawn, lance, knight, silver, bishop, rook, king
374 const small_short is_promoted[NO_PIECES] =
376 false, false, false, false, false, false, false, false,
377 true, true, true, true, true, true, false
380 /* data used to generate nextpos/nextdir */
381 #if !defined SAVE_NEXTPOS
382 static
383 #endif
384 const small_short direc[NO_PTYPE_PIECES][8] =
386 { 11, 0, 0, 0, 0, 0, 0, 0 }, /* 0 ptype_pawn */
387 { 11, 0, 0, 0, 0, 0, 0, 0 }, /* 1 ptype_lance */
388 { 21, 23, 0, 0, 0, 0, 0, 0 }, /* 2 ptype_knight */
389 { 10, 11, 12, -12, -10, 0, 0, 0 }, /* 3 ptype_silver */
390 { 10, 11, 12, -1, 1, -11, 0, 0 }, /* 4 ptype_gold */
391 { 10, 12, -12, -10, 0, 0, 0, 0 }, /* 5 ptype_bishop */
392 { 11, -1, 1, -11, 0, 0, 0, 0 }, /* 6 ptype_rook */
393 { 10, 12, -12, -10, 11, -1, 1, -11 }, /* 7 ptype_pbishop */
394 { 11, -1, 1, -11, 10, 12, -12, -10 }, /* 8 ptype_prook */
395 { 10, 11, 12, -1, 1, -12, -11, -10 }, /* 9 ptype_king */
396 { -11, 0, 0, 0, 0, 0, 0, 0 }, /* 10 ptype_wpawn */
397 { -11, 0, 0, 0, 0, 0, 0, 0 }, /* 11 ptype_wlance */
398 { -21, -23, 0, 0, 0, 0, 0, 0 }, /* 12 ptype_wknight */
399 { -10, -11, -12, 12, 10, 0, 0, 0 }, /* 13 ptype_wsilver */
400 { -10, -11, -12, 1, -1, 11, 0, 0 }
401 }; /* 14 ptype_wgold */
404 small_short diagonal(short d)
406 return (abs(d) == (NO_COLS+1) || abs(d) == (NO_COLS+3));
410 static const small_short max_steps[NO_PTYPE_PIECES] =
412 1, 8, 1, 1, 1, 8, 8, 8, 8, 1, 1, 8, 1, 1, 1
416 const small_short nunmap[(NO_COLS + 2)*(NO_ROWS + 4)] =
418 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
419 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
420 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1,
421 -1, 9, 10, 11, 12, 13, 14, 15, 16, 17, -1,
422 -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1,
423 -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
424 -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1,
425 -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1,
426 -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1,
427 -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, -1,
428 -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, -1,
429 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
430 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
434 const small_short inunmap[NO_SQUARES] =
436 23, 24, 25, 26, 27, 28, 29, 30, 31,
437 34, 35, 36, 37, 38, 39, 40, 41, 42,
438 45, 46, 47, 48, 49, 50, 51, 52, 53,
439 56, 57, 58, 59, 60, 61, 62, 63, 64,
440 67, 68, 69, 70, 71, 72, 73, 74, 75,
441 78, 79, 80, 81, 82, 83, 84, 85, 86,
442 89, 90, 91, 92, 93, 94, 95, 96, 97,
443 100, 101, 102, 103, 104, 105, 106, 107, 108,
444 111, 112, 113, 114, 115, 116, 117, 118, 119
448 int InitFlag = false;
451 #if defined SAVE_NEXTPOS
453 short
454 next_direction(short ptyp, short *d, short sq)
456 short delta, to, sfrom = inunmap[sq];
460 (*d)++;
461 if (*d >= 8)
462 return sq;
464 delta = direc[ptyp][*d];
465 if (delta == 0)
466 return sq;
468 to = nunmap[sfrom + delta];
470 while (to < 0);
472 return to;
476 short
477 next_position(short ptyp, short *d, short sq, short u)
479 if (*d < 4 && psweep[ptyp])
481 short to = nunmap[inunmap[u] + direc[ptyp][*d]];
483 if (to < 0)
484 return next_direction(ptyp, d, sq);
485 else
486 return to;
488 else
490 return next_direction(ptyp, d, sq);
495 short
496 first_direction(short ptyp, short *d, short sq)
498 *d = -1;
499 return next_direction(ptyp, d, sq);
502 #else
505 * This procedure pre-calculates all moves for every piece from every
506 * square. This data is stored in nextpos/nextdir and used later in the
507 * move generation routines.
510 void
511 Initialize_moves(void)
513 short ptyp, po, p0, d, di, s, delta;
514 unsigned char *ppos, *pdir;
515 short dest[8][9];
516 short sorted[9];
517 short steps[8];
518 short fpo = inunmap[0], tpo = 1 + inunmap[NO_SQUARES-1];
520 /* pre-fill nextpos and nextdir with source position, probably so
521 * (color[u] == neutral) stops to match once all moves have been seen
523 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
525 for (po = 0; po < NO_SQUARES; po++)
527 for (p0 = 0; p0 < NO_SQUARES; p0++)
529 (*nextpos[ptyp])[po][p0] = (unsigned char)po;
530 (*nextdir[ptyp])[po][p0] = (unsigned char)po;
535 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
537 for (po = fpo; po < tpo; po++)
539 if (nunmap[po] >= (small_short)0)
541 ppos = (*nextpos[ptyp])[nunmap[po]];
542 pdir = (*nextdir[ptyp])[nunmap[po]];
544 /* dest is a function of direction and steps */
545 for (d = 0; d < 8; d++)
547 dest[d][0] = nunmap[po];
548 delta = direc[ptyp][d];
550 if (delta != 0)
552 p0 = po;
554 for (s = 0; s < max_steps[ptyp]; s++)
556 p0 = p0 + delta;
559 * break if (off board) or (promoted rooks
560 * wishes to move two steps diagonal) or
561 * (promoted bishops wishes to move two steps
562 * non-diagonal)
564 if ((nunmap[p0] < (small_short)0)
565 || ((ptyp == ptype_prook)
566 && (s > 0)
567 && diagonal(delta))
568 || ((ptyp == ptype_pbishop)
569 && (s > 0)
570 && !diagonal(delta)))
571 break;
572 else
573 dest[d][s] = nunmap[p0];
576 else
578 s = 0;
582 * Sort dest in number of steps order; currently no sort
583 * is done due to compatibility with the move generation
584 * order in old gnuchess.
587 steps[d] = s;
589 for (di = d; s > 0 && di > 0; di--)
591 if (steps[sorted[di - 1]] == 0) /* should be: < s */
592 sorted[di] = sorted[di - 1];
593 else
594 break;
597 sorted[di] = d;
601 * update nextpos/nextdir
604 p0 = nunmap[po];
605 pdir[p0] = (unsigned char)dest[sorted[0]][0];
607 for (d = 0; d < 8; d++)
609 for (s = 0; s < steps[sorted[d]]; s++)
611 ppos[p0] = (unsigned char)dest[sorted[d]][s];
612 p0 = dest[sorted[d]][s];
614 if (d < 7)
615 pdir[p0] = (unsigned char)dest[sorted[d + 1]][0];
618 * else is already initialized
627 #endif
632 * Reset the board and other variables to start a new game.
635 void
636 NewGame(void)
638 short l, c, p, max_opening_sequence;
639 #ifdef HAVE_GETTIMEOFDAY
640 struct timeval tv;
641 #endif
642 compptr = oppptr = 0;
643 stage = 0;
644 stage2 = -1; /* the game is not yet started */
645 flag.illegal = flag.mate = flag.post = flag.quit
646 = flag.reverse = flag.bothsides = flag.onemove = flag.force
647 = false;
648 flag.material = flag.coords = flag.hash = flag.easy
649 = flag.beep = flag.rcptr
650 = true;
651 flag.stars = flag.shade = flag.back = flag.musttimeout = false;
652 flag.gamein = false;
653 flag.rv = true;
655 mycnt1 = mycnt2 = 0;
656 GenCnt = NodeCnt = et0 = dither = XCmore = 0;
657 znodes = ZNODES;
658 WAwindow = WAWNDW;
659 WBwindow = WBWNDW;
660 BAwindow = BAWNDW;
661 BBwindow = BBWNDW;
662 xwndw = BXWNDW;
664 if (!MaxSearchDepth)
665 MaxSearchDepth = MAXDEPTH - 1;
667 contempt = 0;
668 GameCnt = 0;
669 Game50 = 1;
670 CptrFlag[0] = TesujiFlag[0] = false;
671 hint = OPENING_HINT;
672 ZeroRPT();
673 GameType[0] = GameType[1] = UNKNOWN;
674 Pscore[0] = Tscore[0] = (SCORE_LIMIT + 3000);
675 opponent = player = black;
676 computer = white;
678 for (l = 0; l < TREE; l++)
679 Tree[l].f = Tree[l].t = 0;
681 gsrand((unsigned int) 1);
683 if (!InitFlag)
685 for (c = black; c <= white; c++)
687 for (p = pawn; p <= king; p++)
689 for (l = 0; l < NO_SQUARES; l++)
691 (*hashcode)[c][p][l].key
692 = (((unsigned long) urand()));
693 (*hashcode)[c][p][l].key
694 += (((unsigned long) urand()) << 16);
695 (*hashcode)[c][p][l].bd
696 = (((unsigned long) urand()));
697 (*hashcode)[c][p][l].bd
698 += (((unsigned long) urand()) << 16);
699 #if SIZEOF_LONG == 8 /* 64-bit long i.e. 8 bytes */
700 (*hashcode)[c][p][l].key
701 += (((unsigned long) urand()) << 32);
702 (*hashcode)[c][p][l].key
703 += (((unsigned long) urand()) << 48);
704 (*hashcode)[c][p][l].bd
705 += (((unsigned long) urand()) << 32);
706 (*hashcode)[c][p][l].bd
707 += (((unsigned long) urand()) << 48);
708 #endif
713 for (c = black; c <= white; c++)
715 for (p = pawn; p <= king; p++)
717 for (l = 0; l < MAX_CAPTURED; l++)
719 (*drop_hashcode)[c][p][l].key
720 = (((unsigned long) urand()));
721 (*drop_hashcode)[c][p][l].key
722 += (((unsigned long) urand()) << 16);
723 (*drop_hashcode)[c][p][l].bd
724 = (((unsigned long) urand()));
725 (*drop_hashcode)[c][p][l].bd
726 += (((unsigned long) urand()) << 16);
727 #if SIZEOF_LONG == 8 /* 64-bit long i.e. 8 bytes */
728 (*drop_hashcode)[c][p][l].key
729 += (((unsigned long) urand()) << 32);
730 (*drop_hashcode)[c][p][l].key
731 += (((unsigned long) urand()) << 48);
732 (*drop_hashcode)[c][p][l].bd
733 += (((unsigned long) urand()) << 32);
734 (*drop_hashcode)[c][p][l].bd
735 += (((unsigned long) urand()) << 48);
736 #endif
742 for (l = 0; l < NO_SQUARES; l++)
744 board[l] = Stboard[l];
745 color[l] = Stcolor[l];
746 Mvboard[l] = 0;
749 ClearCaptured();
750 ClearScreen();
751 InitializeStats();
753 #ifdef HAVE_GETTIMEOFDAY
754 gettimeofday(&tv, NULL);
755 time0 = tv.tv_sec*100 + tv.tv_usec/10000;
756 #else
757 time0 = time((long *) 0);
758 #endif
760 /* resetting reference time */
761 ElapsedTime(COMPUTE_AND_INIT_MODE);
762 flag.regularstart = true;
763 Book = BOOKFAIL;
765 if (!InitFlag)
767 char sx[256];
768 strcpy(sx, CP[169]);
770 if (TCflag)
771 SetTimeControl();
772 else if (MaxResponseTime == 0)
773 SelectLevel(sx);
775 UpdateDisplay(0, 0, 1, 0);
776 GetOpenings();
777 GetOpeningPatterns(&max_opening_sequence);
779 InitFlag = true;
782 #if ttblsz
783 if (TTadd)
785 ZeroTTable();
786 TTadd = 0;
788 #endif /* ttblsz */
790 hashbd = hashkey = 0;
791 return;
797 Initialize_data(void)
799 size_t n;
800 int i;
801 char buffer[60];
802 int doit = true;
805 small_short x = -1;
807 if (x >= 0)
809 ShowMessage("datatype 'small_short' is unsigned; "
810 "check gnushogi.h\n");
811 return 1;
815 n = sizeof(struct leaf) * (size_t)TREE;
816 Tree = malloc(n);
818 if (!Tree)
820 sprintf(buffer, "Cannot allocate %ld bytes for search tree",
821 (long)n);
822 ShowMessage(buffer);
823 return 1;
826 n = sizeof(hashcode_array);
827 hashcode = malloc(n);
829 if (!hashcode)
831 sprintf(buffer, "Cannot allocate %ld bytes for hashcode", (long)n);
832 ShowMessage(buffer);
833 return 1;
836 n = sizeof(drop_hashcode_array);
837 drop_hashcode = malloc(n);
839 if (!drop_hashcode)
841 sprintf(buffer,
842 "Cannot allocate %ld bytes for drop_hashcode",
843 (long)n);
844 ShowMessage(buffer);
845 return 1;
848 n = sizeof(struct GameRec) * (size_t)(MAXMOVES + MAXDEPTH);
849 GameList = malloc(n);
851 if (!GameList)
853 sprintf(buffer,
854 "Cannot allocate %ld bytes for game record",
855 (long)n);
856 ShowMessage(buffer);
857 return 1;
860 #if !defined SAVE_NEXTPOS
861 n = sizeof(next_array);
863 for (i = 0; i < NO_PTYPE_PIECES; i++)
865 nextdir[i] = use_nextpos ? malloc(n) : NULL;
867 if (!nextdir[i])
869 if (use_nextpos)
871 sprintf(buffer, "cannot allocate %ld space for nextdir %d",
872 (long)(n), i);
873 ShowMessage(buffer);
876 nextdir[i] = NULL;
877 use_nextpos = false;
880 nextpos[i] = use_nextpos ? malloc(n) : NULL;
882 if (!nextpos[i])
884 if (use_nextpos)
886 sprintf(buffer, "cannot allocate %ld space for nextpos %d",
887 (long)(n), i);
888 ShowMessage(buffer);
891 use_nextpos = false;
895 if (!use_nextpos)
897 return 1;
899 #endif
901 n = sizeof(value_array);
902 value = malloc(n);
904 if (!value)
906 ShowMessage("cannot allocate value space");
907 return 1;
910 n = sizeof(fscore_array);
911 fscore = malloc(n);
913 if (!fscore)
915 ShowMessage("cannot allocate fscore space");
916 return 1;
919 #if defined HISTORY
920 n = sizeof_history;
921 history = malloc(n);
923 if (!history)
925 sprintf(buffer, "Cannot allocate %ld bytes for history table",
926 (long)sizeof_history);
927 ShowMessage(buffer);
928 use_history = false;
930 #endif
932 #if defined CACHE
933 n = sizeof(struct etable) * (size_t)ETABLE;
935 for (i = 0; i < 2; i++)
937 etab[i] = use_etable ? malloc(n) : 0;
939 if (!etab[i])
941 sprintf(buffer, "Cannot allocate %ld bytes for cache table %ld",
942 (long)n, (long)i);
943 ShowMessage(buffer);
944 use_etable = false;
947 #endif
949 #if ttblsz
951 if (rehash < 0)
952 rehash = MAXrehash;
954 n = sizeof(struct hashentry)*(ttblsize + rehash);
956 while (doit && ttblsize > MINTTABLE)
958 ttable[0] = malloc(n); /* FIXME: cast to the correct type. */
959 ttable[1] = ttable[0] ? malloc(n) : NULL;
961 if (!ttable[0] || !ttable[1])
963 if (!ttable[0])
964 free(ttable[0]);
966 if (!ttable[1])
967 free(ttable[1]);
969 ttblsize = ttblsize >> 1;
970 n = sizeof(struct hashentry) * (ttblsize + rehash);
972 else
974 doit = false;
978 if (ttblsize <= MINTTABLE)
980 use_ttable = false;
983 if (use_ttable)
985 /* CHECKME: is the precedence here correct? */
986 /* ttbllimit = ttblsize << 1 - ttblsize >> 2; */
987 ttbllimit = (ttblsize << 1) - (ttblsize >> 2);
989 else
991 sprintf(buffer, "Cannot allocate %ld bytes for transposition table",
992 (long)(2 * n));
993 ShowMessage(buffer);
994 ttable[0] = ttable[1] = NULL;
996 #endif /* ttblsz */
998 #if !defined SAVE_DISTDATA
999 n = sizeof(distdata_array);
1000 distdata = malloc(n);
1002 if (!distdata)
1004 ShowMessage("cannot allocate distdata space...");
1005 use_distdata = false;
1007 #endif
1009 #if !defined SAVE_PTYPE_DISTDATA
1010 n = sizeof(distdata_array);
1012 for (i = 0; i < NO_PTYPE_PIECES; i++)
1014 ptype_distdata[i] = use_ptype_distdata ? malloc(n) : 0;
1016 if (!ptype_distdata[i])
1018 sprintf(buffer,
1019 "cannot allocate %ld bytes for ptype_distdata %d...",
1020 (long)n, i);
1021 use_ptype_distdata = false;
1024 #endif
1026 return 0;
1030 #if defined EXTLANGFILE
1032 #ifdef OLDLANGFILE
1034 void
1035 InitConst(char *lang)
1037 FILE *constfile;
1038 char s[256];
1039 char sl[5];
1040 char buffer[120];
1041 int len, entry;
1042 char *p, *q;
1043 constfile = fopen(LANGFILE, "r");
1045 if (!constfile)
1047 ShowMessage("NO LANGFILE");
1048 exit(1);
1051 while (fgets(s, sizeof(s), constfile))
1053 if (s[0] == '!')
1054 continue;
1056 len = strlen(s);
1058 for (q = &s[len]; q > &s[8]; q--)
1059 if (*q == '}')
1060 break;
1062 if (q == &s[8])
1064 ShowMessage("{ error in cinstfile");
1065 exit(1);
1068 *q = '\0';
1070 if ((s[3] != ':') || (s[7] != ':') || (s[8] != '{'))
1072 sprintf(buffer, "Langfile format error %s", s);
1073 ShowMessage(buffer);
1074 exit(1);
1077 s[3] = s[7] = '\0';
1079 if (lang == NULL)
1081 lang = sl;
1082 strcpy(sl, &s[4]);
1085 if (strcmp(&s[4], lang))
1086 continue;
1088 entry = atoi(s);
1090 if ((entry < 0) || (entry >= CPSIZE))
1092 ShowMessage("Langfile number error");
1093 exit(1);
1096 for (q = p = &s[9]; *p; p++)
1098 if (*p != '\\')
1100 *q++ = *p;
1102 else if (*(p + 1) == 'n')
1104 *q++ = '\n';
1105 p++;
1109 *q = '\0';
1111 if ((entry < 0) || (entry > 255))
1113 sprintf(buffer, "Langfile error %d\n", entry);
1114 ShowMessage(buffer);
1115 exit(0);
1118 CP[entry] = (char *)GLOBAL_ALLOC((unsigned) strlen(&s[9]) + 1);
1120 if (CP[entry] == NULL)
1122 char buffer[80];
1123 sprintf(buffer, "CP MALLOC, entry %d", entry);
1124 perror(buffer);
1125 exit(0);
1128 strcpy(CP[entry], &s[9]);
1131 fclose(constfile);
1134 #else
1136 void
1137 InitConst(char *lang)
1139 FILE *constfile;
1140 char s[256];
1141 char sl[5];
1142 char buffer[120];
1143 int len, entry;
1144 char *p, *q;
1145 constfile = fopen(LANGFILE, "r");
1147 if (!constfile)
1149 ShowMessage("NO LANGFILE");
1150 exit(1);
1153 while (fgets(s, sizeof(s), constfile))
1155 if (s[0] == '!')
1156 continue;
1158 len = strlen(s);
1160 if ((len > 3) && (s[3] == ':') || (len > 7) && (s[7] == ':'))
1162 ShowMessage("old Langfile error");
1163 exit(1);
1166 if (len <= 15)
1168 ShowMessage("length error in Langfile");
1169 exit(1);
1172 for (q = &s[len]; q > &s[15]; q--)
1174 if (*q == '"')
1175 break;
1178 if (q == &s[15])
1180 ShowMessage("\" error in Langfile");
1181 exit(1);
1184 *q = '\0';
1186 if ((s[6] != ':') || (s[10] != ':') || (s[15] != '"'))
1188 sprintf(buffer, "Langfile format error %s", s);
1189 ShowMessage(buffer);
1190 exit(1);
1193 s[6] = s[10] = '\0';
1195 if (lang == NULL)
1197 lang = sl;
1198 strcpy(sl, &s[7]);
1201 if (strcmp(&s[7], lang))
1202 continue;
1204 entry = atoi(&s[3]);
1206 if ((entry < 0) || (entry >= CPSIZE))
1208 ShowMessage("Langfile number error");
1209 exit(1);
1212 for (q = p = &s[16]; *p; p++)
1214 if (*p != '\\')
1216 *q++ = *p;
1218 else if (*(p + 1) == 'n')
1220 *q++ = '\n';
1221 p++;
1225 *q = '\0';
1227 if ((entry < 0) || (entry > 255))
1229 sprintf(buffer, "Langfile error %d\n", entry);
1230 ShowMessage(buffer);
1231 exit(0);
1234 CP[entry] = (char *)GLOBAL_ALLOC((unsigned)strlen(&s[16]) + 1);
1236 if (CP[entry] == NULL)
1238 char buffer[80];
1239 sprintf(buffer, "CP MALLOC, entry %d", entry);
1240 perror(buffer);
1241 exit(0);
1244 strcpy(CP[entry], &s[16]);
1247 fclose(constfile);
1250 #endif
1252 #endif
1256 InitMain(void)
1258 gsrand(starttime = ((unsigned int)time((long *)0))); /* init urand */
1260 #if ttblsz
1261 ttblsize = ttblsz;
1262 rehash = -1;
1263 #endif /* ttblsz */
1265 if (Initialize_data() != 0)
1266 return 1;
1268 #if defined EXTLANGFILE
1269 InitConst(Lang);
1270 #endif
1272 strcpy(ColorStr[0], CP[118]);
1273 strcpy(ColorStr[1], CP[119]);
1275 XC = 0;
1276 MaxResponseTime = 0;
1278 if (XSHOGI)
1280 TCmoves = 40;
1281 TCminutes = 5;
1282 TCseconds = 0;
1283 TCadd = 0;
1285 TCflag = true;
1286 OperatorTime = 0;
1287 barebones = 1;
1289 else
1291 TCflag = false;
1292 OperatorTime = 0;
1293 barebones = 0;
1296 Initialize();
1297 Initialize_dist();
1298 Initialize_eval();
1299 #if !defined SAVE_NEXTPOS
1300 Initialize_moves();
1301 #endif
1303 NewGame();
1305 flag.easy = ahead;
1306 flag.hash = hash;
1308 if (xwin)
1309 xwndw = atoi(xwin);
1311 #ifdef HASHFILE
1312 hashfile = NULL;
1313 #endif
1315 #if ttblsz
1316 #ifdef HASHFILE
1317 hashfile = fopen(HASHFILE, RWA_ACC);
1319 if (hashfile)
1321 fseek(hashfile, 0L, SEEK_END);
1322 filesz = ftell(hashfile) / sizeof(struct fileentry) - 1 - MAXrehash;
1323 hashmask = filesz >> 1;
1324 hashbase = hashmask + 1;
1326 #endif /* HASHFILE */
1327 #endif /* ttblsz */
1329 savefile[0] = '\0';
1330 listfile[0] = '\0';
1332 return 0;
1336 void
1337 ExitMain(void)
1339 #if ttblsz
1340 #ifdef HASHFILE
1341 if (hashfile)
1342 fclose(hashfile);
1343 #endif /* HASHFILE */
1344 #endif /* ttblsz */
1346 ExitShogi();