📄 book.c
字号:
if (c == EOF)
return (-1);
if (s[0] == '!' || s[0] == ';')
{
while (c != '\n' && c != EOF)
c = gnc (hbook);
if (c == EOF)
return -1;
else
return (0);
}
if ((strcmp (s, "o-o-o") == 0) || (strcmp (s, "OOO") == 0) || (strcmp (s, "O-O-O") == 0) || (strcmp (s, "0-0-0") == 0))
{
if (side == black)
strcpy (s, "e8c8");
else
strcpy (s, "e1c1");
}
else if ((strcmp ("o-o", s) == 0) || (strcmp (s, "OO") == 0) || (strcmp (s, "O-O") == 0) || (strcmp (s, "0-0") == 0))
{
if (side == black)
strcpy (s, "e8g8");
else
strcpy (s, "e1g1");
}
else if (strcmp (s, "draw") == 0)
continue;
else if (strcmp (s, "Draw") == 0)
continue;
else if (strcmp (s, "1-0") == 0)
continue;
else if (strcmp (s, "0-1") == 0)
continue;
else if (strcmp (s, "2-1/2") == 0)
continue;
if (isupper (s[i - 1]))
s[i - 1] = tolower (s[i - 1]);
bhashkey = hashkey;
bhashbd = hashbd;
i = BVerifyMove (s, mv, moveno);
if (c == '?')
{ /* Bad move, not for the program to play */
*mv |= BADMOVE; /* Flag it ! */
c = readc (hbook);
}
else if (c == '+' || c == '\r')
c = gnc (hbook);
if (!i)
{
/* flush to start of next */
while ((c = gnc (hbook)) != '[' && c != EOF && c != '#');
if (c == EOF)
return -1;
else
{
ungetc (c, hbook);
return i;
}
}
#ifdef GENIT
if (GENline++ > 15)
{
GENline = 1;
fprintf (GEN, "\n");
}
if ((GENmove / 2) * 2 == GENmove)
fprintf ("%d. ", (GENmove / 2) + 1);
if (c == '?')
fprintf (GEN, "%s? ", GENITs);
else
fprintf (GEN, "%s ", GENITs);
if (!(GENline & 1))
fprintf (GEN, " ");
GENmove++;
#endif
return (i);
}
}
/*===================================== GDX =======================================*/
struct gdxadmin
{
unsigned long bookcount;
unsigned long booksize;
unsigned long maxoffset;
}
ADMIN, B;
struct gdxdata
{
unsigned long hashbd;
utshort hashkey;
utshort bmove;
utshort hint;
utshort count;
}
DATA;
#ifdef LONG64
#define lts(x) (utshort)(((x>>48)&0xfffe)|side)
#else
#define lts(x) (utshort)(((x>>16)&0xfffe)|side)
#endif
unsigned long currentoffset;
int gfd=-1;
void
GetOpenings (void)
/*
* The binary hash file is opened with readonly access during the game.
*/
{
/* open book as reader */
gfd = open (binbookfile, O_RDONLY | O_BINARY);
if (gfd >= 0)
{
read (gfd, &ADMIN, sizeof (struct gdxadmin));
B.bookcount = ADMIN.bookcount;
B.booksize = ADMIN.booksize;
B.maxoffset = ADMIN.maxoffset;
if (B.booksize && !(B.maxoffset == ((unsigned long) (B.booksize - 1) * sizeof (struct gdxdata) + sizeof (struct gdxadmin))))
{
sprintf (msg,"Bad format %s", binbookfile);
ShowMessage(msg);
close(gfd);
goto nobook;
}
}
else
{
nobook:
B.bookcount = 0;
B.booksize = booksize;
}
Book = flag.usebook ? BOOKFAIL : 0;
if (!B.bookcount)
{
EnableMenuItem ( GetMenu(hWnd), IDM_BOOK, MF_GRAYED);
Book = 0;
}
}
BOOL PASCAL CompileBookDlgProc (HWND hDlg, UINT Message,
WPARAM wParam, LPARAM lParam)
{
switch ( Message )
{
case WM_INITDIALOG:
return true;
#ifdef WIN32
case WM_CTLCOLORSTATIC:
SetBkMode((HDC)wParam,TRANSPARENT);
case WM_CTLCOLORDLG:
return hDlgBkgrnd;
#else
case WM_CTLCOLOR:
switch(HIWORD(lParam))
{
case CTLCOLOR_STATIC:
SetBkMode((HDC)wParam,TRANSPARENT);
case CTLCOLOR_DLG:
return hDlgBkgrnd;
}
return 0;
#endif
case WM_COMMAND:
if (LOWORD(wParam)==IDOK)
{
CompileBook(GetDlgItem(hDlg,IDC_OFFSET),GetDlgItem(hDlg,IDC_REC),
GetDlgItem(hDlg,IDC_GAMES));
EndDialog(hDlg,true);
}
else if (LOWORD(wParam)==IDCANCEL)
{
end=1;
EndDialog(hDlg,false);
}
return true;
}
return false;
}
void
CompileBook(HWND hOffset, HWND hRec, HWND hGames)
/*
* If a text file of opening chess plays (the Opening Book) is available:
* Read in the Opening Book file and parse the algebraic notation for a move
* into an unsigned integer format indicating the from and to square. Create
* or update a binary hash file with the recomended move/moves for each
* position.
* The binary hash file is opened with readonly access during the game.
*/
{
register SHORT i;
CHAR opening[1024];
CHAR msg[1024];
int mustwrite = false;
UTSHORT xside, doit, side;
SHORT c;
UTSHORT mv;
UTSHORT ix;
unsigned long games = 0;
SHORT OrigCompCol=computer; /*save current computer color*/
int hbook;
long oldoffset=0;
EnableWindow(hOffset,true);
EnableWindow(hRec,true);
EnableWindow(hGames,true);
fileoffset=0;
hbook = open ("gnuchess.bk", O_RDONLY | O_BINARY);
#ifdef GENIT
if ((GEN = fopen ("GEN", "w")) == NULL)
{
printf ("GEN FAIL\n");
exit (1);
}
#endif
if (hbook >= 0)
{
/* yes add to book */
/* open book as writer */
if (gfd>=0) close(gfd);
gfdptr = malloc(booksize*sizeof(struct gdxdata)+sizeof(struct gdxadmin));
bkptr = bkdata = (char*)malloc(CHUNK);
if (!bkdata || !gfdptr)
{
ShowMessage(CP[70]);
if (gfdptr) free(gfdptr);
close(hbook);
GetOpenings();
return;
}
gfd = open (binbookfile, O_RDONLY | O_BINARY);
bkend = bkdata+read(hbook,bkdata,CHUNK);
if (gfd >= 0)
{
if (sizeof (struct gdxadmin) == read (gfd, &ADMIN, sizeof (struct gdxadmin)))
{
B.bookcount = ADMIN.bookcount;
B.booksize = ADMIN.booksize;
B.maxoffset = ADMIN.maxoffset;
if (B.booksize && !(B.maxoffset == ((unsigned long) (B.booksize - 1) * sizeof (struct gdxdata) + sizeof (struct gdxadmin))))
{
nogood:
sprintf (msg,"Bad format %s", binbookfile);
ShowMessage(msg);
free(gfdptr); free(bkdata);
B.bookcount=Book=0;
close(gfd);
close(hbook);
EnableMenuItem (GetMenu(hWnd), IDM_BOOK, MF_GRAYED);
return;
}
}
else goto nogood;
close (gfd);
gfd = open (binbookfile, O_RDWR | O_BINARY);
read(gfd,gfdptr,B.maxoffset+sizeof(struct gdxdata));
lseek(gfd,0,SEEK_SET);
}
else
{
#ifdef Think_C
gfd = open (binbookfile, O_RDWR | O_CREAT | O_BINARY);
#else
gfd = open (binbookfile, O_RDWR | O_CREAT | O_BINARY, 0644);
#endif
ADMIN.bookcount = B.bookcount = 0;
ADMIN.booksize = B.booksize = booksize;
B.maxoffset = ADMIN.maxoffset = (unsigned long) (booksize - 1) * sizeof (struct gdxdata) + sizeof (struct gdxadmin);
DATA.hashbd = 0;
DATA.hashkey = 0;
DATA.bmove = 0;
DATA.hint = 0;
DATA.count = 0;
memcpy(gfdptr,&ADMIN,sizeof (struct gdxadmin));
/* sprintf (msg,"creating bookfile %s %ld %ld", binbookfile, B.maxoffset, B.booksize);
ShowMessage(msg); */
memset(gfdptr+sizeof(struct gdxadmin),0,B.booksize*sizeof(struct gdxdata));
}
if (gfd >= 0)
{
side = opponent = white;
xside = computer = black;
InitializeStats ();
i = 0;
end = 0;
while ((c = Vparse (hbook, &mv, side, opening, i)) >= 0 && !end)
{
if (c == 1)
{
/*
* if not first move of an opening and first
* time we have seen it save next move as
* hint
*/
i++;
if (i < bookmaxply + 2)
{
if (i > 1)
{
DATA.hint = mv & 0x3f3f;
}
if (i < bookmaxply + 1)
{
doit = true;
/*
* see if this position and
* move already exist from
* some other opening
*/
/*
* is this ethical, to offer
* the bad move as a
* hint?????
*/
ix = 0;
if (mustwrite)
{
memcpy(gfdptr+currentoffset,&DATA,sizeof(struct gdxdata));
mustwrite = false;
}
doit = true;
currentoffset = (unsigned long) (bhashkey % B.booksize) * sizeof (struct gdxdata) + sizeof (struct gdxadmin);
while (true)
{
memcpy(&DATA,gfdptr+currentoffset,sizeof(struct gdxdata));
if (DATA.bmove == 0)
break;
if (DATA.hashkey == (utshort) (lts (bhashkey)) && DATA.hashbd == bhashbd)
{
if ((DATA.bmove & (~(LASTMOVE | BADMOVE))) == (mv & ~BADMOVE))
{
DATA.count++;
if (mv & BADMOVE)
DATA.bmove |= BADMOVE;
/*
* yes so just bump count - count is
* used to choose opening move in
* proportion to its presence in the book
*/
doit = false;
mustwrite = true;
break;
}
else if (DATA.bmove & LASTMOVE)
{
DATA.bmove &= (~LASTMOVE);
memcpy(gfdptr+currentoffset,&DATA,sizeof(struct gdxdata));
}
}
currentoffset += sizeof (struct gdxdata);
if (currentoffset > B.maxoffset)
currentoffset = sizeof (struct gdxadmin);
}
/*
* doesn`t exist so add it to
* the book
*/
if (!mustwrite)
{
B.bookcount++;
/* initialize a record */
DATA.hashbd = bhashbd;
DATA.hashkey = (utshort) (lts (bhashkey));
DATA.bmove = mv | LASTMOVE;
DATA.count = 1;
DATA.hint = 0;
mustwrite = true;
}
}
}
computer = opponent;
opponent = computer ^ 1;
xside = side;
side = side ^ 1;
}
else if (i > 0)
{
/* reset for next opening */
if (fileoffset-oldoffset > 1000)
{
MSG m;
oldoffset=fileoffset;
sprintf (msg,"Bytes Processed: %ld", fileoffset);
SetWindowText(hOffset,msg);
sprintf (msg,"Record: %ld", B.bookcount);
SetWindowText(hRec,msg);
sprintf(msg,"Games: %ld",games);
SetWindowText(hGames,msg);
while ( PeekMessage(&m, NULL, NULL, NULL, PM_REMOVE))
{ TranslateMessage(&m);
DispatchMessage(&m); }
}
games++;
if (mustwrite)
{
memcpy(gfdptr+currentoffset,&DATA,sizeof(struct gdxdata));
mustwrite = false;
}
RESET ();
i = 0;
side = opponent = white;
xside = computer = black;
}
}
if (mustwrite)
{
memcpy(gfdptr+currentoffset,&DATA,sizeof(struct gdxdata));
mustwrite = false;
}
close (hbook);
free(bkdata);
/* write admin rec with counts */
ADMIN.bookcount = B.bookcount;
memcpy(gfdptr,&ADMIN,sizeof(struct gdxadmin));
write (gfd, gfdptr, B.maxoffset+sizeof(struct gdxdata));
close (gfd);
free(gfdptr);
}
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -