2 * init.c - C source for GNU SHOGI
4 * Copyright (c) 1993 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)
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.
30 #if defined HASGETTIMEOFDAY && !defined THINK_C
34 extern unsigned int TTadd
;
35 unsigned int ttbllimit
;
37 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
46 #define abs(a) (((a)<0)?-(a):(a))
48 #define max(a,b) (((a)<(b))?(b):(a))
49 #define odd(a) ((a) & 1)
53 #define malloc(size) farmalloc(size)
57 const small_short piece_of_ptype
[NO_PTYPE_PIECES
] =
58 { pawn
, lance
, knight
, silver
, gold
, bishop
, rook
, pbishop
, prook
, king
,
59 pawn
, lance
, knight
, silver
, gold
};
62 const small_short side_of_ptype
[NO_PTYPE_PIECES
] =
63 { black
, black
, black
, black
, black
, black
, black
, black
, black
, black
,
64 white
, white
, white
, white
, white
};
67 static const sweep
[NO_PTYPE_PIECES
] =
68 { false, true, false, false, false, true, true, true, true, false,
69 false, true, false, false, false };
74 ptype_distance (short ptyp
, short f
, short t
)
77 * Determine the minimum number of moves for a piece from
78 * square "f" to square "t". If the piece cannot reach "t",
79 * the count is set to CANNOT_REACH.
82 #define csquare(sq) ((side == black) ? sq : (NO_SQUARES-1-sq))
83 #define crow(sq) row(csquare(sq))
84 #define ccol(sq) column(csquare(sq))
88 short colf
, colt
, rowf
, rowt
, dcol
, drow
;
93 piece
= piece_of_ptype
[ptyp
];
94 side
= side_of_ptype
[ptyp
];
96 dcol
= (colt
= ccol(t
)) - (colf
= ccol(f
));
97 drow
= (rowt
= crow(t
)) - (rowf
= crow(f
));
102 if ( (dcol
!= 0) || (drow
!= 1) )
103 return (CANNOT_REACH
);
108 if ( (dcol
!= 0) || (drow
< 1) )
109 return (CANNOT_REACH
);
114 if ( odd(drow
) || (odd(drow
/ 2) != odd(dcol
)) )
115 return (CANNOT_REACH
);
116 else if ( (drow
== 0) || ((drow
/ 2) < abs(dcol
)) )
117 return (CANNOT_REACH
);
122 if ( odd(drow
) == odd(dcol
) )
123 return max(abs(drow
),abs(dcol
));
125 if ( abs(dcol
) <= drow
)
128 return (max(abs(drow
),abs(dcol
))+1);
129 else if ( dcol
== 0 )
132 return (max(abs(drow
),abs(dcol
))+1);
139 if ( abs(dcol
) == 0 )
141 else if ( drow
>= 0 )
142 return max(drow
,abs(dcol
));
144 return (abs(dcol
)-drow
);
147 if ( odd(dcol
) != odd(drow
) )
148 return (CANNOT_REACH
);
150 return ((abs(dcol
) == abs(drow
)) ? 1 : 2);
153 if ( odd(dcol
) != odd(drow
) )
154 if ( (abs(dcol
) <= 1) && (abs(drow
) <= 1) )
156 else if ( abs(abs(dcol
) - abs(drow
)) == 1 )
161 return ((abs(dcol
) == abs(drow
)) ? 1 : 2);
164 if ( (dcol
== 0) || (drow
== 0) )
170 if ( (dcol
== 0) || (drow
== 0) )
172 else if ( (abs(dcol
) == 1) && (abs(drow
) == 1) )
178 return max(abs(drow
),abs(dcol
));
181 /* should never occur */
182 return (CANNOT_REACH
);
189 #ifndef SAVE_DISTDATA
190 distdata_array
*distdata
;
193 #ifndef SAVE_PTYPE_DISTDATA
194 distdata_array
*ptype_distdata
[NO_PTYPE_PIECES
];
199 Initialize_dist (void)
201 register short a
, b
, d
, di
, ptyp
;
202 #ifndef SAVE_DISTDATA
203 if ( (distdata
= (distdata_array
*) malloc (sizeof(distdata_array
))) == NULL
)
205 ShowMessage("cannot allocate distdata space...");
208 for (a
= 0; a
< NO_SQUARES
; a
++)
209 for (b
= 0; b
< NO_SQUARES
; b
++)
211 d
= abs (column (a
) - column (b
));
212 di
= abs (row (a
) - row (b
));
213 (*distdata
)[a
][b
] = (small_short
)((d
> di
) ? d
: di
);
216 #ifndef SAVE_PTYPE_DISTDATA
217 for (ptyp
= 0; ptyp
< NO_PTYPE_PIECES
; ptyp
++)
219 size_t space
= sizeof(distdata_array
);
220 ptype_distdata
[ptyp
] = (distdata_array
*) malloc (space
);
221 if ( ptype_distdata
[ptyp
] == NULL
)
223 ShowMessage("cannot allocate ptype_distdata space...");
226 for (a
= 0; a
< NO_SQUARES
; a
++)
227 for (b
= 0; b
< NO_SQUARES
; b
++)
228 (*ptype_distdata
[ptyp
])[a
][b
] = ptype_distance(ptyp
,a
,b
);
235 * nextpos[piece][from-square] , nextdir[piece][from-square] gives vector of
236 * positions reachable from from-square in ppos with piece such that the
237 * sequence ppos = nextpos[piece][from-square]; pdir =
238 * nextdir[piece][from-square]; u = ppos[sq]; do { u = ppos[u]; if(color[u]
239 * != neutral) u = pdir[u]; } while (sq != u); will generate the sequence of
240 * all squares reachable from sq.
242 * If the path is blocked u = pdir[sq] will generate the continuation of the
243 * sequence in other directions.
247 #if !defined SAVE_NEXTPOS
248 next_array
*nextdir
[NO_PTYPE_PIECES
], *nextpos
[NO_PTYPE_PIECES
];
253 * ptype is used to separate black and white pawns, like this; ptyp =
254 * ptype[side][piece] piece can be used directly in nextpos/nextdir when
255 * generating moves for pieces that are not white pawns.
258 const small_short ptype
[2][NO_PIECES
] =
259 { ptype_no_piece
, ptype_pawn
, ptype_lance
, ptype_knight
,
260 ptype_silver
, ptype_gold
, ptype_bishop
, ptype_rook
,
261 ptype_gold
, ptype_gold
, ptype_gold
, ptype_gold
,
262 ptype_pbishop
, ptype_prook
, ptype_king
,
263 ptype_no_piece
, ptype_wpawn
, ptype_wlance
, ptype_wknight
,
264 ptype_wsilver
, ptype_wgold
, ptype_bishop
, ptype_rook
,
265 ptype_wgold
, ptype_wgold
, ptype_wgold
, ptype_wgold
,
266 ptype_pbishop
, ptype_prook
, ptype_king
};
268 const small_short promoted
[NO_PIECES
] =
269 { no_piece
, ppawn
, plance
, pknight
, psilver
, gold
, pbishop
, prook
,
270 ppawn
, plance
, pknight
, psilver
, pbishop
, prook
, king
};
272 const small_short unpromoted
[NO_PIECES
] =
273 { no_piece
, pawn
, lance
, knight
, silver
, gold
, bishop
, rook
,
274 pawn
, lance
, knight
, silver
, bishop
, rook
, king
};
276 const small_short is_promoted
[NO_PIECES
] =
277 { false, false, false, false, false, false, false, false,
278 true, true, true, true, true, true, false };
280 /* data used to generate nextpos/nextdir */
281 #if !defined SAVE_NEXTPOS
284 const small_short direc
[NO_PTYPE_PIECES
][8] =
286 11, 0, 0, 0, 0, 0, 0, 0 , /* 0 ptype_pawn */
287 11, 0, 0, 0, 0, 0, 0, 0 , /* 1 ptype_lance */
288 21, 23, 0, 0, 0, 0, 0, 0 , /* 2 ptype_knight */
289 10, 11, 12,-12,-10, 0, 0, 0 , /* 3 ptype_silver */
290 10, 11, 12, -1, 1,-11, 0, 0 , /* 4 ptype_gold */
291 10, 12,-12,-10, 0, 0, 0, 0 , /* 5 ptype_bishop */
292 11, -1, 1,-11, 0, 0, 0, 0 , /* 6 ptype_rook */
293 10, 12,-12,-10, 11, -1, 1,-11 , /* 7 ptype_pbishop */
294 11, -1, 1,-11, 10, 12,-12,-10 , /* 8 ptype_prook */
295 10, 11, 12, -1, 1,-12,-11,-10 , /* 9 ptype_king */
296 -11, 0, 0, 0, 0, 0, 0, 0 , /* 10 ptype_wpawn */
297 -11, 0, 0, 0, 0, 0, 0, 0 , /* 11 ptype_wlance */
298 -21,-23, 0, 0, 0, 0, 0, 0 , /* 12 ptype_wknight */
299 -10,-11,-12, 12, 10, 0, 0, 0 , /* 13 ptype_wsilver */
300 -10,-11,-12, 1, -1, 11, 0, 0 }; /* 14 ptype_wgold */
303 small_short
diagonal(short d
)
304 { return(abs(d
) == 10 || abs(d
) == 12);
308 static const small_short max_steps
[NO_PTYPE_PIECES
] =
309 {1, 8, 1, 1, 1, 8, 8, 8, 8, 1, 1, 8, 1, 1, 1 };
311 #if !defined SAVE_NEXTPOS
314 const small_short nunmap
[(NO_COLS
+2)*(NO_ROWS
+4)] =
316 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
317 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
318 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1,
319 -1, 9, 10, 11, 12, 13, 14, 15, 16, 17, -1,
320 -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, -1,
321 -1, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1,
322 -1, 36, 37, 38, 39, 40, 41, 42, 43, 44, -1,
323 -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1,
324 -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, -1,
325 -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, -1,
326 -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, -1,
327 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
328 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
332 const small_short inunmap
[NO_SQUARES
] =
334 23, 24, 25, 26, 27, 28, 29, 30, 31,
335 34, 35, 36, 37, 38, 39, 40, 41, 42,
336 45, 46, 47, 48, 49, 50, 51, 52, 53,
337 56, 57, 58, 59, 60, 61, 62, 63, 64,
338 67, 68, 69, 70, 71, 72, 73, 74, 75,
339 78, 79, 80, 81, 82, 83, 84, 85, 86,
340 89, 90, 91, 92, 93, 94, 95, 96, 97,
341 100,101,102,103,104,105,106,107,108,
342 111,112,113,114,115,116,117,118,119 };
345 int InitFlag
= false;
348 #if defined SAVE_NEXTPOS
350 short next_direction(short ptyp
, short *d
, short sq
)
352 short delta
, to
, sfrom
= inunmap
[sq
];
355 if ( *d
>= 8 ) return sq
;
356 delta
= direc
[ptyp
][*d
];
357 if ( delta
== 0 ) return sq
;
358 to
= nunmap
[sfrom
+ delta
];
363 short next_position(short ptyp
, short *d
, short sq
, short u
)
365 if ( *d
< 4 && sweep
[ptyp
] ) {
366 short to
= nunmap
[inunmap
[u
]+direc
[ptyp
][*d
]];
368 return next_direction(ptyp
,d
,sq
);
372 return next_direction(ptyp
,d
,sq
);
376 short first_direction(short ptyp
, short *d
, short sq
)
379 return next_direction(ptyp
,d
,sq
);
385 Initialize_moves (void)
388 * This procedure pre-calculates all moves for every piece from every square.
389 * This data is stored in nextpos/nextdir and used later in the move
390 * generation routines.
394 short ptyp
, po
, p0
, d
, di
, s
, delta
;
395 unsigned char *ppos
, *pdir
;
399 short fpo
=23,tpo
=120;
401 for (ptyp
= 0; ptyp
< NO_PTYPE_PIECES
; ptyp
++)
403 if ( !(nextdir
[ptyp
] = (next_array
*) malloc ((size_t)sizeof(next_array
))) )
405 ShowMessage ("cannot allocate nextdir space\n");
408 if ( !(nextpos
[ptyp
] = (next_array
*) malloc ((size_t)sizeof(next_array
))) )
410 ShowMessage ("cannot allocate nextpos space\n");
413 for (po
= 0; po
< NO_SQUARES
; po
++)
414 for (p0
= 0; p0
< NO_SQUARES
; p0
++)
416 (*nextpos
[ptyp
])[po
][p0
] = (unsigned char) po
;
417 (*nextdir
[ptyp
])[po
][p0
] = (unsigned char) po
;
421 for (ptyp
= 0; ptyp
< NO_PTYPE_PIECES
; ptyp
++)
422 for (po
= fpo
; po
< tpo
; po
++)
423 if (nunmap
[po
] >= (small_short
)0)
425 ppos
= (*nextpos
[ptyp
])[nunmap
[po
]];
426 pdir
= (*nextdir
[ptyp
])[nunmap
[po
]];
427 /* dest is a function of direction and steps */
428 for (d
= 0; d
< 8; d
++)
430 dest
[d
][0] = nunmap
[po
];
431 delta
= direc
[ptyp
][d
];
435 for (s
= 0; s
< max_steps
[ptyp
]; s
++)
440 * break if (off board) or (promoted rooks wishes to
441 * move two steps diagonal) or (promoted
442 * bishops wishes to move two steps non-diagonal)
444 if ( (nunmap
[p0
] < (small_short
)0) ||
445 ((ptyp
== ptype_prook
) && (s
> 0) && diagonal(delta
)) ||
446 ((ptyp
== ptype_pbishop
) && (s
> 0) && !diagonal(delta
)) )
449 dest
[d
][s
] = nunmap
[p0
];
456 * sort dest in number of steps order currently no sort
457 * is done due to compability with the move generation
458 * order in old gnu chess
461 for (di
= d
; s
> 0 && di
> 0; di
--)
462 if (steps
[sorted
[di
- 1]] == 0) /* should be: < s */
463 sorted
[di
] = sorted
[di
- 1];
470 * update nextpos/nextdir
473 pdir
[p0
] = (unsigned char) dest
[sorted
[0]][0];
474 for (d
= 0; d
< 8; d
++)
475 for (s
= 0; s
< steps
[sorted
[d
]]; s
++)
477 ppos
[p0
] = (unsigned char) dest
[sorted
[d
]][s
];
478 p0
= dest
[sorted
[d
]][s
];
480 pdir
[p0
] = (unsigned char) dest
[sorted
[d
+ 1]][0];
483 * else is already initialized
496 * Reset the board and other variables to start a new game.
501 #ifdef HASGETTIMEOFDAY
504 compptr
= oppptr
= 0;
505 stage
= stage2
= -1; /* the game is not yet started */
506 flag
.illegal
= flag
.mate
= flag
.post
= flag
.quit
= flag
.reverse
= flag
.bothsides
= flag
.onemove
= flag
.force
= false;
507 flag
.material
= flag
.coords
= flag
.hash
= flag
.easy
= flag
.beep
= flag
.rcptr
= true;
508 flag
.stars
= flag
.shade
= flag
.back
= flag
.musttimeout
= false;
510 #if defined(MSDOS) && !defined(SEVENBIT)
514 #endif /* MSDOS && !SEVENBIT */
516 GenCnt
= NodeCnt
= et0
= dither
= XCmore
= 0;
524 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
;
535 for (l
= 0; l
< TREE
; l
++)
536 Tree
[l
].f
= Tree
[l
].t
= 0;
537 gsrand ((unsigned int) 1);
540 for (c
= black
; c
<= white
; c
++)
541 for (p
= pawn
; p
<= king
; p
++)
542 for (l
= 0; l
< NO_SQUARES
; l
++)
544 hashcode
[c
][p
][l
].key
= (((unsigned long) urand ()));
545 hashcode
[c
][p
][l
].key
+= (((unsigned long) urand ()) << 16);
546 hashcode
[c
][p
][l
].bd
= (((unsigned long) urand ()));
547 hashcode
[c
][p
][l
].bd
+= (((unsigned long) urand ()) << 16);
549 hashcode
[c
][p
][l
].key
+= (((unsigned long) urand ()) << 32);
550 hashcode
[c
][p
][l
].key
+= (((unsigned long) urand ()) << 48);
551 hashcode
[c
][p
][l
].bd
+= (((unsigned long) urand ()) << 32);
552 hashcode
[c
][p
][l
].bd
+= (((unsigned long) urand ()) << 48);
555 for (c
= black
; c
<= white
; c
++)
556 for (p
= pawn
; p
<= king
; p
++)
557 for (l
= 0; l
< MAX_CAPTURED
; l
++)
559 drop_hashcode
[c
][p
][l
].key
= (((unsigned long) urand ()));
560 drop_hashcode
[c
][p
][l
].key
+= (((unsigned long) urand ()) << 16);
561 drop_hashcode
[c
][p
][l
].bd
= (((unsigned long) urand ()));
562 drop_hashcode
[c
][p
][l
].bd
+= (((unsigned long) urand ()) << 16);
564 drop_hashcode
[c
][p
][l
].key
+= (((unsigned long) urand ()) << 32);
565 drop_hashcode
[c
][p
][l
].key
+= (((unsigned long) urand ()) << 48);
566 drop_hashcode
[c
][p
][l
].bd
+= (((unsigned long) urand ()) << 32);
567 drop_hashcode
[c
][p
][l
].bd
+= (((unsigned long) urand ()) << 48);
571 for (l
= 0; l
< NO_SQUARES
; l
++)
573 board
[l
] = Stboard
[l
];
574 color
[l
] = Stcolor
[l
];
580 #ifdef HASGETTIMEOFDAY
581 gettimeofday(&tv
, NULL
);
582 time0
= tv
.tv_sec
*100+tv
.tv_usec
/10000;
584 time0
= time ((long *) 0);
586 /* resetting reference time */
587 ElapsedTime (COMPUTE_AND_INIT_MODE
);
588 flag
.regularstart
= true;
596 else if (MaxResponseTime
== 0)
598 UpdateDisplay (0, 0, 1, 0);
601 GetOpeningPatterns ();
602 /* ShowOpeningPatterns (); */
610 if(TTadd
){ZeroTTable (); TTadd
= 0;}
612 hashbd
= hashkey
= 0;
617 #if !defined GDISPLAY
621 InitConst (char *lang
)
629 constfile
= fopen (LANGFILE
, "r");
632 ShowMessage ("NO LANGFILE");
635 while (fgets (s
, sizeof (s
), constfile
))
640 for (q
= &s
[len
]; q
> &s
[8]; q
--)
645 ShowMessage("{ error in cinstfile");
649 if (s
[3] != ':' || s
[7] != ':' || s
[8] != '{')
651 sprintf (buffer
,"Langfile format error %s", s
);
661 if (strcmp (&s
[4], lang
))
664 if (entry
< 0 || entry
>= CPSIZE
)
666 ShowMessage("Langfile number error");
669 for (q
= p
= &s
[9]; *p
; p
++)
675 else if (*(p
+ 1) == 'n')
682 if (entry
< 0 || entry
> 255)
684 sprintf (buffer
,"Langfile error %d\n", entry
);
688 CP
[entry
] = (char *) malloc ((unsigned) strlen (&s
[9]) + 1);
689 if (CP
[entry
] == NULL
)
692 sprintf(buffer
,"CP malloc, entry %d",entry
);
696 strcpy (CP
[entry
], &s
[9]);
715 #if !defined BAREBONES && defined NONDSP
717 sprintf(s
,"expected ttable is %ld",(long)ttblsize
);
722 while ( doit
&& ttblsize
> MINTTABLE
) {
723 ttable
[0] = (struct hashentry
*)malloc((unsigned)(sizeof(struct hashentry
))*(ttblsize
+rehash
));
724 ttable
[1] = (struct hashentry
*)malloc((unsigned)(sizeof(struct hashentry
))*(ttblsize
+rehash
));
725 if (ttable
[0] == NULL
|| ttable
[1] == NULL
) {
726 if (ttable
[0] != NULL
) free(ttable
[0]);
727 if (ttable
[1] != NULL
) free(ttable
[1]);
728 ttblsize
= ttblsize
>> 1;
732 if (ttable
[0] == NULL
|| ttable
[1] == NULL
) {
733 perror("ttable memory alloc");
737 #if defined NONDSP && !defined XSHOGI
739 sprintf(s
,"ttable is %ld",(long)ttblsize
);
744 ttbllimit
= ttblsize
<<1 - ttblsize
>>2;