Curses: fix inverted column numbers display for minishogi.
[gnushogi.git] / gnushogi / init-common.c
blob061c7f9e30e3815ceb52ef89157e3caee9f43a16
1 /*
2 * FILE: init-common.c
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
24 * for more details.
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 * ----------------------------------------------------------------------
32 #include "gnushogi.h"
33 #include "pattern.h"
35 unsigned int ttbllimit;
38 * ptype is used to separate black and white pawns, like this; ptyp =
39 * ptype[side][piece] piece can be used directly in nextpos/nextdir when
40 * generating moves for pieces that are not white pawns.
43 const small_short ptype[2][NO_PIECES] =
46 ptype_no_piece, ptype_pawn,
47 #ifndef MINISHOGI
48 ptype_lance, ptype_knight,
49 #endif
50 ptype_silver, ptype_gold, ptype_bishop, ptype_rook,
51 ptype_gold,
52 #ifndef MINISHOGI
53 ptype_gold, ptype_gold,
54 #endif
55 ptype_gold,
56 ptype_pbishop, ptype_prook, ptype_king
59 ptype_no_piece, ptype_wpawn,
60 #ifndef MINISHOGI
61 ptype_wlance, ptype_wknight,
62 #endif
63 ptype_wsilver, ptype_wgold, ptype_bishop, ptype_rook,
64 ptype_wgold,
65 #ifndef MINISHOGI
66 ptype_wgold, ptype_wgold,
67 #endif
68 ptype_wgold,
69 ptype_pbishop, ptype_prook, ptype_king
73 const small_short promoted[NO_PIECES] =
75 no_piece, ppawn,
76 #ifndef MINISHOGI
77 plance, pknight,
78 #endif
79 psilver, gold, pbishop, prook,
80 ppawn,
81 #ifndef MINISHOGI
82 plance, pknight,
83 #endif
84 psilver, pbishop, prook, king
87 const small_short unpromoted[NO_PIECES] =
89 no_piece, pawn,
90 #ifndef MINISHOGI
91 lance, knight,
92 #endif
93 silver, gold, bishop, rook,
94 pawn,
95 #ifndef MINISHOGI
96 lance, knight,
97 #endif
98 silver, bishop, rook, king
102 /* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
104 #ifndef WIN32
105 #define max(a, b) (((a) < (b))?(b):(a))
106 #endif
107 #define odd(a) ((a) & 1)
109 const small_short piece_of_ptype[NO_PTYPE_PIECES] =
111 pawn,
112 #ifndef MINISHOGI
113 lance, knight,
114 #endif
115 silver, gold, bishop, rook, pbishop, prook, king,
116 pawn,
117 #ifndef MINISHOGI
118 lance, knight,
119 #endif
120 silver, gold
124 /* FIXME: all bishops and rooks are black ? */
125 const small_short side_of_ptype[NO_PTYPE_PIECES] =
127 black,
128 #ifndef MINISHOGI
129 black, black,
130 #endif
131 black, black, black, black, black, black, black,
132 white,
133 #ifndef MINISHOGI
134 white, white,
135 #endif
136 white, white
141 Initialize_data(void)
143 size_t n;
144 int i;
145 char buffer[60];
146 int doit = true;
149 small_short x = -1;
151 if (x >= 0)
153 ShowMessage("datatype 'small_short' is unsigned; "
154 "check gnushogi.h\n");
155 return 1;
159 n = sizeof(struct leaf) * (size_t)TREE;
160 Tree = malloc(n);
162 if (!Tree)
164 sprintf(buffer, "Cannot allocate %ld bytes for search tree",
165 (long)n);
166 ShowMessage(buffer);
167 return 1;
170 n = sizeof(hashcode_array);
171 hashcode = malloc(n);
173 if (!hashcode)
175 sprintf(buffer, "Cannot allocate %ld bytes for hashcode", (long)n);
176 ShowMessage(buffer);
177 return 1;
180 n = sizeof(drop_hashcode_array);
181 drop_hashcode = malloc(n);
183 if (!drop_hashcode)
185 sprintf(buffer,
186 "Cannot allocate %ld bytes for drop_hashcode",
187 (long)n);
188 ShowMessage(buffer);
189 return 1;
192 n = sizeof(struct GameRec) * (size_t)(MAXMOVES + MAXDEPTH);
193 GameList = malloc(n);
195 if (!GameList)
197 sprintf(buffer,
198 "Cannot allocate %ld bytes for game record",
199 (long)n);
200 ShowMessage(buffer);
201 return 1;
204 #if !defined SAVE_NEXTPOS
205 n = sizeof(next_array);
207 for (i = 0; i < NO_PTYPE_PIECES; i++)
209 nextdir[i] = use_nextpos ? malloc(n) : NULL;
211 if (!nextdir[i])
213 if (use_nextpos)
215 sprintf(buffer, "cannot allocate %ld space for nextdir %d",
216 (long)(n), i);
217 ShowMessage(buffer);
220 nextdir[i] = NULL;
221 use_nextpos = false;
224 nextpos[i] = use_nextpos ? malloc(n) : NULL;
226 if (!nextpos[i])
228 if (use_nextpos)
230 sprintf(buffer, "cannot allocate %ld space for nextpos %d",
231 (long)(n), i);
232 ShowMessage(buffer);
235 use_nextpos = false;
239 if (!use_nextpos)
241 return 1;
243 #endif
245 n = sizeof(value_array);
246 value = malloc(n);
248 if (!value)
250 ShowMessage("cannot allocate value space");
251 return 1;
254 n = sizeof(fscore_array);
255 fscore = malloc(n);
257 if (!fscore)
259 ShowMessage("cannot allocate fscore space");
260 return 1;
263 #if defined HISTORY
264 n = sizeof_history;
265 history = malloc(n);
267 if (!history)
269 sprintf(buffer, "Cannot allocate %ld bytes for history table",
270 (long)sizeof_history);
271 ShowMessage(buffer);
272 use_history = false;
274 #endif
276 #if defined CACHE
277 n = sizeof(struct etable) * (size_t)ETABLE;
279 for (i = 0; i < 2; i++)
281 etab[i] = use_etable ? malloc(n) : 0;
283 if (!etab[i])
285 sprintf(buffer, "Cannot allocate %ld bytes for cache table %ld",
286 (long)n, (long)i);
287 ShowMessage(buffer);
288 use_etable = false;
291 #endif
293 #if ttblsz
295 if (rehash < 0)
296 rehash = MAXrehash;
298 n = sizeof(struct hashentry)*(ttblsize + rehash);
300 while (doit && ttblsize > MINTTABLE)
302 ttable[0] = malloc(n); /* FIXME: cast to the correct type. */
303 ttable[1] = ttable[0] ? malloc(n) : NULL;
305 if (!ttable[0] || !ttable[1])
307 if (!ttable[0])
308 free(ttable[0]);
310 if (!ttable[1])
311 free(ttable[1]);
313 ttblsize = ttblsize >> 1;
314 n = sizeof(struct hashentry) * (ttblsize + rehash);
316 else
318 doit = false;
322 if (ttblsize <= MINTTABLE)
324 use_ttable = false;
327 if (use_ttable)
329 /* CHECKME: is the precedence here correct? */
330 /* ttbllimit = ttblsize << 1 - ttblsize >> 2; */
331 ttbllimit = (ttblsize << 1) - (ttblsize >> 2);
333 else
335 sprintf(buffer, "Cannot allocate %ld bytes for transposition table",
336 (long)(2 * n));
337 ShowMessage(buffer);
338 ttable[0] = ttable[1] = NULL;
340 #endif /* ttblsz */
342 #if !defined SAVE_DISTDATA
343 n = sizeof(distdata_array);
344 distdata = malloc(n);
346 if (!distdata)
348 ShowMessage("cannot allocate distdata space...");
349 use_distdata = false;
351 #endif
353 #if !defined SAVE_PTYPE_DISTDATA
354 n = sizeof(distdata_array);
356 for (i = 0; i < NO_PTYPE_PIECES; i++)
358 ptype_distdata[i] = use_ptype_distdata ? malloc(n) : 0;
360 if (!ptype_distdata[i])
362 sprintf(buffer,
363 "cannot allocate %ld bytes for ptype_distdata %d...",
364 (long)n, i);
365 use_ptype_distdata = false;
368 #endif
370 return 0;
374 #ifdef SAVE_PTYPE_DISTDATA
375 short
376 piece_distance(short side, short piece, short f, short t)
378 return ((f > NO_SQUARES)
379 ? (short)1
380 : (short)ptype_distance(ptype[side][piece], f, t));
382 #else
383 short
384 piece_distance(short side, short piece, short f, short t)
386 return ((f > NO_SQUARES)
387 ? (short)1
388 : (use_ptype_distdata
389 ? (short)(*ptype_distdata[ptype[side][piece]])[f][t]
390 : (short)ptype_distance(ptype[side][piece], f, t)));
392 #endif
396 * Determine the minimum number of moves for a piece from
397 * square "f" to square "t". If the piece cannot reach "t",
398 * the count is set to CANNOT_REACH.
401 #define csquare(sq) ((side == black) ? sq : (NO_SQUARES - 1 - sq))
402 #define crow(sq) row(csquare(sq))
403 #define ccol(sq) column(csquare(sq))
405 short
406 ptype_distance(short ptyp, short f, short t)
408 short side, piece;
409 short colf, colt, rowf, rowt, dcol, drow;
411 if (f == t)
412 return 0;
414 piece = piece_of_ptype[ptyp];
415 side = side_of_ptype[ptyp];
417 dcol = (colt = ccol(t)) - (colf = ccol(f));
418 drow = (rowt = crow(t)) - (rowf = crow(f));
420 switch (piece)
422 case pawn:
423 if ((dcol != 0) || (drow < 1))
424 return CANNOT_REACH;
425 else
426 return drow;
428 #ifndef MINISHOGI
429 case lance:
430 if ((dcol != 0) || (drow < 1))
431 return CANNOT_REACH;
432 else
433 return 1;
435 case knight:
436 if (odd(drow) || (odd(drow / 2) != odd(dcol)))
437 return CANNOT_REACH;
438 else if ((drow == 0) || ((drow / 2) < abs(dcol)))
439 return CANNOT_REACH;
440 else
441 return (drow / 2);
442 #endif
444 case silver:
445 if (drow > 0)
447 if (odd(drow) == odd(dcol))
449 return max(abs(drow), abs(dcol));
451 else
453 if (abs(dcol) <= drow)
454 return drow;
455 else
456 return (max(abs(drow), abs(dcol)) + 1);
459 else
461 if (odd(drow) == odd(dcol))
462 return (max(abs(drow), abs(dcol)));
463 else
464 return (max(abs(drow) + 1, abs(dcol)) + 1);
467 case gold:
468 case ppawn:
469 #ifndef MINISHOGI
470 case pknight:
471 case plance:
472 #endif
473 case psilver:
474 if (abs(dcol) == 0)
475 return (abs(drow));
476 else if (drow >= 0)
477 return max(drow, abs(dcol));
478 else
479 return (abs(dcol) - drow);
481 case bishop:
482 if (odd(dcol) != odd(drow))
483 return CANNOT_REACH;
484 else
485 return ((abs(dcol) == abs(drow)) ? 1 : 2);
487 case pbishop:
488 if (odd(dcol) != odd(drow))
490 if ((abs(dcol) <= 1) && (abs(drow) <= 1))
491 return 1;
492 else if (abs(abs(dcol) - abs(drow)) == 1)
493 return 2;
494 else
495 return 3;
497 else
499 return ((abs(dcol) == abs(drow)) ? 1 : 2);
502 case rook:
503 if ((dcol == 0) || (drow == 0))
504 return 1;
505 else
506 return 2;
508 case prook:
509 if ((dcol == 0) || (drow == 0))
510 return 1;
511 else if ((abs(dcol) == 1) && (abs(drow) == 1))
512 return 1;
513 else
514 return 2;
516 case king:
517 return max(abs(drow), abs(dcol));
519 default:
520 /* should never occur */
521 return (CANNOT_REACH);