📄 book.c
字号:
/*
* book.c - C source for GNU CHESS for Windows
*
* Copyright (c) 1988,1989,1990 John Stanback
* Copyright (c) 1992 Free Software Foundation
* Modified by Conor McCarthy for the Windows environment
*
* This file is part of GNU CHESS.
*
* GNU Chess is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2, or (at your option) any later
* version.
*
* GNU Chess is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* GNU Chess; see the file COPYING. If not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "gnuchess.h"
#include "ttable.h" /* uses hashbd, hashkey */
#include "ataks.h"
#define ungetc(c,hbook) bkptr--;
#define CHUNK 16384
#ifdef GENIT
FILE *GEN;
int GENline = 0;
int GENmove = 0;
CHAR gs0[12], gs1[12], gs2[12], gs3[12], GENITs[12];
#endif
#include <io.h>
#include <fcntl.h>
unsigned long booksize = BOOKSIZE;
unsigned long int BKTBLSIZE;
unsigned long BOOKMASK;
unsigned long bookcount = 0;
unsigned long bookline = 0;
unsigned bookpocket = BOOKPOCKET;
long fileoffset;
char *bkdata,*bkptr,*bkend;
int bkoffset=0;
char *gfdptr;
SHORT end;
UTSHORT bookmaxply = BOOKMAXPLY;
extern HBRUSH hDlgBkgrnd;
#ifdef ECO
#include <sys/types.h>
#include <sys/stat.h>
#endif
CHAR *binbookfile = BINBOOK;
int GotBook = false;
unsigned long bhashbd, bhashkey;
void CompileBook(HWND, HWND, HWND);
inline
int readc(int hbook)
{
if (bkptr-bkdata == CHUNK)
{
*bkdata=*(bkptr-1); /* allow ungetc() */
bkptr=bkdata+1;
bkend=bkptr+read(hbook,bkptr,CHUNK-1);
}
if (bkptr==bkend)return EOF;
fileoffset++;
return (UINT)*(bkptr++);
}
#ifdef GENIT
GENITchk (gs)
CHAR *gs;
{
int gcnt, gpnt;
struct leaf *node = NULL;
gcnt = 0;
gpnt = TrPnt[2];
while (gpnt < TrPnt[3])
{
node = &Tree[gpnt++];
algbr (node->f, node->t, (SHORT) node->flags);
if (strcmp (gs, mvstr[0]) == 0 || strcmp (gs, mvstr[1]) == 0 ||
strcmp (gs, mvstr[2]) == 0 || strcmp (gs, mvstr[3]) == 0
|| strcmp (gs, mvstr[4]) == 0)
{
gcnt++;
}
}
return gcnt;
}
#endif
#ifndef QUIETBOOKGEN
void
bkdisplay (s, cnt, moveno)
CHAR *s;
int cnt;
int moveno;
{
static SHORT pnt;
#ifndef SEMIQUIETBOOKGEN
struct leaf *node;
int r, c, l;
#endif
pnt = TrPnt[2];
printf ("matches = %d\n", cnt);
printf ("inout move is :%s:move number %d side %s\n", s, moveno / 2 + 1, !(moveno & 1) ? "white" : "black");
#ifndef SEMIQUIETBOOKGEN
printf ("legal moves are \n");
while (pnt < TrPnt[3])
{
node = &Tree[pnt++];
algbr (node->f, node->t, (SHORT) node->flags);
printf ("%s %s %s %s %s\n", mvstr[0], mvstr[1], mvstr[2], mvstr[3], mvstr[4]);
}
printf ("\n current board is\n");
for (r = 7; r >= 0; r--)
{
for (c = 0; c <= 7; c++)
{
l = locn (r, c);
if (color[l] == neutral)
printf (" -");
else if (color[l] == white)
printf (" %c", qxx[board[l]]);
else
printf (" %c", pxx[board[l]]);
}
printf ("\n");
}
printf ("\n\n");
#endif
}
#endif
int
BVerifyMove (CHAR * s, UTSHORT * mv, int moveno)
/*
* Compare the string 's' to the list of legal moves available for the
* opponent. If a match is found, make the move on the board.
*/
{
static SHORT pnt, tempb, tempc, tempsf, tempst, cnt;
static struct leaf xnode;
struct leaf *node;
*mv = 0;
cnt = 0;
VMoveList (opponent, 2);
pnt = TrPnt[2];
while (pnt < TrPnt[3])
{
node = &Tree[pnt++];
algbr (node->f, node->t, (SHORT) node->flags);
if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0 || strcmp (s, mvstr[4]) == 0)
{
cnt++;
xnode = *node;
}
}
if (cnt == 1)
{
#ifdef GENIT
algbr (xnode.f, xnode.t, (SHORT) xnode.flags);
strcpy (gs0, mvstr[0]);
strcpy (gs1, mvstr[1]);
strcpy (gs2, mvstr[2]);
strcpy (gs3, mvstr[3]);
if (GENITchk (gs1) == 1)
strcpy (GENITs, gs1);
else if (GENITchk (gs2) == 1)
strcpy (GENITs, gs2);
else if (GENITchk (gs2) == 1)
strcpy (GENITs, gs1);
else
strcpy (GENITs, gs0);
if (strcmp ("e8g8", GENITs) == 0 || strcmp ("e1g1", GENITs) == 0)
strcpy (GENITs, "o-o");
else if (strcmp ("e8c8", GENITs) == 0 || strcmp ("e1c1", GENITs) == 0)
strcpy (GENITs, "o-o-o");
#endif
MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
if (SqAtakd (PieceList[opponent][0], computer))
{
UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
/* Illegal move in check */
#ifndef QUIETBOOKGEN
printf (CP[27]);
printf ("\n");
bkdisplay (s, cnt, moveno);
#endif
return (false);
}
else
{
*mv = (xnode.f << 8) | xnode.t;
algbr (xnode.f, xnode.t, false);
if (board[xnode.t] == pawn)
{
if (xnode.t - xnode.f == 16)
epsquare = xnode.f + 8;
else if (xnode.f - xnode.t == 16)
epsquare = xnode.f - 8;
}
else
epsquare = -1;
return (true);
}
}
/* Illegal move */
#ifndef QUIETBOOKGEN
printf (CP[25], s);
bkdisplay (s, cnt, moveno);
#endif
return (false);
}
void
RESET (void)
/*
* Reset the board and other variables to start a new game.
*/
{
SHORT l;
flag.illegal = flag.mate = flag.quit = flag.bothsides = flag.onemove = flag.force = false;
flag.back = flag.musttimeout = false;
GenCnt = epsquare = 0;
GameCnt = 0;
Developed[white] = Developed[black] = false;
castld[white] = castld[black] = false;
PawnThreat[0] = CptrFlag[0] = false;
for (l = 0; l < 64; l++)
{
board[l] = Stboard[l];
color[l] = Stcolor[l];
Mvboard[l] = 0;
}
InitializeStats ();
}
int
gnc (int hbook)
{
int c;
c = readc (hbook);
if (c == '(')
{
#ifdef GENIT
fputc (GEN, c);
#endif
do
{
c = readc (hbook);
#ifdef GENIT
fputc (GEN, c);
#endif
if (c == ')')
{
c = readc (hbook);
break;
}
if (c == EOF)
break;
}
while (true);
}
else if (c == '{')
{
#ifdef GENIT
fputc (GEN, c);
#endif
do
{
c = readc (hbook);
#ifdef GENIT
fputc (GEN, c);
#endif
if (c == '}')
{
c = readc (hbook);
break;
}
if (c == EOF)
break;
}
while (true);
}
return c;
}
int
Vparse (int hbook, UTSHORT * mv, SHORT side, CHAR * opening, int moveno)
{
register int c, i;
CHAR s[1024];
CHAR *p;
while (true)
{
while ((c = gnc (hbook)) == ' ' || c == '\n');
if (c == '\r')
continue;
i = 0;
if (c == '#' || c == '[' || c == '%')
{ /* comment */
#ifdef GENIT
pcurr =
#endif
p = opening;
do
{
*p++ = c;
c = gnc (hbook);
if (c == '\r')
continue;
/* goes to end of line */
if (c == '\n')
{
/* does the comment continue */
if (opening[0] == '[')
{
if ((c = readc (hbook)) == '[')
{
#ifdef GENIT
*p = '\0';
fprintf (GEN, "%s\n", pcurr);
pcurr = p;
#endif
continue;
}
else
ungetc (c, hbook);
}
*p = '\0';
#ifdef GENIT
GENline = 0;
fprintf (GEN, "%s\n", opening);
GENmove = 0;
#endif
return 0;
}
if (c == EOF)
return -1;
}
while (true);
}
/* is it a move number or analysis ( in [ ] or in { } ) */
/* number cannot start with a 0 because of 0-0 */
else if (!isalpha (c) && c != '0')
{
int nlxx = false;
int nonspace = false;
while (true)
{
c = gnc (hbook);
if (nlxx)
if (c == '#' || c == '[' || c == '%')
{
ungetc (c, hbook);
return 0;
}
if (c == '\r')
continue;
if (c == '\n')
{
nlxx = true;
continue;
}
else
nlxx = false;
if (c == EOF)
{
return -1;
}
/* stop at first nonspace a ... is space */
/* must be nonspace because of 0-0 */
if (nonspace)
{
if (c != '.' && c != ' ')
break;
}
if (c == '.')
{
nonspace = true;
}
/* stop if alpha must be move */
else if (isalpha (c))
break;
}
}
s[0] = (CHAR) c;
while ((c = gnc (hbook)) != '\n' && c != ' ' && c != '\t' && c != EOF)
{
if (isupper (c))
{
if (c != 'O')
{
ungetc (c, hbook);
c = ' ';
break;
}
}
if (c == '\r')
continue;
if (c == '?')
break;
if (c == '!')
continue;
if (c == '+')
continue;
if (c == '#')
continue;
if (c == '%')
continue;
if (c == '=')
{
c = gnc (hbook);
c = tolower (c);
}
if (c != 'x')
s[++i] = c;
}
s[++i] = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -