Merge branch 'maint'
[gnushogi.git] / gnushogi / init-common.c
blob945f9e05310fcbef866c410353b1c88160b5de5d
1 #include "gnushogi.h"
2 #include "pattern.h"
4 unsigned int ttbllimit;
6 /*
7 * ptype is used to separate black and white pawns, like this; ptyp =
8 * ptype[side][piece] piece can be used directly in nextpos/nextdir when
9 * generating moves for pieces that are not white pawns.
12 const small_short ptype[2][NO_PIECES] =
15 ptype_no_piece, ptype_pawn,
16 #ifndef MINISHOGI
17 ptype_lance, ptype_knight,
18 #endif
19 ptype_silver, ptype_gold, ptype_bishop, ptype_rook,
20 ptype_gold,
21 #ifndef MINISHOGI
22 ptype_gold, ptype_gold,
23 #endif
24 ptype_gold,
25 ptype_pbishop, ptype_prook, ptype_king
28 ptype_no_piece, ptype_wpawn,
29 #ifndef MINISHOGI
30 ptype_wlance, ptype_wknight,
31 #endif
32 ptype_wsilver, ptype_wgold, ptype_bishop, ptype_rook,
33 ptype_wgold,
34 #ifndef MINISHOGI
35 ptype_wgold, ptype_wgold,
36 #endif
37 ptype_wgold,
38 ptype_pbishop, ptype_prook, ptype_king
42 const small_short promoted[NO_PIECES] =
44 no_piece, ppawn,
45 #ifndef MINISHOGI
46 plance, pknight,
47 #endif
48 psilver, gold, pbishop, prook,
49 ppawn,
50 #ifndef MINISHOGI
51 plance, pknight,
52 #endif
53 psilver, pbishop, prook, king
56 const small_short unpromoted[NO_PIECES] =
58 no_piece, pawn,
59 #ifndef MINISHOGI
60 lance, knight,
61 #endif
62 silver, gold, bishop, rook,
63 pawn,
64 #ifndef MINISHOGI
65 lance, knight,
66 #endif
67 silver, bishop, rook, king
71 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
73 #ifndef WIN32
74 #define max(a, b) (((a) < (b))?(b):(a))
75 #endif
76 #define odd(a) ((a) & 1)
78 const small_short piece_of_ptype[NO_PTYPE_PIECES] =
80 pawn,
81 #ifndef MINISHOGI
82 lance, knight,
83 #endif
84 silver, gold, bishop, rook, pbishop, prook, king,
85 pawn,
86 #ifndef MINISHOGI
87 lance, knight,
88 #endif
89 silver, gold
93 /* FIXME: all bishops and rooks are black ? */
94 const small_short side_of_ptype[NO_PTYPE_PIECES] =
96 black,
97 #ifndef MINISHOGI
98 black, black,
99 #endif
100 black, black, black, black, black, black, black,
101 white,
102 #ifndef MINISHOGI
103 white, white,
104 #endif
105 white, white
110 Initialize_data(void)
112 size_t n;
113 int i;
114 char buffer[60];
115 int doit = true;
118 small_short x = -1;
120 if (x >= 0)
122 dsp->ShowMessage("datatype 'small_short' is unsigned; "
123 "check gnushogi.h\n");
124 return 1;
128 n = sizeof(struct leaf) * (size_t)TREE;
129 Tree = malloc(n);
131 if (!Tree)
133 sprintf(buffer, "Cannot allocate %ld bytes for search tree",
134 (long)n);
135 dsp->ShowMessage(buffer);
136 return 1;
139 n = sizeof(hashcode_array);
140 hashcode = malloc(n);
142 if (!hashcode)
144 sprintf(buffer, "Cannot allocate %ld bytes for hashcode", (long)n);
145 dsp->ShowMessage(buffer);
146 return 1;
149 n = sizeof(drop_hashcode_array);
150 drop_hashcode = malloc(n);
152 if (!drop_hashcode)
154 sprintf(buffer,
155 "Cannot allocate %ld bytes for drop_hashcode",
156 (long)n);
157 dsp->ShowMessage(buffer);
158 return 1;
161 n = sizeof(struct GameRec) * (size_t)(MAXMOVES + MAXDEPTH);
162 GameList = malloc(n);
164 if (!GameList)
166 sprintf(buffer,
167 "Cannot allocate %ld bytes for game record",
168 (long)n);
169 dsp->ShowMessage(buffer);
170 return 1;
173 #if !defined SAVE_NEXTPOS
174 n = sizeof(next_array);
176 for (i = 0; i < NO_PTYPE_PIECES; i++)
178 nextdir[i] = use_nextpos ? malloc(n) : NULL;
180 if (!nextdir[i])
182 if (use_nextpos)
184 sprintf(buffer, "cannot allocate %ld space for nextdir %d",
185 (long)(n), i);
186 dsp->ShowMessage(buffer);
189 nextdir[i] = NULL;
190 use_nextpos = false;
193 nextpos[i] = use_nextpos ? malloc(n) : NULL;
195 if (!nextpos[i])
197 if (use_nextpos)
199 sprintf(buffer, "cannot allocate %ld space for nextpos %d",
200 (long)(n), i);
201 dsp->ShowMessage(buffer);
204 use_nextpos = false;
208 if (!use_nextpos)
210 return 1;
212 #endif
214 n = sizeof(value_array);
215 value = malloc(n);
217 if (!value)
219 dsp->ShowMessage("cannot allocate value space");
220 return 1;
223 n = sizeof(fscore_array);
224 fscore = malloc(n);
226 if (!fscore)
228 dsp->ShowMessage("cannot allocate fscore space");
229 return 1;
232 #if defined HISTORY
233 n = sizeof_history;
234 history = malloc(n);
236 if (!history)
238 sprintf(buffer, "Cannot allocate %ld bytes for history table",
239 (long)sizeof_history);
240 dsp->ShowMessage(buffer);
241 use_history = false;
243 #endif
245 #if defined CACHE
246 n = sizeof(struct etable) * (size_t)ETABLE;
248 for (i = 0; i < 2; i++)
250 etab[i] = use_etable ? malloc(n) : 0;
252 if (!etab[i])
254 sprintf(buffer, "Cannot allocate %ld bytes for cache table %ld",
255 (long)n, (long)i);
256 dsp->ShowMessage(buffer);
257 use_etable = false;
260 #endif
262 #if ttblsz
264 if (rehash < 0)
265 rehash = MAXrehash;
267 n = sizeof(struct hashentry)*(ttblsize + rehash);
269 while (doit && ttblsize > MINTTABLE)
271 ttable[0] = malloc(n); /* FIXME: cast to the correct type. */
272 ttable[1] = ttable[0] ? malloc(n) : NULL;
274 if (!ttable[0] || !ttable[1])
276 if (!ttable[0])
277 free(ttable[0]);
279 if (!ttable[1])
280 free(ttable[1]);
282 ttblsize = ttblsize >> 1;
283 n = sizeof(struct hashentry) * (ttblsize + rehash);
285 else
287 doit = false;
291 if (ttblsize <= MINTTABLE)
293 use_ttable = false;
296 if (use_ttable)
298 /* CHECKME: is the precedence here correct? */
299 /* ttbllimit = ttblsize << 1 - ttblsize >> 2; */
300 ttbllimit = (ttblsize << 1) - (ttblsize >> 2);
302 else
304 sprintf(buffer, "Cannot allocate %ld bytes for transposition table",
305 (long)(2 * n));
306 dsp->ShowMessage(buffer);
307 ttable[0] = ttable[1] = NULL;
309 #endif /* ttblsz */
311 #if !defined SAVE_DISTDATA
312 n = sizeof(distdata_array);
313 distdata = malloc(n);
315 if (!distdata)
317 dsp->ShowMessage("cannot allocate distdata space...");
318 use_distdata = false;
320 #endif
322 #if !defined SAVE_PTYPE_DISTDATA
323 n = sizeof(distdata_array);
325 for (i = 0; i < NO_PTYPE_PIECES; i++)
327 ptype_distdata[i] = use_ptype_distdata ? malloc(n) : 0;
329 if (!ptype_distdata[i])
331 sprintf(buffer,
332 "cannot allocate %ld bytes for ptype_distdata %d...",
333 (long)n, i);
334 use_ptype_distdata = false;
337 #endif
339 return 0;
343 #ifdef SAVE_PTYPE_DISTDATA
344 short
345 piece_distance(short side, short piece, short f, short t)
347 return ((f > NO_SQUARES)
348 ? (short)1
349 : (short)ptype_distance(ptype[side][piece], f, t));
351 #else
352 short
353 piece_distance(short side, short piece, short f, short t)
355 return ((f > NO_SQUARES)
356 ? (short)1
357 : (use_ptype_distdata
358 ? (short)(*ptype_distdata[ptype[side][piece]])[f][t]
359 : (short)ptype_distance(ptype[side][piece], f, t)));
361 #endif
365 * Determine the minimum number of moves for a piece from
366 * square "f" to square "t". If the piece cannot reach "t",
367 * the count is set to CANNOT_REACH.
370 #define csquare(sq) ((side == black) ? sq : (NO_SQUARES - 1 - sq))
371 #define crow(sq) row(csquare(sq))
372 #define ccol(sq) column(csquare(sq))
374 short
375 ptype_distance(short ptyp, short f, short t)
377 short side, piece;
378 short colf, colt, rowf, rowt, dcol, drow;
380 if (f == t)
381 return 0;
383 piece = piece_of_ptype[ptyp];
384 side = side_of_ptype[ptyp];
386 dcol = (colt = ccol(t)) - (colf = ccol(f));
387 drow = (rowt = crow(t)) - (rowf = crow(f));
389 switch (piece)
391 case pawn:
392 if ((dcol != 0) || (drow < 1))
393 return CANNOT_REACH;
394 else
395 return drow;
397 #ifndef MINISHOGI
398 case lance:
399 if ((dcol != 0) || (drow < 1))
400 return CANNOT_REACH;
401 else
402 return 1;
404 case knight:
405 if (odd(drow) || (odd(drow / 2) != odd(dcol)))
406 return CANNOT_REACH;
407 else if ((drow == 0) || ((drow / 2) < abs(dcol)))
408 return CANNOT_REACH;
409 else
410 return (drow / 2);
411 #endif
413 case silver:
414 if (drow > 0)
416 if (odd(drow) == odd(dcol))
418 return max(abs(drow), abs(dcol));
420 else
422 if (abs(dcol) <= drow)
423 return drow;
424 else
425 return (max(abs(drow), abs(dcol)) + 1);
428 else
430 if (odd(drow) == odd(dcol))
431 return (max(abs(drow), abs(dcol)));
432 else
433 return (max(abs(drow) + 1, abs(dcol)) + 1);
436 case gold:
437 case ppawn:
438 #ifndef MINISHOGI
439 case pknight:
440 case plance:
441 #endif
442 case psilver:
443 if (abs(dcol) == 0)
444 return (abs(drow));
445 else if (drow >= 0)
446 return max(drow, abs(dcol));
447 else
448 return (abs(dcol) - drow);
450 case bishop:
451 if (odd(dcol) != odd(drow))
452 return CANNOT_REACH;
453 else
454 return ((abs(dcol) == abs(drow)) ? 1 : 2);
456 case pbishop:
457 if (odd(dcol) != odd(drow))
459 if ((abs(dcol) <= 1) && (abs(drow) <= 1))
460 return 1;
461 else if (abs(abs(dcol) - abs(drow)) == 1)
462 return 2;
463 else
464 return 3;
466 else
468 return ((abs(dcol) == abs(drow)) ? 1 : 2);
471 case rook:
472 if ((dcol == 0) || (drow == 0))
473 return 1;
474 else
475 return 2;
477 case prook:
478 if ((dcol == 0) || (drow == 0))
479 return 1;
480 else if ((abs(dcol) == 1) && (abs(drow) == 1))
481 return 1;
482 else
483 return 2;
485 case king:
486 return max(abs(drow), abs(dcol));
488 default:
489 /* should never occur */
490 return (CANNOT_REACH);