📄 book.c
字号:
{
ShowMessage(CP[80]);
B.bookcount=0;
}
gfd = open (binbookfile, O_RDONLY | O_BINARY);
if (gfd >= 0)
{
B.bookcount = ADMIN.bookcount;
B.booksize = ADMIN.booksize;
B.maxoffset = ADMIN.maxoffset;
}
else B.bookcount = 0;
/* set every thing back to start game */
Book = flag.usebook ? BOOKFAIL : 0;
RESET ();
computer = OrigCompCol;
opponent = computer^1;
if (!B.bookcount)
{
EnableMenuItem (GetMenu(hWnd), IDM_BOOK, MF_GRAYED);
Book = 0;
}
else EnableMenuItem(GetMenu(hWnd), IDM_BOOK, MF_ENABLED);
}
int
OpeningBook (SHORT * hint, SHORT side)
/*
* Go thru each of the opening lines of play and check for a match with the
* current game listing. If a match occurs, generate a random number. If this
* number is the largest generated so far then the next move in this line
* becomes the current "candidate". After all lines are checked, the
* candidate move is put at the top of the Tree[] array and will be played by
* the program. Note that the program does not handle book transpositions.
*/
{
UTSHORT r, m;
int possibles = TrPnt[2] - TrPnt[1];
register UTSHORT i, x;
register UTSHORT rec = 0;
register UTSHORT summ = 0;
register UTSHORT h = 0, b = 0;
struct gdxdata OBB[128];
gsrand ((unsigned int) time ((long *) 0));
m = 0;
/*
* find all the moves for this position - count them and get their
* total count
*/
if (B.bookcount == 0)
{
Book--;
return false;
}
currentoffset = (unsigned long) (hashkey % B.booksize) * sizeof (struct gdxdata) + sizeof (struct gdxadmin);
x = 0;
lseek (gfd, currentoffset, SEEK_SET);
while (true)
{
if (read (gfd, &OBB[x], sizeof (struct gdxdata)) == 0)
break;
if (OBB[x].bmove == 0)
break;
if (OBB[x].hashkey == (utshort) (lts (hashkey)) && OBB[x].hashbd == hashbd)
{
x++;
if (OBB[x - 1].bmove & LASTMOVE)
break;
}
currentoffset += sizeof (struct gdxdata);
if (currentoffset > B.maxoffset)
{
lseek (gfd, sizeof (struct gdxadmin), SEEK_SET);
currentoffset = sizeof (struct gdxadmin);
}
}
if (x == 0)
{
Book--;
return false;
}
#ifdef DEBUG33
{
int loop = true;
while (loop)
{
loop = false;
for (i = 1; i < x; i++)
{
struct gdxdata tmp;
if (OBB[i].count > OBB[i - 1].count)
{
loop = true;
tmp = OBB[i - 1];
OBB[i - 1] = OBB[i];
OBB[i] = tmp;
}
}
}
}
for (i = 0; i < x; i++)
{
algbr ((OBB[i].bmove >> 8) & 0x3f, (OBB[i].bmove) & 0x3f, 0);
printf (" %s ", mvstr[0], OBB[i].count);
algbr ((OBB[i].hint >> 8) & 0x3f, (OBB[i].hint) & 0x3f, 0);
printf ("%s %c %d\n", mvstr[0], (OBB[i].bmove & BADMOVE) ? '*' : ' ', OBB[i].count);
}
#endif
for (i = 0; i < x; i++)
{
if ((m = OBB[i].bmove) & BADMOVE)
{
m &= 0x3f3f;
/* is the move is in the MoveList */
for (b = TrPnt[1]; b < (unsigned) TrPnt[2]; b++)
{
if (((Tree[b].f << 8) | Tree[b].t) == m)
{
if (--possibles)
Tree[b].score = DONTUSE;
pick (TrPnt[1], TrPnt[2] - 1);
break;
}
}
}
else
summ += OBB[i].count;
}
if (summ == 0)
{
Book--;
return false;
}
r = (urand () % summ);
#ifdef DEBUG33
printf ("rand is %d, sum is %d\n", r, summ);
#endif
for (i = 0; i < x; i++)
if (!(OBB[i].bmove & BADMOVE))
{
if (r < OBB[i].count)
{
rec = i;
break;
}
else
r -= OBB[i].count;
#ifdef DEBUG33
printf ("rand is %d, sum is %d\n", r, summ);
#endif
}
h = ((OBB[rec].hint) & 0x3f3f);
m = ((OBB[rec].bmove) & 0x3f3f);
/* make sure the move is in the MoveList */
for (b = TrPnt[1]; b < (unsigned) TrPnt[2]; b++)
{
if (((Tree[b].f << 8) | Tree[b].t) == m)
{
Tree[b].flags |= book;
Tree[b].score = 0;
break;
}
}
/* Make sure its the best */
pick (TrPnt[1], TrPnt[2] - 1);
if (Tree[TrPnt[1]].score)
{
/* no! */
Book--;
return false;
}
/* ok pick up the hint and go */
*hint = h;
return true;
}
void
LOpeningBook (SHORT side)
/*
* Go thru each of the opening lines of play and check for a match with the
* current game listing. If a match occurs, generate a random number. If this
* number is the largest generated so far then the next move in this line
* becomes the current "candidate". After all lines are checked, the
* candidate move is put at the top of the Tree[] array and will be played by
* the program. Note that the program does not handle book transpositions.
*/
{
char Lmove[12], Lhint[12];
/*
* find all the moves for this position - count them and get their
* total count
*/
struct gdxdata OBB[128];
SHORT x;
if (B.bookcount == 0)
{
return;
}
/* Ldisplay1 (); */
currentoffset = (unsigned long) (hashkey % B.booksize) * sizeof (struct gdxdata) + sizeof (struct gdxadmin);
x = 0;
lseek (gfd, currentoffset, SEEK_SET);
while (true)
{
if (read (gfd, &OBB[x], sizeof (struct gdxdata)) == 0)
return;
if (OBB[x].bmove == 0)
return;
if (OBB[x].hashkey == (utshort) (lts (hashkey)) && OBB[x].hashbd == hashbd)
{
algbr ((OBB[x].bmove >> 8) & 0x3f, (OBB[x].bmove) & 0x3f, 0);
strcpy (Lmove, mvstr[1]);
if (OBB[x].bmove & BADMOVE)
strcat (Lmove, "?");
algbr ((OBB[x].hint >> 8) & 0x3f, (OBB[x].hint) & 0x3f, 0);
strcpy (Lhint, mvstr[1]);
/* Ldisplay (Lmove, Lhint, OBB[x].count); */
if (OBB[x++].bmove & LASTMOVE)
break;
}
currentoffset += sizeof (struct gdxdata);
if (currentoffset > B.maxoffset)
{
lseek (gfd, sizeof (struct gdxadmin), SEEK_SET);
currentoffset = sizeof (struct gdxadmin);
}
}
/* Ldisplay2 (); */
return;
}
#ifdef IGNUAN
int
GOpeningBook (SHORT * hint, SHORT side, CHAR * mv)
/*
* Go thru each of the opening lines of play and check for a match with the
* current game listing. If a match occurs, generate a random number. If this
* number is the largest generated so far then the next move in this line
* becomes the current "candidate". After all lines are checked, the
* candidate move is put at the top of the Tree[] array and will be played by
* the program. Note that the program does not handle book transpositions.
*/
{
char Lmove[12], Lhint[12];
/*
* find all the moves for this position - count them and get their
* total count
*/
struct gdxdata OBB[128];
SHORT x;
if (B.bookcount == 0)
{
return false;
}
currentoffset = (unsigned long) (hashkey % B.booksize) * sizeof (struct gdxdata) + sizeof (struct gdxadmin);
x = 0;
lseek (gfd, currentoffset, SEEK_SET);
while (true)
{
if (read (gfd, &OBB[x], sizeof (struct gdxdata)) == 0)
return false;
if (OBB[x].bmove == 0)
return false;
if (OBB[x].hashkey == (utshort) (lts (hashkey)) && OBB[x].hashbd == hashbd)
{
algbr ((OBB[x].bmove >> 8) & 0x3f, (OBB[x].bmove) & 0x3f, 0);
if ((strcmp (mvstr[0], mv) == 0) ||
strcmp (mvstr[1], mv) == 0 ||
strcmp (mvstr[2], mv) == 0 ||
strcmp (mvstr[3], mv) == 0 ||
strcmp (mvstr[4], mv) == 0)
return true;
if (OBB[x++].bmove & LASTMOVE)
return false;
}
currentoffset += sizeof (struct gdxdata);
if (currentoffset > B.maxoffset)
{
lseek (gfd, sizeof (struct gdxadmin), SEEK_SET);
currentoffset = sizeof (struct gdxadmin);
}
}
return false;
}
#endif
#ifdef ECO
#ifdef LONG64
#define rts(x) (unsigned long)(((x)&(~1))|(side))
#else
#define rts(x) (unsigned long)(((x)&(~1))|(side))
#endif
extern SHORT ecomove;
int efd = 0;
FILE *Efd;
unsigned int efdsize = 0;
void
EOpeningBook (SHORT side)
{
char E[256];
struct gdxecodata
{
unsigned long hashbd;
unsigned long hashkey;
unsigned int ecoptr;
utshort cntr;
};
SHORT ECOmove = ecomove;
/*
* find all the moves for this position - count them and get their
* total count
*/
struct gdxecodata OBB;
SHORT x, k;
int h = 0;
int l = 0;
unsigned int ecocur;
k = 0;
if (efd == 0)
{
struct stat buf;
efd = open (BINECO, O_RDONLY | O_BINARY);
if (efd < 0)
{
ShowMessage ("BINECO");
return;
}
stat (BINECO, &buf);
efdsize = buf.st_size / sizeof (struct gdxecodata);
Efd = fopen (PGNECO, "r");
if (Efd == (FILE *) NULL)
{
ShowMessage ("PGNECO");
return;
}
}
Ldisplay3 ();
while (ECOmove > 0)
{
h = efdsize;
l = 0;
ecocur = (h + l) / 2;
x = 0;
while (true)
{
SHORT ecofirst;
currentoffset = ecocur * sizeof (struct gdxecodata);
if (lseek (efd, currentoffset, SEEK_SET) < 0)
{
perror ("seek error\n");
exit (0);
}
if (read (efd, &OBB, sizeof (struct gdxecodata)) == 0) break;
if (OBB.hashbd == GameList[ECOmove].hashbd && OBB.hashkey == (unsigned long) (rts (GameList[ECOmove].hashkey))
&& OBB.cntr == 0)
{
/* got it */
printf ("After %d plys:\n", ECOmove);
ecofirst = true;
while (true)
{
if (!ecofirst) { if (read (efd, &OBB, sizeof (struct gdxecodata)) == 0) break; }
else ecofirst = false;
if (OBB.hashbd != GameList[ECOmove].hashbd) break;
if (OBB.hashkey != (unsigned long) (rts (GameList[ECOmove].hashkey))) continue;
if (fseek (Efd, (long) OBB.ecoptr, SEEK_SET) < 0)
{ perror ("Eseek PGNECO"); exit (1); }
if (fgets (E, sizeof (E), Efd) <= (char *) NULL)
{ perror ("fget "); exit (1); }
Ldisplay4 (E);
k++;
if (fgets (E, sizeof (E), Efd) <= (char *) NULL)
{ perror ("fget "); exit (1); }
k += 2;
while (E[0] != '[')
{
Ldisplay4 (E);
k++;
if (fgets (E, sizeof (E), Efd) <= (char *) NULL)
{ perror ("fget "); exit (1); }
}
Ldisplay4 ("\n");
k++;
if (k++ > 32){
if (getchar () == 'q')
{ k = 999; break; }
else
k = 1;}
}
}
else if (OBB.hashbd > GameList[ECOmove].hashbd
|| (OBB.hashbd == GameList[ECOmove].hashbd
&& OBB.hashkey > (unsigned long) (rts (GameList[ECOmove].hashkey))
&& OBB.cntr > 0)
|| (OBB.hashbd == GameList[ECOmove].hashbd
&& OBB.hashkey == (unsigned long) (rts (GameList[ECOmove].hashkey))
&& OBB.cntr > 0))
{ /* high */
h = ecocur;
}
else
{ /* low */
l = ecocur;
}
if ((h == l) || (h - l) == 1)
break;
ecocur = (h + l) / 2;
if (k > 0)
break;
}
if (k > 0)
break;
ECOmove--;
}
Ldisplay2 ();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -