Document internal APIs.
[gnushogi.git] / gnushogi / init.c
blobed52724f3dfe8ab8f4d16f3f59e431e481899d83
1 /*
2 * FILE: init.c
4 * ----------------------------------------------------------------------
6 * Copyright (c) 2012 Free Software Foundation
8 * GNU SHOGI is based on GNU CHESS
10 * This file is part of GNU SHOGI.
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.
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.
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 * ----------------------------------------------------------------------
29 #include "gnushogi.h"
31 #if defined HAVE_GETTIMEOFDAY
32 #include <sys/time.h>
33 #endif
35 #include <signal.h>
37 #include "pattern.h"
39 /****************************************
40 * A variety of global flags.
41 ****************************************/
44 * If hard_time_limit is nonzero, exceeding the time limit means
45 * losing the game.
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
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.
62 display_t display_type = DISPLAY_X;
64 unsigned int ttbllimit;
66 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
69 #define max(a, b) (((a) < (b))?(b):(a))
70 #define odd(a) ((a) & 1)
73 const small_short piece_of_ptype[NO_PTYPE_PIECES] =
75 pawn, lance, knight, silver, gold, bishop, rook, pbishop, prook, king,
76 pawn, lance, knight, silver, gold
80 const small_short side_of_ptype[NO_PTYPE_PIECES] =
82 black, black, black, black, black, black, black, black, black, black,
83 white, white, white, white, white
86 #ifdef SAVE_NEXTPOS
87 const small_short psweep[NO_PTYPE_PIECES] =
89 false, true, false, false, false, true, true, true, true, false,
90 false, true, false, false, false
92 #endif
94 const small_short sweep[NO_PIECES] =
96 false, false, true, false, false, false, true, true,
97 false, false, false, false, true, true, false
101 #if !defined EXTLANGFILE
103 char *CP[CPSIZE] =
106 /* 000: eng: */ "",
107 #ifdef LANGFILE
108 #include LANGFILE
109 #else
110 #include "gnushogi.lng"
111 #endif
114 #else
116 char *CP[CPSIZE];
118 #endif
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.
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))
131 short
132 ptype_distance(short ptyp, short f, short t)
134 short side, piece;
135 short colf, colt, rowf, rowt, dcol, drow;
137 if (f == t)
138 return 0;
140 piece = piece_of_ptype[ptyp];
141 side = side_of_ptype[ptyp];
143 dcol = (colt = ccol(t)) - (colf = ccol(f));
144 drow = (rowt = crow(t)) - (rowf = crow(f));
146 switch (piece)
148 case pawn:
149 if ((dcol != 0) || (drow < 1))
150 return CANNOT_REACH;
151 else
152 return drow;
154 case lance:
155 if ((dcol != 0) || (drow < 1))
156 return CANNOT_REACH;
157 else
158 return 1;
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);
168 case silver:
169 if (drow > 0)
171 if (odd(drow) == odd(dcol))
173 return max(abs(drow), abs(dcol));
175 else
177 if (abs(dcol) <= drow)
178 return drow;
179 else
180 return (max(abs(drow), abs(dcol)) + 1);
183 else
185 if (odd(drow) == odd(dcol))
186 return (max(abs(drow), abs(dcol)));
187 else
188 return (max(abs(drow) + 1, abs(dcol)) + 1);
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);
203 case bishop:
204 if (odd(dcol) != odd(drow))
205 return CANNOT_REACH;
206 else
207 return ((abs(dcol) == abs(drow)) ? 1 : 2);
209 case pbishop:
210 if (odd(dcol) != odd(drow))
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;
219 else
221 return ((abs(dcol) == abs(drow)) ? 1 : 2);
224 case rook:
225 if ((dcol == 0) || (drow == 0))
226 return 1;
227 else
228 return 2;
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;
238 case king:
239 return max(abs(drow), abs(dcol));
241 default:
242 /* should never occur */
243 return (CANNOT_REACH);
248 #ifdef SAVE_DISTDATA
249 short
250 distance(short a, short b)
252 return (short)computed_distance(a, b);
254 #else
255 short
256 distance(short a, short b)
258 return (use_distdata
259 ? (short)(*distdata)[(int)a][(int)b]
260 : (short)computed_distance(a, b));
262 #endif
265 #ifdef SAVE_PTYPE_DISTDATA
266 short
267 piece_distance(short side, short piece, short f, short t)
269 return ((f > NO_SQUARES)
270 ? (short)1
271 : (short)ptype_distance(ptype[side][piece], f, t));
273 #else
274 short
275 piece_distance(short side, short piece, short f, short t)
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)));
283 #endif
286 void
287 Initialize_dist(void)
289 short a, b, d, di, ptyp;
290 #ifndef SAVE_DISTDATA
291 for (a = 0; a < NO_SQUARES; a++)
293 for (b = 0; b < NO_SQUARES; b++)
295 d = abs(column(a) - column(b));
296 di = abs(row(a) - row(b));
297 (*distdata)[a][b] = (small_short)((d > di) ? d : di);
300 #endif
301 #ifndef SAVE_PTYPE_DISTDATA
302 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
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);
308 #endif
313 * nextpos[ptype][from-square], nextdir[ptype][from-square] gives vector
314 * of positions reachable from from-square in ppos with ptype such that the
315 * sequence
317 * ppos = nextpos[ptype][from-square];
318 * pdir = nextdir[ptype][from-square];
319 * u = ppos[sq];
321 * do
323 * u = ppos[u];
325 * if(color[u] != neutral)
326 * u = pdir[u];
328 * while (sq != u);
330 * will generate the sequence of all squares reachable from sq.
332 * If the path is blocked u = pdir[sq] will generate the continuation of the
333 * sequence in other directions.
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.
343 const small_short ptype[2][NO_PIECES] =
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
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
359 const small_short promoted[NO_PIECES] =
361 no_piece, ppawn, plance, pknight, psilver, gold, pbishop, prook,
362 ppawn, plance, pknight, psilver, pbishop, prook, king
365 const small_short unpromoted[NO_PIECES] =
367 no_piece, pawn, lance, knight, silver, gold, bishop, rook,
368 pawn, lance, knight, silver, bishop, rook, king
371 const small_short is_promoted[NO_PIECES] =
373 false, false, false, false, false, false, false, false,
374 true, true, true, true, true, true, false
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] =
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 */
401 small_short diagonal(short d)
403 return (abs(d) == (NO_COLS+1) || abs(d) == (NO_COLS+3));
407 static const small_short max_steps[NO_PTYPE_PIECES] =
409 1, 8, 1, 1, 1, 8, 8, 8, 8, 1, 1, 8, 1, 1, 1
413 const small_short nunmap[(NO_COLS + 2)*(NO_ROWS + 4)] =
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
431 const small_short inunmap[NO_SQUARES] =
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
445 int InitFlag = false;
448 #if defined SAVE_NEXTPOS
450 short
451 next_direction(short ptyp, short *d, short sq)
453 short delta, to, sfrom = inunmap[sq];
457 (*d)++;
458 if (*d >= 8)
459 return sq;
461 delta = direc[ptyp][*d];
462 if (delta == 0)
463 return sq;
465 to = nunmap[sfrom + delta];
467 while (to < 0);
469 return to;
473 short
474 next_position(short ptyp, short *d, short sq, short u)
476 if (*d < 4 && psweep[ptyp])
478 short to = nunmap[inunmap[u] + direc[ptyp][*d]];
480 if (to < 0)
481 return next_direction(ptyp, d, sq);
482 else
483 return to;
485 else
487 return next_direction(ptyp, d, sq);
492 short
493 first_direction(short ptyp, short *d, short sq)
495 *d = -1;
496 return next_direction(ptyp, d, sq);
499 #else
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.
507 void
508 Initialize_moves(void)
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 = inunmap[0], tpo = 1 + inunmap[NO_SQUARES-1];
517 /* pre-fill nextpos and nextdir with source position, probably so
518 * (color[u] == neutral) stops to match once all moves have been seen
520 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
522 for (po = 0; po < NO_SQUARES; po++)
524 for (p0 = 0; p0 < NO_SQUARES; p0++)
526 (*nextpos[ptyp])[po][p0] = (unsigned char)po;
527 (*nextdir[ptyp])[po][p0] = (unsigned char)po;
532 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
534 for (po = fpo; po < tpo; po++)
536 if (nunmap[po] >= (small_short)0)
538 ppos = (*nextpos[ptyp])[nunmap[po]];
539 pdir = (*nextdir[ptyp])[nunmap[po]];
541 /* dest is a function of direction and steps */
542 for (d = 0; d < 8; d++)
544 dest[d][0] = nunmap[po];
545 delta = direc[ptyp][d];
547 if (delta != 0)
549 p0 = po;
551 for (s = 0; s < max_steps[ptyp]; s++)
553 p0 = p0 + delta;
556 * break if (off board) or (promoted rooks
557 * wishes to move two steps diagonal) or
558 * (promoted bishops wishes to move two steps
559 * non-diagonal)
561 if ((nunmap[p0] < (small_short)0)
562 || ((ptyp == ptype_prook)
563 && (s > 0)
564 && diagonal(delta))
565 || ((ptyp == ptype_pbishop)
566 && (s > 0)
567 && !diagonal(delta)))
568 break;
569 else
570 dest[d][s] = nunmap[p0];
573 else
575 s = 0;
579 * Sort dest in number of steps order; currently no sort
580 * is done due to compatibility with the move generation
581 * order in old gnuchess.
584 steps[d] = s;
586 for (di = d; s > 0 && di > 0; di--)
588 if (steps[sorted[di - 1]] == 0) /* should be: < s */
589 sorted[di] = sorted[di - 1];
590 else
591 break;
594 sorted[di] = d;
598 * update nextpos/nextdir
601 p0 = nunmap[po];
602 pdir[p0] = (unsigned char)dest[sorted[0]][0];
604 for (d = 0; d < 8; d++)
606 for (s = 0; s < steps[sorted[d]]; s++)
608 ppos[p0] = (unsigned char)dest[sorted[d]][s];
609 p0 = dest[sorted[d]][s];
611 if (d < 7)
612 pdir[p0] = (unsigned char)dest[sorted[d + 1]][0];
615 * else is already initialized
624 #endif
629 * Reset the board and other variables to start a new game.
632 void
633 NewGame(void)
635 short l, c, p, max_opening_sequence;
636 #ifdef HAVE_GETTIMEOFDAY
637 struct timeval tv;
638 #endif
639 compptr = oppptr = 0;
640 stage = 0;
641 stage2 = -1; /* the game is not yet started */
642 flag.illegal = flag.mate = flag.post = flag.quit
643 = flag.reverse = flag.bothsides = flag.onemove = flag.force
644 = false;
645 flag.material = flag.coords = flag.hash = flag.easy
646 = flag.beep = flag.rcptr
647 = true;
648 flag.stars = flag.shade = flag.back = flag.musttimeout = false;
649 flag.gamein = false;
650 flag.rv = true;
652 mycnt1 = mycnt2 = 0;
653 GenCnt = NodeCnt = et0 = dither = XCmore = 0;
654 znodes = ZNODES;
655 WAwindow = WAWNDW;
656 WBwindow = WBWNDW;
657 BAwindow = BAWNDW;
658 BBwindow = BBWNDW;
659 xwndw = BXWNDW;
661 if (!MaxSearchDepth)
662 MaxSearchDepth = MAXDEPTH - 1;
664 contempt = 0;
665 GameCnt = 0;
666 Game50 = 1;
667 CptrFlag[0] = TesujiFlag[0] = false;
668 hint = OPENING_HINT;
669 ZeroRPT();
670 GameType[0] = GameType[1] = UNKNOWN;
671 Pscore[0] = Tscore[0] = (SCORE_LIMIT + 3000);
672 opponent = player = black;
673 computer = white;
675 for (l = 0; l < TREE; l++)
676 Tree[l].f = Tree[l].t = 0;
678 gsrand((unsigned int) 1);
680 if (!InitFlag)
682 for (c = black; c <= white; c++)
684 for (p = pawn; p <= king; p++)
686 for (l = 0; l < NO_SQUARES; l++)
688 (*hashcode)[c][p][l].key
689 = (((unsigned long) urand()));
690 (*hashcode)[c][p][l].key
691 += (((unsigned long) urand()) << 16);
692 (*hashcode)[c][p][l].bd
693 = (((unsigned long) urand()));
694 (*hashcode)[c][p][l].bd
695 += (((unsigned long) urand()) << 16);
696 #if SIZEOF_LONG == 8 /* 64-bit long i.e. 8 bytes */
697 (*hashcode)[c][p][l].key
698 += (((unsigned long) urand()) << 32);
699 (*hashcode)[c][p][l].key
700 += (((unsigned long) urand()) << 48);
701 (*hashcode)[c][p][l].bd
702 += (((unsigned long) urand()) << 32);
703 (*hashcode)[c][p][l].bd
704 += (((unsigned long) urand()) << 48);
705 #endif
710 for (c = black; c <= white; c++)
712 for (p = pawn; p <= king; p++)
714 for (l = 0; l < MAX_CAPTURED; l++)
716 (*drop_hashcode)[c][p][l].key
717 = (((unsigned long) urand()));
718 (*drop_hashcode)[c][p][l].key
719 += (((unsigned long) urand()) << 16);
720 (*drop_hashcode)[c][p][l].bd
721 = (((unsigned long) urand()));
722 (*drop_hashcode)[c][p][l].bd
723 += (((unsigned long) urand()) << 16);
724 #if SIZEOF_LONG == 8 /* 64-bit long i.e. 8 bytes */
725 (*drop_hashcode)[c][p][l].key
726 += (((unsigned long) urand()) << 32);
727 (*drop_hashcode)[c][p][l].key
728 += (((unsigned long) urand()) << 48);
729 (*drop_hashcode)[c][p][l].bd
730 += (((unsigned long) urand()) << 32);
731 (*drop_hashcode)[c][p][l].bd
732 += (((unsigned long) urand()) << 48);
733 #endif
739 for (l = 0; l < NO_SQUARES; l++)
741 board[l] = Stboard[l];
742 color[l] = Stcolor[l];
743 Mvboard[l] = 0;
746 ClearCaptured();
747 ClearScreen();
748 InitializeStats();
750 #ifdef HAVE_GETTIMEOFDAY
751 gettimeofday(&tv, NULL);
752 time0 = tv.tv_sec*100 + tv.tv_usec/10000;
753 #else
754 time0 = time((long *) 0);
755 #endif
757 /* resetting reference time */
758 ElapsedTime(COMPUTE_AND_INIT_MODE);
759 flag.regularstart = true;
760 Book = BOOKFAIL;
762 if (!InitFlag)
764 char sx[256];
765 strcpy(sx, CP[169]);
767 if (TCflag)
768 SetTimeControl();
769 else if (MaxResponseTime == 0)
770 SelectLevel(sx);
772 UpdateDisplay(0, 0, 1, 0);
773 GetOpenings();
774 GetOpeningPatterns(&max_opening_sequence);
776 InitFlag = true;
779 #if ttblsz
780 if (TTadd)
782 ZeroTTable();
783 TTadd = 0;
785 #endif /* ttblsz */
787 hashbd = hashkey = 0;
788 return;
794 Initialize_data(void)
796 size_t n;
797 int i;
798 char buffer[60];
799 int doit = true;
802 small_short x = -1;
804 if (x >= 0)
806 ShowMessage("datatype 'small_short' is unsigned; "
807 "check gnushogi.h\n");
808 return 1;
812 n = sizeof(struct leaf) * (size_t)TREE;
813 Tree = malloc(n);
815 if (!Tree)
817 sprintf(buffer, "Cannot allocate %ld bytes for search tree",
818 (long)n);
819 ShowMessage(buffer);
820 return 1;
823 n = sizeof(hashcode_array);
824 hashcode = malloc(n);
826 if (!hashcode)
828 sprintf(buffer, "Cannot allocate %ld bytes for hashcode", (long)n);
829 ShowMessage(buffer);
830 return 1;
833 n = sizeof(drop_hashcode_array);
834 drop_hashcode = malloc(n);
836 if (!drop_hashcode)
838 sprintf(buffer,
839 "Cannot allocate %ld bytes for drop_hashcode",
840 (long)n);
841 ShowMessage(buffer);
842 return 1;
845 n = sizeof(struct GameRec) * (size_t)(MAXMOVES + MAXDEPTH);
846 GameList = malloc(n);
848 if (!GameList)
850 sprintf(buffer,
851 "Cannot allocate %ld bytes for game record",
852 (long)n);
853 ShowMessage(buffer);
854 return 1;
857 #if !defined SAVE_NEXTPOS
858 n = sizeof(next_array);
860 for (i = 0; i < NO_PTYPE_PIECES; i++)
862 nextdir[i] = use_nextpos ? malloc(n) : NULL;
864 if (!nextdir[i])
866 if (use_nextpos)
868 sprintf(buffer, "cannot allocate %ld space for nextdir %d",
869 (long)(n), i);
870 ShowMessage(buffer);
873 nextdir[i] = NULL;
874 use_nextpos = false;
877 nextpos[i] = use_nextpos ? malloc(n) : NULL;
879 if (!nextpos[i])
881 if (use_nextpos)
883 sprintf(buffer, "cannot allocate %ld space for nextpos %d",
884 (long)(n), i);
885 ShowMessage(buffer);
888 use_nextpos = false;
892 if (!use_nextpos)
894 return 1;
896 #endif
898 n = sizeof(value_array);
899 value = malloc(n);
901 if (!value)
903 ShowMessage("cannot allocate value space");
904 return 1;
907 n = sizeof(fscore_array);
908 fscore = malloc(n);
910 if (!fscore)
912 ShowMessage("cannot allocate fscore space");
913 return 1;
916 #if defined HISTORY
917 n = sizeof_history;
918 history = malloc(n);
920 if (!history)
922 sprintf(buffer, "Cannot allocate %ld bytes for history table",
923 (long)sizeof_history);
924 ShowMessage(buffer);
925 use_history = false;
927 #endif
929 #if defined CACHE
930 n = sizeof(struct etable) * (size_t)ETABLE;
932 for (i = 0; i < 2; i++)
934 etab[i] = use_etable ? malloc(n) : 0;
936 if (!etab[i])
938 sprintf(buffer, "Cannot allocate %ld bytes for cache table %ld",
939 (long)n, (long)i);
940 ShowMessage(buffer);
941 use_etable = false;
944 #endif
946 #if ttblsz
948 if (rehash < 0)
949 rehash = MAXrehash;
951 n = sizeof(struct hashentry)*(ttblsize + rehash);
953 while (doit && ttblsize > MINTTABLE)
955 ttable[0] = malloc(n); /* FIXME: cast to the correct type. */
956 ttable[1] = ttable[0] ? malloc(n) : NULL;
958 if (!ttable[0] || !ttable[1])
960 if (!ttable[0])
961 free(ttable[0]);
963 if (!ttable[1])
964 free(ttable[1]);
966 ttblsize = ttblsize >> 1;
967 n = sizeof(struct hashentry) * (ttblsize + rehash);
969 else
971 doit = false;
975 if (ttblsize <= MINTTABLE)
977 use_ttable = false;
980 if (use_ttable)
982 /* CHECKME: is the precedence here correct? */
983 /* ttbllimit = ttblsize << 1 - ttblsize >> 2; */
984 ttbllimit = (ttblsize << 1) - (ttblsize >> 2);
986 else
988 sprintf(buffer, "Cannot allocate %ld bytes for transposition table",
989 (long)(2 * n));
990 ShowMessage(buffer);
991 ttable[0] = ttable[1] = NULL;
993 #endif /* ttblsz */
995 #if !defined SAVE_DISTDATA
996 n = sizeof(distdata_array);
997 distdata = malloc(n);
999 if (!distdata)
1001 ShowMessage("cannot allocate distdata space...");
1002 use_distdata = false;
1004 #endif
1006 #if !defined SAVE_PTYPE_DISTDATA
1007 n = sizeof(distdata_array);
1009 for (i = 0; i < NO_PTYPE_PIECES; i++)
1011 ptype_distdata[i] = use_ptype_distdata ? malloc(n) : 0;
1013 if (!ptype_distdata[i])
1015 sprintf(buffer,
1016 "cannot allocate %ld bytes for ptype_distdata %d...",
1017 (long)n, i);
1018 use_ptype_distdata = false;
1021 #endif
1023 return 0;
1027 #if defined EXTLANGFILE
1029 #ifdef OLDLANGFILE
1031 void
1032 InitConst(char *lang)
1034 FILE *constfile;
1035 char s[256];
1036 char sl[5];
1037 char buffer[120];
1038 int len, entry;
1039 char *p, *q;
1040 constfile = fopen(LANGFILE, "r");
1042 if (!constfile)
1044 ShowMessage("NO LANGFILE");
1045 exit(1);
1048 while (fgets(s, sizeof(s), constfile))
1050 if (s[0] == '!')
1051 continue;
1053 len = strlen(s);
1055 for (q = &s[len]; q > &s[8]; q--)
1056 if (*q == '}')
1057 break;
1059 if (q == &s[8])
1061 ShowMessage("{ error in cinstfile");
1062 exit(1);
1065 *q = '\0';
1067 if ((s[3] != ':') || (s[7] != ':') || (s[8] != '{'))
1069 sprintf(buffer, "Langfile format error %s", s);
1070 ShowMessage(buffer);
1071 exit(1);
1074 s[3] = s[7] = '\0';
1076 if (lang == NULL)
1078 lang = sl;
1079 strcpy(sl, &s[4]);
1082 if (strcmp(&s[4], lang))
1083 continue;
1085 entry = atoi(s);
1087 if ((entry < 0) || (entry >= CPSIZE))
1089 ShowMessage("Langfile number error");
1090 exit(1);
1093 for (q = p = &s[9]; *p; p++)
1095 if (*p != '\\')
1097 *q++ = *p;
1099 else if (*(p + 1) == 'n')
1101 *q++ = '\n';
1102 p++;
1106 *q = '\0';
1108 if ((entry < 0) || (entry > 255))
1110 sprintf(buffer, "Langfile error %d\n", entry);
1111 ShowMessage(buffer);
1112 exit(0);
1115 CP[entry] = (char *)GLOBAL_ALLOC((unsigned) strlen(&s[9]) + 1);
1117 if (CP[entry] == NULL)
1119 char buffer[80];
1120 sprintf(buffer, "CP MALLOC, entry %d", entry);
1121 perror(buffer);
1122 exit(0);
1125 strcpy(CP[entry], &s[9]);
1128 fclose(constfile);
1131 #else
1133 void
1134 InitConst(char *lang)
1136 FILE *constfile;
1137 char s[256];
1138 char sl[5];
1139 char buffer[120];
1140 int len, entry;
1141 char *p, *q;
1142 constfile = fopen(LANGFILE, "r");
1144 if (!constfile)
1146 ShowMessage("NO LANGFILE");
1147 exit(1);
1150 while (fgets(s, sizeof(s), constfile))
1152 if (s[0] == '!')
1153 continue;
1155 len = strlen(s);
1157 if ((len > 3) && (s[3] == ':') || (len > 7) && (s[7] == ':'))
1159 ShowMessage("old Langfile error");
1160 exit(1);
1163 if (len <= 15)
1165 ShowMessage("length error in Langfile");
1166 exit(1);
1169 for (q = &s[len]; q > &s[15]; q--)
1171 if (*q == '"')
1172 break;
1175 if (q == &s[15])
1177 ShowMessage("\" error in Langfile");
1178 exit(1);
1181 *q = '\0';
1183 if ((s[6] != ':') || (s[10] != ':') || (s[15] != '"'))
1185 sprintf(buffer, "Langfile format error %s", s);
1186 ShowMessage(buffer);
1187 exit(1);
1190 s[6] = s[10] = '\0';
1192 if (lang == NULL)
1194 lang = sl;
1195 strcpy(sl, &s[7]);
1198 if (strcmp(&s[7], lang))
1199 continue;
1201 entry = atoi(&s[3]);
1203 if ((entry < 0) || (entry >= CPSIZE))
1205 ShowMessage("Langfile number error");
1206 exit(1);
1209 for (q = p = &s[16]; *p; p++)
1211 if (*p != '\\')
1213 *q++ = *p;
1215 else if (*(p + 1) == 'n')
1217 *q++ = '\n';
1218 p++;
1222 *q = '\0';
1224 if ((entry < 0) || (entry > 255))
1226 sprintf(buffer, "Langfile error %d\n", entry);
1227 ShowMessage(buffer);
1228 exit(0);
1231 CP[entry] = (char *)GLOBAL_ALLOC((unsigned)strlen(&s[16]) + 1);
1233 if (CP[entry] == NULL)
1235 char buffer[80];
1236 sprintf(buffer, "CP MALLOC, entry %d", entry);
1237 perror(buffer);
1238 exit(0);
1241 strcpy(CP[entry], &s[16]);
1244 fclose(constfile);
1247 #endif
1249 #endif
1253 InitMain(void)
1255 gsrand(starttime = ((unsigned int)time((long *)0))); /* init urand */
1257 #if ttblsz
1258 ttblsize = ttblsz;
1259 rehash = -1;
1260 #endif /* ttblsz */
1262 if (Initialize_data() != 0)
1263 return 1;
1265 #if defined EXTLANGFILE
1266 InitConst(Lang);
1267 #endif
1269 strcpy(ColorStr[0], CP[118]);
1270 strcpy(ColorStr[1], CP[119]);
1272 XC = 0;
1273 MaxResponseTime = 0;
1275 if (XSHOGI)
1277 signal(SIGUSR1, TerminateSearch);
1279 TCmoves = 40;
1280 TCminutes = 5;
1281 TCseconds = 0;
1282 TCadd = 0;
1284 TCflag = true;
1285 OperatorTime = 0;
1286 barebones = 1;
1288 else
1290 TCflag = false;
1291 OperatorTime = 0;
1292 barebones = 0;
1295 Initialize();
1296 Initialize_dist();
1297 Initialize_eval();
1298 #if !defined SAVE_NEXTPOS
1299 Initialize_moves();
1300 #endif
1302 NewGame();
1304 flag.easy = ahead;
1305 flag.hash = hash;
1307 if (xwin)
1308 xwndw = atoi(xwin);
1310 #ifdef HASHFILE
1311 hashfile = NULL;
1312 #endif
1314 #if ttblsz
1315 #ifdef HASHFILE
1316 hashfile = fopen(HASHFILE, RWA_ACC);
1318 if (hashfile)
1320 fseek(hashfile, 0L, SEEK_END);
1321 filesz = ftell(hashfile) / sizeof(struct fileentry) - 1 - MAXrehash;
1322 hashmask = filesz >> 1;
1323 hashbase = hashmask + 1;
1325 #endif /* HASHFILE */
1326 #endif /* ttblsz */
1328 savefile[0] = '\0';
1329 listfile[0] = '\0';
1331 return 0;
1335 void
1336 ExitMain(void)
1338 #if ttblsz
1339 #ifdef HASHFILE
1340 if (hashfile)
1341 fclose(hashfile);
1342 #endif /* HASHFILE */
1343 #endif /* ttblsz */
1345 ExitShogi();