4 * ----------------------------------------------------------------------
5 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * Copyright (c) 1999 Michael Vanier and the Free Software Foundation
7 * Copyright (c) 2008, 2013, 2014 Yann Dirson and the Free Software Foundation
9 * GNU SHOGI is based on GNU CHESS
11 * Copyright (c) 1988, 1989, 1990 John Stanback
12 * Copyright (c) 1992 Free Software Foundation
14 * This file is part of GNU SHOGI.
16 * GNU Shogi is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 3 of the License,
19 * or (at your option) any later version.
21 * GNU Shogi is distributed in the hope that it will be useful, but WITHOUT
22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * You should have received a copy of the GNU General Public License along
27 * with GNU Shogi; see the file COPYING. If not, see
28 * <http://www.gnu.org/licenses/>.
29 * ----------------------------------------------------------------------
35 #if defined HAVE_GETTIMEOFDAY
43 /****************************************
44 * A variety of global flags.
45 ****************************************/
48 * If hard_time_limit is nonzero, exceeding the time limit means
52 short hard_time_limit = 1;
54 short nolist = 0; /* List the game after exit. */
56 short nolist = 1; /* Don't list the game after exit. */
60 * The default display type can be DISPLAY_RAW, DISPLAY_CURSES,
61 * or DISPLAY_X; the default is DISPLAY_X to make life easier for xshogi.
64 display_t display_type = DISPLAY_X;
66 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
69 const small_short psweep[NO_PTYPE_PIECES] =
71 false, true, false, false, false, true, true, true, true, false,
72 false, true, false, false, false
76 const small_short sweep[NO_PIECES] =
82 false, false, true, true,
87 false, true, true, false
90 const int typeMask[NO_PIECES] =
96 T_SILVER, T_GOLD, T_BISHOP, T_ROOK,
101 T_PSILVER, T_PBISHOP, T_PROOK, T_KING
107 distance(short a, short b)
109 return (short)computed_distance(a, b);
113 distance(short a, short b)
116 ? (short)(*distdata)[(int)a][(int)b]
117 : (short)computed_distance(a, b));
123 Initialize_dist(void)
125 short a, b, d, di, ptyp;
126 #ifndef SAVE_DISTDATA
127 for (a = 0; a < NO_SQUARES; a++)
129 for (b = 0; b < NO_SQUARES; b++)
131 d = abs(column(a) - column(b));
132 di = abs(row(a) - row(b));
133 (*distdata)[a][b] = (small_short)((d > di) ? d : di);
137 #ifndef SAVE_PTYPE_DISTDATA
138 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
140 for (a = 0; a < NO_SQUARES; a++)
141 for (b = 0; b < NO_SQUARES; b++)
142 (*ptype_distdata[ptyp])[a][b] = ptype_distance(ptyp, a, b);
149 * nextpos[ptype][from-square], nextdir[ptype][from-square] gives vector
150 * of positions reachable from from-square in ppos with ptype such that the
153 * ppos = nextpos[ptype][from-square];
154 * pdir = nextdir[ptype][from-square];
161 * if(color[u] != neutral)
166 * will generate the sequence of all squares reachable from sq.
168 * If the path is blocked u = pdir[sq] will generate the continuation of the
169 * sequence in other directions.
173 const small_short is_promoted[NO_PIECES] =
179 false, false, false, false,
184 true, true, true, false
187 /* data used to generate nextpos/nextdir */
189 /* FIXME: use predefined constants ! */
190 #if !defined SAVE_NEXTPOS
193 const small_short direc[NO_PTYPE_PIECES][8] =
195 { 11, 0, 0, 0, 0, 0, 0, 0 }, /* 0 ptype_pawn */
196 { 11, 0, 0, 0, 0, 0, 0, 0 }, /* 1 ptype_lance */
197 { 21, 23, 0, 0, 0, 0, 0, 0 }, /* 2 ptype_knight */
198 { 10, 11, 12, -12, -10, 0, 0, 0 }, /* 3 ptype_silver */
199 { 10, 11, 12, -1, 1, -11, 0, 0 }, /* 4 ptype_gold */
200 { 10, 12, -12, -10, 0, 0, 0, 0 }, /* 5 ptype_bishop */
201 { 11, -1, 1, -11, 0, 0, 0, 0 }, /* 6 ptype_rook */
202 { 10, 12, -12, -10, 11, -1, 1, -11 }, /* 7 ptype_pbishop */
203 { 11, -1, 1, -11, 10, 12, -12, -10 }, /* 8 ptype_prook */
204 { 10, 11, 12, -1, 1, -12, -11, -10 }, /* 9 ptype_king */
205 { -11, 0, 0, 0, 0, 0, 0, 0 }, /* 10 ptype_wpawn */
206 { -11, 0, 0, 0, 0, 0, 0, 0 }, /* 11 ptype_wlance */
207 { -21, -23, 0, 0, 0, 0, 0, 0 }, /* 12 ptype_wknight */
208 { -10, -11, -12, 12, 10, 0, 0, 0 }, /* 13 ptype_wsilver */
209 { -10, -11, -12, 1, -1, 11, 0, 0 } /* 14 ptype_wgold */
212 #if !defined SAVE_NEXTPOS
215 const small_short direc[NO_PTYPE_PIECES][8] =
217 { 7, 0, 0, 0, 0, 0, 0, 0 }, /* 0 ptype_pawn */
218 { 6, 7, 8, -8, -6, 0, 0, 0 }, /* 3 ptype_silver */
219 { 6, 7, 8, -1, 1, -7, 0, 0 }, /* 4 ptype_gold */
220 { 6, 8, -8, -6, 0, 0, 0, 0 }, /* 5 ptype_bishop */
221 { 7, -1, 1, -7, 0, 0, 0, 0 }, /* 6 ptype_rook */
222 { 6, 8, -8, -6, 7, -1, 1, -7 }, /* 7 ptype_pbishop */
223 { 7, -1, 1, -7, 6, 8, -8, -6 }, /* 8 ptype_prook */
224 { 6, 7, 8, -1, 1, -8, -7, -6 }, /* 9 ptype_king */
225 { -7, 0, 0, 0, 0, 0, 0, 0 }, /* 10 ptype_wpawn */
226 { -6, -7, -8, 8, 6, 0, 0, 0 }, /* 13 ptype_wsilver */
227 { -6, -7, -8, 1, -1, 7, 0, 0 } /* 14 ptype_wgold */
232 small_short diagonal(short d)
234 return (abs(d) == (NO_COLS+1) || abs(d) == (NO_COLS+3));
240 static const small_short max_steps[NO_PTYPE_PIECES] =
242 1, 8, 1, 1, 1, 8, 8, 8, 8, 1, 1, 8, 1, 1, 1
245 static const small_short max_steps[NO_PTYPE_PIECES] =
247 1, 1, 1, 4, 4, 4, 4, 1, 1, 1, 1
252 const small_short nunmap[(NO_COLS + 2)*(NO_ROWS + 4)] =
254 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
255 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
256 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1,
257 -1, 9, 10, 11, 12, 13, 14, 15, 16, 17, -1,
258 -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1,
259 -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
260 -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1,
261 -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1,
262 -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1,
263 -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, -1,
264 -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, -1,
265 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
266 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
270 const small_short inunmap[NO_SQUARES] =
272 23, 24, 25, 26, 27, 28, 29, 30, 31,
273 34, 35, 36, 37, 38, 39, 40, 41, 42,
274 45, 46, 47, 48, 49, 50, 51, 52, 53,
275 56, 57, 58, 59, 60, 61, 62, 63, 64,
276 67, 68, 69, 70, 71, 72, 73, 74, 75,
277 78, 79, 80, 81, 82, 83, 84, 85, 86,
278 89, 90, 91, 92, 93, 94, 95, 96, 97,
279 100, 101, 102, 103, 104, 105, 106, 107, 108,
280 111, 112, 113, 114, 115, 116, 117, 118, 119
283 const small_short nunmap[(NO_COLS + 2)*(NO_ROWS + 2)] =
285 -1, -1, -1, -1, -1, -1, -1,
286 -1, 0, 1, 2, 3, 4, -1,
287 -1, 5, 6, 7, 8, 9, -1,
288 -1, 10, 11, 12, 13, 14, -1,
289 -1, 15, 16, 17, 18, 19, -1,
290 -1, 20, 21, 22, 23, 24, -1,
291 -1, -1, -1, -1, -1, -1, -1,
295 const small_short inunmap[NO_SQUARES] =
305 int InitFlag = false;
308 #if defined SAVE_NEXTPOS
311 next_direction(short ptyp, short *d, short sq)
313 short delta, to, sfrom = inunmap[sq];
321 delta = direc[ptyp][*d];
325 to = nunmap[sfrom + delta];
334 next_position(short ptyp, short *d, short sq, short u)
336 if (*d < 4 && psweep[ptyp])
338 short to = nunmap[inunmap[u] + direc[ptyp][*d]];
341 return next_direction(ptyp, d, sq);
347 return next_direction(ptyp, d, sq);
353 first_direction(short ptyp, short *d, short sq)
356 return next_direction(ptyp, d, sq);
362 * This procedure pre-calculates all moves for every piece from every
363 * square. This data is stored in nextpos/nextdir and used later in the
364 * move generation routines.
368 Initialize_moves(void)
370 short ptyp, po, p0, d, di, s, delta;
371 unsigned char *ppos, *pdir;
375 short fpo = inunmap[0], tpo = 1 + inunmap[NO_SQUARES-1];
377 /* pre-fill nextpos and nextdir with source position, probably so
378 * (color[u] == neutral) stops to match once all moves have been seen
380 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
382 for (po = 0; po < NO_SQUARES; po++)
384 for (p0 = 0; p0 < NO_SQUARES; p0++)
386 (*nextpos[ptyp])[po][p0] = (unsigned char)po;
387 (*nextdir[ptyp])[po][p0] = (unsigned char)po;
392 for (ptyp = 0; ptyp < NO_PTYPE_PIECES; ptyp++)
394 for (po = fpo; po < tpo; po++)
396 if (nunmap[po] >= (small_short)0)
398 ppos = (*nextpos[ptyp])[nunmap[po]];
399 pdir = (*nextdir[ptyp])[nunmap[po]];
401 /* dest is a function of direction and steps */
402 for (d = 0; d < 8; d++)
404 dest[d][0] = nunmap[po];
405 delta = direc[ptyp][d];
411 for (s = 0; s < max_steps[ptyp]; s++)
416 * break if (off board) or (promoted rooks
417 * wishes to move two steps diagonal) or
418 * (promoted bishops wishes to move two steps
421 if ((nunmap[p0] < (small_short)0)
422 || ((ptyp == ptype_prook)
425 || ((ptyp == ptype_pbishop)
427 && !diagonal(delta)))
430 dest[d][s] = nunmap[p0];
439 * Sort dest in number of steps order; currently no sort
440 * is done due to compatibility with the move generation
441 * order in old gnuchess.
446 for (di = d; s > 0 && di > 0; di--)
448 if (steps[sorted[di - 1]] == 0) /* should be: < s */
449 sorted[di] = sorted[di - 1];
458 * update nextpos/nextdir
462 pdir[p0] = (unsigned char)dest[sorted[0]][0];
464 for (d = 0; d < 8; d++)
466 for (s = 0; s < steps[sorted[d]]; s++)
468 ppos[p0] = (unsigned char)dest[sorted[d]][s];
469 p0 = dest[sorted[d]][s];
472 pdir[p0] = (unsigned char)dest[sorted[d + 1]][0];
475 * else is already initialized
489 * Reset the board and other variables to start a new game.
495 short l, c, p, max_opening_sequence;
496 #ifdef HAVE_GETTIMEOFDAY
499 compptr = oppptr = 0;
501 stage2 = -1; /* the game is not yet started */
502 flag.illegal = flag.mate = flag.quit
503 = flag.reverse = flag.bothsides = flag.onemove = flag.force
505 flag.post &= xboard; /* xboard: do not alter post status on 'new' */
506 flag.material = flag.coords = flag.hash = flag.easy
507 = flag.beep = flag.rcptr
509 flag.stars = flag.shade = flag.back = flag.musttimeout = false;
514 GenCnt = NodeCnt = et0 = dither = XCmore = 0;
523 MaxSearchDepth = MAXDEPTH - 1;
528 CptrFlag[0] = TesujiFlag[0] = false;
531 GameType[0] = GameType[1] = UNKNOWN;
532 Pscore[0] = Tscore[0] = (SCORE_LIMIT + 3000);
533 opponent = player = black;
536 for (l = 0; l < TREE; l++)
537 Tree[l].f = Tree[l].t = 0;
539 gsrand((unsigned int) 1);
543 for (c = black; c <= white; c++)
545 for (p = pawn; p <= king; p++)
547 for (l = 0; l < NO_SQUARES; l++)
549 (*hashcode)[c][p][l].key
550 = (((unsigned long) urand()));
551 (*hashcode)[c][p][l].key
552 += (((unsigned long) urand()) << 16);
553 (*hashcode)[c][p][l].bd
554 = (((unsigned long) urand()));
555 (*hashcode)[c][p][l].bd
556 += (((unsigned long) urand()) << 16);
557 #if SIZEOF_LONG == 8 /* 64-bit long i.e. 8 bytes */
558 (*hashcode)[c][p][l].key
559 += (((unsigned long) urand()) << 32);
560 (*hashcode)[c][p][l].key
561 += (((unsigned long) urand()) << 48);
562 (*hashcode)[c][p][l].bd
563 += (((unsigned long) urand()) << 32);
564 (*hashcode)[c][p][l].bd
565 += (((unsigned long) urand()) << 48);
571 for (c = black; c <= white; c++)
573 for (p = pawn; p <= king; p++)
575 for (l = 0; l < MAX_CAPTURED; l++)
577 (*drop_hashcode)[c][p][l].key
578 = (((unsigned long) urand()));
579 (*drop_hashcode)[c][p][l].key
580 += (((unsigned long) urand()) << 16);
581 (*drop_hashcode)[c][p][l].bd
582 = (((unsigned long) urand()));
583 (*drop_hashcode)[c][p][l].bd
584 += (((unsigned long) urand()) << 16);
585 #if SIZEOF_LONG == 8 /* 64-bit long i.e. 8 bytes */
586 (*drop_hashcode)[c][p][l].key
587 += (((unsigned long) urand()) << 32);
588 (*drop_hashcode)[c][p][l].key
589 += (((unsigned long) urand()) << 48);
590 (*drop_hashcode)[c][p][l].bd
591 += (((unsigned long) urand()) << 32);
592 (*drop_hashcode)[c][p][l].bd
593 += (((unsigned long) urand()) << 48);
600 for (l = 0; l < NO_SQUARES; l++)
602 board[l] = Stboard[l];
603 color[l] = Stcolor[l];
611 #ifdef HAVE_GETTIMEOFDAY
612 gettimeofday(&tv, NULL);
613 time0 = tv.tv_sec*100 + tv.tv_usec/10000;
615 time0 = time((long *) 0);
618 /* resetting reference time */
619 ElapsedTime(COMPUTE_AND_INIT_MODE);
620 flag.regularstart = true;
630 else if (MaxResponseTime == 0)
631 dsp->SelectLevel(sx);
633 dsp->UpdateDisplay(0, 0, 1, 0);
635 GetOpeningPatterns(&max_opening_sequence);
648 hashbd = hashkey = 0;
658 gsrand(starttime = ((unsigned int)time((long *)0))); /* init urand */
665 if (Initialize_data() != 0)
668 strcpy(ColorStr[0], "Black");
669 strcpy(ColorStr[1], "White");
693 #if !defined SAVE_NEXTPOS
711 hashfile = fopen(HASHFILE, RWA_ACC);
715 fseek(hashfile, 0L, SEEK_END);
716 filesz = ftell(hashfile) / sizeof(struct fileentry) - 1 - MAXrehash;
717 hashmask = filesz >> 1;
718 hashbase = hashmask + 1;
720 #endif /* HASHFILE */
737 #endif /* HASHFILE */