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
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 * ----------------------------------------------------------------------
31 #if defined HAVE_GETTIMEOFDAY
39 /****************************************
40 * A variety of global flags.
41 ****************************************/
44 * If hard_time_limit is nonzero, exceeding the time limit means
48 short hard_time_limit = 1;
49 short barebones = 0; /* Suppress printing of statistics
50 * (mainly for xshogi). */
52 short nolist = 0; /* List the game after exit. */
54 short nolist = 1; /* Don't list the game after exit. */
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
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
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
110 #include "gnushogi.lng"
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))
132 ptype_distance(short ptyp, short f, short t)
135 short colf, colt, rowf, rowt, dcol, drow;
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));
149 if ((dcol != 0) || (drow < 1))
155 if ((dcol != 0) || (drow < 1))
161 if (odd(drow) || (odd(drow / 2) != odd(dcol)))
163 else if ((drow == 0) || ((drow / 2) < abs(dcol)))
171 if (odd(drow) == odd(dcol))
173 return max(abs(drow), abs(dcol));
177 if (abs(dcol) <= drow)
180 return (max(abs(drow), abs(dcol)) + 1);
185 if (odd(drow) == odd(dcol))
186 return (max(abs(drow), abs(dcol)));
188 return (max(abs(drow) + 1, abs(dcol)) + 1);
199 return max(drow, abs(dcol));
201 return (abs(dcol) - drow);
204 if (odd(dcol) != odd(drow))
207 return ((abs(dcol) == abs(drow)) ? 1 : 2);
210 if (odd(dcol) != odd(drow))
212 if ((abs(dcol) <= 1) && (abs(drow) <= 1))
214 else if (abs(abs(dcol) - abs(drow)) == 1)
221 return ((abs(dcol) == abs(drow)) ? 1 : 2);
225 if ((dcol == 0) || (drow == 0))
231 if ((dcol == 0) || (drow == 0))
233 else if ((abs(dcol) == 1) && (abs(drow) == 1))
239 return max(abs(drow), abs(dcol));
242 /* should never occur */
243 return (CANNOT_REACH);
250 distance(short a, short b)
252 return (short)computed_distance(a, b);
256 distance(short a, short b)
259 ? (short)(*distdata)[(int)a][(int)b]
260 : (short)computed_distance(a, b));
265 #ifdef SAVE_PTYPE_DISTDATA
267 piece_distance(short side, short piece, short f, short t)
269 return ((f > NO_SQUARES)
271 : (short)ptype_distance(ptype[side][piece], f, t));
275 piece_distance(short side, short piece, short f, short t)
277 return ((f > NO_SQUARES)
279 : (use_ptype_distdata
280 ? (short)(*ptype_distdata[ptype[side][piece]])[f][t]
281 : (short)ptype_distance(ptype[side][piece], f, t)));
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);
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);
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
317 * ppos = nextpos[ptype][from-square];
318 * pdir = nextdir[ptype][from-square];
325 * if(color[u] != neutral)
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
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
451 next_direction(short ptyp, short *d, short sq)
453 short delta, to, sfrom = inunmap[sq];
461 delta = direc[ptyp][*d];
465 to = nunmap[sfrom + delta];
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]];
481 return next_direction(ptyp, d, sq);
487 return next_direction(ptyp, d, sq);
493 first_direction(short ptyp, short *d, short sq)
496 return next_direction(ptyp, d, sq);
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.
508 Initialize_moves(void)
510 short ptyp, po, p0, d, di, s, delta;
511 unsigned char *ppos, *pdir;
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];
551 for (s = 0; s < max_steps[ptyp]; s++)
556 * break if (off board) or (promoted rooks
557 * wishes to move two steps diagonal) or
558 * (promoted bishops wishes to move two steps
561 if ((nunmap[p0] < (small_short)0)
562 || ((ptyp == ptype_prook)
565 || ((ptyp == ptype_pbishop)
567 && !diagonal(delta)))
570 dest[d][s] = nunmap[p0];
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.
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];
598 * update nextpos/nextdir
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];
612 pdir[p0] = (unsigned char)dest[sorted[d + 1]][0];
615 * else is already initialized
629 * Reset the board and other variables to start a new game.
635 short l, c, p, max_opening_sequence;
636 #ifdef HAVE_GETTIMEOFDAY
639 compptr = oppptr = 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
645 flag.material = flag.coords = flag.hash = flag.easy
646 = flag.beep = flag.rcptr
648 flag.stars = flag.shade = flag.back = flag.musttimeout = false;
653 GenCnt = NodeCnt = et0 = dither = XCmore = 0;
662 MaxSearchDepth = MAXDEPTH - 1;
667 CptrFlag[0] = TesujiFlag[0] = false;
670 GameType[0] = GameType[1] = UNKNOWN;
671 Pscore[0] = Tscore[0] = (SCORE_LIMIT + 3000);
672 opponent = player = black;
675 for (l = 0; l < TREE; l++)
676 Tree[l].f = Tree[l].t = 0;
678 gsrand((unsigned int) 1);
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);
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);
739 for (l = 0; l < NO_SQUARES; l++)
741 board[l] = Stboard[l];
742 color[l] = Stcolor[l];
750 #ifdef HAVE_GETTIMEOFDAY
751 gettimeofday(&tv, NULL);
752 time0 = tv.tv_sec*100 + tv.tv_usec/10000;
754 time0 = time((long *) 0);
757 /* resetting reference time */
758 ElapsedTime(COMPUTE_AND_INIT_MODE);
759 flag.regularstart = true;
769 else if (MaxResponseTime == 0)
772 UpdateDisplay(0, 0, 1, 0);
774 GetOpeningPatterns(&max_opening_sequence);
787 hashbd = hashkey = 0;
794 Initialize_data(void)
806 ShowMessage("datatype 'small_short' is unsigned; "
807 "check gnushogi.h\n");
812 n = sizeof(struct leaf) * (size_t)TREE;
817 sprintf(buffer, "Cannot allocate %ld bytes for search tree",
823 n = sizeof(hashcode_array);
824 hashcode = malloc(n);
828 sprintf(buffer, "Cannot allocate %ld bytes for hashcode", (long)n);
833 n = sizeof(drop_hashcode_array);
834 drop_hashcode = malloc(n);
839 "Cannot allocate %ld bytes for drop_hashcode",
845 n = sizeof(struct GameRec) * (size_t)(MAXMOVES + MAXDEPTH);
846 GameList = malloc(n);
851 "Cannot allocate %ld bytes for game record",
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;
868 sprintf(buffer, "cannot allocate %ld space for nextdir %d",
877 nextpos[i] = use_nextpos ? malloc(n) : NULL;
883 sprintf(buffer, "cannot allocate %ld space for nextpos %d",
898 n = sizeof(value_array);
903 ShowMessage("cannot allocate value space");
907 n = sizeof(fscore_array);
912 ShowMessage("cannot allocate fscore space");
922 sprintf(buffer, "Cannot allocate %ld bytes for history table",
923 (long)sizeof_history);
930 n = sizeof(struct etable) * (size_t)ETABLE;
932 for (i = 0; i < 2; i++)
934 etab[i] = use_etable ? malloc(n) : 0;
938 sprintf(buffer, "Cannot allocate %ld bytes for cache table %ld",
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])
966 ttblsize = ttblsize >> 1;
967 n = sizeof(struct hashentry) * (ttblsize + rehash);
975 if (ttblsize <= MINTTABLE)
982 /* CHECKME: is the precedence here correct? */
983 /* ttbllimit = ttblsize << 1 - ttblsize >> 2; */
984 ttbllimit = (ttblsize << 1) - (ttblsize >> 2);
988 sprintf(buffer, "Cannot allocate %ld bytes for transposition table",
991 ttable[0] = ttable[1] = NULL;
995 #if !defined SAVE_DISTDATA
996 n = sizeof(distdata_array);
997 distdata = malloc(n);
1001 ShowMessage("cannot allocate distdata space...");
1002 use_distdata = false;
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])
1016 "cannot allocate %ld bytes for ptype_distdata %d...",
1018 use_ptype_distdata = false;
1027 #if defined EXTLANGFILE
1032 InitConst(char *lang)
1040 constfile = fopen(LANGFILE, "r");
1044 ShowMessage("NO LANGFILE");
1048 while (fgets(s, sizeof(s), constfile))
1055 for (q = &s[len]; q > &s[8]; q--)
1061 ShowMessage("{ error in cinstfile");
1067 if ((s[3] != ':') || (s[7] != ':') || (s[8] != '{'))
1069 sprintf(buffer, "Langfile format error %s", s);
1070 ShowMessage(buffer);
1082 if (strcmp(&s[4], lang))
1087 if ((entry < 0) || (entry >= CPSIZE))
1089 ShowMessage("Langfile number error");
1093 for (q = p = &s[9]; *p; p++)
1099 else if (*(p + 1) == 'n')
1108 if ((entry < 0) || (entry > 255))
1110 sprintf(buffer, "Langfile error %d\n", entry);
1111 ShowMessage(buffer);
1115 CP[entry] = (char *)GLOBAL_ALLOC((unsigned) strlen(&s[9]) + 1);
1117 if (CP[entry] == NULL)
1120 sprintf(buffer, "CP MALLOC, entry %d", entry);
1125 strcpy(CP[entry], &s[9]);
1134 InitConst(char *lang)
1142 constfile = fopen(LANGFILE, "r");
1146 ShowMessage("NO LANGFILE");
1150 while (fgets(s, sizeof(s), constfile))
1157 if ((len > 3) && (s[3] == ':') || (len > 7) && (s[7] == ':'))
1159 ShowMessage("old Langfile error");
1165 ShowMessage("length error in Langfile");
1169 for (q = &s[len]; q > &s[15]; q--)
1177 ShowMessage("\" error in Langfile");
1183 if ((s[6] != ':') || (s[10] != ':') || (s[15] != '"'))
1185 sprintf(buffer, "Langfile format error %s", s);
1186 ShowMessage(buffer);
1190 s[6] = s[10] = '\0';
1198 if (strcmp(&s[7], lang))
1201 entry = atoi(&s[3]);
1203 if ((entry < 0) || (entry >= CPSIZE))
1205 ShowMessage("Langfile number error");
1209 for (q = p = &s[16]; *p; p++)
1215 else if (*(p + 1) == 'n')
1224 if ((entry < 0) || (entry > 255))
1226 sprintf(buffer, "Langfile error %d\n", entry);
1227 ShowMessage(buffer);
1231 CP[entry] = (char *)GLOBAL_ALLOC((unsigned)strlen(&s[16]) + 1);
1233 if (CP[entry] == NULL)
1236 sprintf(buffer, "CP MALLOC, entry %d", entry);
1241 strcpy(CP[entry], &s[16]);
1255 gsrand(starttime = ((unsigned int)time((long *)0))); /* init urand */
1262 if (Initialize_data() != 0)
1265 #if defined EXTLANGFILE
1269 strcpy(ColorStr[0], CP[118]);
1270 strcpy(ColorStr[1], CP[119]);
1273 MaxResponseTime = 0;
1277 signal(SIGUSR1, TerminateSearch);
1298 #if !defined SAVE_NEXTPOS
1316 hashfile = fopen(HASHFILE, RWA_ACC);
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 */
1342 #endif /* HASHFILE */