home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
games
/
gnuchess.zip
/
GNUCHESS.C1
< prev
next >
Wrap
Text File
|
1988-10-23
|
43KB
|
1,505 lines
/* Compile via: cc gnuchess.c -o gnuchess. For display version,
add -DDISPLAY flag and -lcurses -ltermcap libraries to
command-line. For SUN Chesstool version, add -DCHESSTOOL
but don't include display options in last sentence.
For faster version, add -O flag to any of these flags.
*/
/* This file contains code for CHESS.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
This file is part of CHESS.
CHESS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY. No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing. Refer to the CHESS General Public
License for full details.
Everyone is granted permission to copy, modify and redistribute
CHESS, but only under the conditions described in the
CHESS General Public License. A copy of this license is
supposed to have been given to you along with CHESS so you
can know your rights and responsibilities. It should be in a
file named COPYING. Among other things, the copyright notice
and this notice must be preserved on all copies. */
/* Modified 12/18/87 by Bill Randle (billr@tekred.tek.com) to
remove a redundant #include and #ifdef section.
*/
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#ifdef MSDOS
#include <dos.h>
#include <stdlib.h>
#include <time.h>
#include <alloc.h>
#define printz printf
#define scanz scanf
#define refresh();
#define initscr();
#define crmode();
#define nocrmode();
#define endwin();
#define _stklen 8000
#define ttblsz 4096
#else
#include <sys/param.h>
#include <sys/times.h>
#define ttblsz 16384
#ifdef DISPLAY
#include <curses.h>
#define printz printw
#define scanz fflush(stdout), scanw
#else
#define printz printf
#define scanz fflush(stdout), scanf
#define refresh();
#define initscr();
#define crmode();
#define nocrmode();
#define endwin();
#endif DISPLAY
#endif MSDOS
#ifndef HZ
#define HZ 60
#endif
#define neutral 0
#define white 1
#define black 2
#define no_piece 0
#define pawn 1
#define knight 2
#define bishop 3
#define rook 4
#define queen 5
#define king 6
#define valueP 100
#define valueN 330
#define valueB 330
#define valueR 520
#define valueQ 980
#define valueK 999
#define ctlP 0x4000
#define ctlN 0x2800
#define ctlB 0x1800
#define ctlR 0x0400
#define ctlQ 0x0200
#define ctlK 0x0100
#define ctlBQ 0x1200
#define ctlRQ 0x0600
#define ctlNN 0x2000
#define px " PNBRQK"
#define qx " pnbrqk"
#define rx "12345678"
#define cx "abcdefgh"
#define check 0x0001
#define capture 0x0002
#define draw 0x0004
#define promote 0x0008
#define cstlmask 0x0010
#define epmask 0x0020
#define exact 0x0040
#define pwnthrt 0x0080
#define truescore 0x0001
#define lowerbound 0x0002
#define upperbound 0x0004
#define maxdepth 30
#define true 1
#define false 0
#define absv(x) ((x) < 0 ? -(x) : (x))
#define taxicab(a,b) (absv(col[a]-col[b]) + absv(row[a]-row[b]))
struct leaf
{
short f,t,score,reply;
unsigned short flags;
};
struct GameRec
{
unsigned short gmove;
short score,depth,time,piece,color;
long nodes;
};
struct TimeControlRec
{
short moves[3];
long clock[3];
};
struct hashval
{
unsigned long bd;
unsigned short key;
};
struct hashentry
{
unsigned long hashbd;
unsigned short reply,flags;
short score,depth;
};
char mvstr1[5],mvstr2[5];
struct leaf Tree[2000],*root;
short TrPnt[maxdepth],board[64],color[64];
short row[64],col[64],locn[8][8],Pindex[64],svalue[64];
short PieceList[3][16],PieceCnt[3],atak[3][64],PawnCnt[3][8];
short castld[3],kingmoved[3],mtl[3],pmtl[3],emtl[3],hung[3];
short mate,post,opponent,computer,Sdepth,Awindow,Bwindow,randflag;
long ResponseTime,ExtraTime,Level,et,et0,time0,cputimer,ft;
long NodeCnt,evrate,ETnodes,EvalNodes,HashCnt;
long OperatorTime;
short quit,reverse,bothsides,hashflag,InChk,player,force,easy,beep;
short wking,bking,TOsquare,timeout,Zscore,zwndw,cptrval,prune,slk;
short HasPawn[3],HasKnight[3],HasBishop[3],HasRook[3],HasQueen[3];
short ChkFlag[maxdepth],CptrFlag[maxdepth],PawnThreat[maxdepth];
short Pscore[maxdepth],Tscore[maxdepth],Threat[maxdepth];
struct GameRec GameList[240];
short GameCnt,Game50,epsquare,lpost;
short BookSize,BookDepth,MaxSearchDepth;
struct TimeControlRec TimeControl;
short TCflag,TCmoves,mycnt1,mycnt2;
#ifdef MSDOS
unsigned short Book[80][24];
#else
unsigned short Book[250][50];
struct tms tmbuf1,tmbuf2;
#endif
short otherside[3]={0,2,1};
short map[64]=
{26,27,28,29,30,31,32,33,38,39,40,41,42,43,44,45,
50,51,52,53,54,55,56,57,62,63,64,65,66,67,68,69,
74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,
98,99,100,101,102,103,104,105,110,111,112,113,114,115,116,117};
short unmap[144]=
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,0,1,2,3,4,5,6,7,-1,-1,-1,-1,8,9,10,11,12,13,14,15,-1,-1,
-1,-1,16,17,18,19,20,21,22,23,-1,-1,-1,-1,24,25,26,27,28,29,30,31,-1,-1,
-1,-1,32,33,34,35,36,37,38,39,-1,-1,-1,-1,40,41,42,43,44,45,46,47,-1,-1,
-1,-1,48,49,50,51,52,53,54,55,-1,-1,-1,-1,56,57,58,59,60,61,62,63,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
short Stboard[64]=
{rook,knight,bishop,queen,king,bishop,knight,rook,
pawn,pawn,pawn,pawn,pawn,pawn,pawn,pawn,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
pawn,pawn,pawn,pawn,pawn,pawn,pawn,pawn,
rook,knight,bishop,queen,king,bishop,knight,rook};
short Stcolor[64]=
{white,white,white,white,white,white,white,white,
white,white,white,white,white,white,white,white,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
black,black,black,black,black,black,black,black,
black,black,black,black,black,black,black,black};
short sweep[7]= {false,false,false,true,true,true,false};
short sweep1[7]= {false,false,false,false,true,true,false};
short sweep2[7]= {false,false,false,true,false,true,false};
short Dpwn[3]={0,4,6};
short Dstart[7]={6,4,8,4,0,0,0};
short Dstop[7]={7,5,15,7,3,7,7};
short Dir[16]={1,12,-1,-12,11,13,-11,-13,10,-10,14,-14,23,-23,25,-25};
short rank7[3] = {0,6,1};
unsigned short killr0[maxdepth],killr1[maxdepth],killr2[maxdepth];
unsigned short killr3[maxdepth],Qkillr[maxdepth],PrVar[maxdepth];
unsigned short PV,hint,Swag0,Swag1,Swag2,Swag3,Swag4,Swag5;
unsigned short hashkey;
unsigned long hashbd;
struct hashval hashcode[3][7][64];
#ifdef MSDOS
struct hashentry far *ttable,*ptbl;
#else
struct hashentry *ttable,*ptbl;
int TerminateSearch(),Die();
#endif MSDOS
unsigned char history[2][64][64];
short Mwpawn[64],Mbpawn[64],Mknight[3][64],Mbishop[3][64],Mking[3][64];
short WeakSq[3][64],Kfield[3][64],contempt[3];
short value[7]={0,valueP,valueN,valueB,valueR,valueQ,valueK};
short control[7]={0,ctlP,ctlN,ctlB,ctlR,ctlQ,ctlK};
short passed_pawn1[8]={0,15,30,60,100,180,280,800};
short passed_pawn2[8]={0,15,25,35,50,90,140,800};
short passed_pawn3[8]={0,5,10,15,20,30,120,800};
short ISOLANI[8] = {-12,-14,-16,-20,-20,-16,-14,-12};
short DOUBLED[8] = {-12,-12,-12,-10,-10,-12,-12,-12};
short BMBLTY[30] = {-4,-2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,13,14,14,
15,15,16,16,17,17,18,18,18,18,18};
short RMBLTY[30] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,14,15,15,
16,16,17,17,18,18,19,19,20,20,20,20};
short Kthreat[16] = {0,-6,-16,-32,-48,-64,-64,-64,-64,-64,-64,-64,
-64,-64,-64,-64};
short KNIGHTPOST,KNIGHTSTRONG,BISHOPSTRONG,KATAK;
short PEDRNK2B,PBKWRD,PWEAKA,PWEAKH,PADVNCM,PAWNSHIELD;
short RHOPN,RHOPNX,KHOPN,KHOPNX;
short ATAKD,HUNGP,HUNGX,KCASTLD,KMOVD,XRAY;
short stage,Zwmtl,Zbmtl,c1,c2,KSFTY,Developed[3];
short KingOpening[64]=
{ 0, 0, -4, -8, -8, -4, 0, 0,
-4, -4, -8,-12,-12, -8, -4, -4,
-12,-16,-20,-20,-20,-20,-16,-12,
-16,-20,-24,-24,-24,-24,-20,-16,
-16,-20,-24,-24,-24,-24,-20,-16,
-12,-16,-20,-20,-20,-20,-16,-12,
-4, -4, -8,-12,-12, -8, -4, -4,
0, 0, -4, -8, -8, -4, 0, 0};
short KingEnding[64]=
{ 0, 6,12,18,18,12, 6, 0,
6,12,18,24,24,18,12, 6,
12,18,24,30,30,24,18,12,
18,24,30,36,36,30,24,18,
18,24,30,36,36,30,24,18,
12,18,24,30,30,24,18,12,
6,12,18,24,24,18,12, 6,
0, 6,12,18,18,12, 6, 0};
short DyingKing[64]=
{ 0, 8,16,24,24,16, 8, 0,
8,32,40,48,48,40,32, 8,
16,40,56,64,64,56,40,16,
24,48,64,72,72,64,48,24,
24,48,64,72,72,64,48,24,
16,40,56,64,64,56,40,16,
8,32,40,48,48,40,32, 8,
0, 8,16,24,24,16, 8, 0};
short pknight[64]=
{ 0, 4, 8,10,10, 8, 4, 0,
4, 8,16,20,20,16, 8, 4,
8,16,24,28,28,24,16, 8,
10,20,28,32,32,28,20,10,
10,20,28,32,32,28,20,10,
8,16,24,28,28,24,16, 8,
4, 8,16,20,20,16, 8, 4,
0, 4, 8,10,10, 8, 4, 0};
short pbishop[64]=
{14,14,14,14,14,14,14,14,
14,22,18,18,18,18,22,14,
14,18,22,22,22,22,18,14,
14,18,22,22,22,22,18,14,
14,18,22,22,22,22,18,14,
14,18,22,22,22,22,18,14,
14,22,18,18,18,18,22,14,
14,14,14,14,14,14,14,14};
short PawnAdvance[64]=
{ 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 4, 0, 0, 4, 2, 0,
6, 8,10,12,12,10, 8, 6,
8,12,20,32,32,20,12, 8,
12,20,28,40,40,28,20,12,
16,28,36,48,48,36,28,16,
16,28,36,48,48,36,28,16,
0, 0, 0, 0, 0, 0, 0, 0};
main(argc,argv)
int argc; char *argv[];
{
#ifdef MSDOS
ttable = (struct hashentry far *)farmalloc(ttblsz *
(unsigned long)sizeof(struct hashentry));
printf("%lu bytes free\n",farcoreleft());
#else
ttable = (struct hashentry *)malloc(ttblsz *
(unsigned long)sizeof(struct hashentry));
signal(SIGINT,Die); signal(SIGQUIT,Die);
#endif MSDOS
#ifdef CHESSTOOL
setlinebuf(stdout);
if (argc > 1) Level = atoi(argv[1]);
else Level = 30; /* Default to 30 seconds */
#endif CHESSTOOL
initscr();
crmode();
NewGame();
while (!(quit))
{
if (bothsides && !mate) SelectMove(opponent,1); else input_command();
if (!(quit || mate || force)) SelectMove(computer,1);
}
nocrmode();
endwin();
}
#ifndef MSDOS
Die()
{
char s[80];
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
gotoXY(50,24);
printz("Abort? ");
scanz("%s",s);
if (strcmp(s,"yes") == 0)
{
#ifdef DISPLAY
gotoXY(1,24);
nocrmode();
endwin();
#endif DISPLAY
exit(0);
}
signal(SIGINT,Die); signal(SIGQUIT,Die);
}
TerminateSearch()
{
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
timeout = true;
bothsides = false;
signal(SIGINT,Die); signal(SIGQUIT,Die);
}
#endif
OpeningBook()
{
short i,j,r0,pnt;
unsigned m,r;
srand((unsigned)time0);
r0 = m = 0;
for (i = 0; i < BookSize; i++)
{
for (j = 0; j <= GameCnt; j++)
if (GameList[j].gmove != Book[i][j]) break;
if (j > GameCnt)
if ((r=rand()) > r0)
{
r0 = r; m = Book[i][GameCnt+1];
hint = Book[i][GameCnt+2];
}
}
for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++)
if ((Tree[pnt].f<<8) + Tree[pnt].t == m) Tree[pnt].score = 0;
sort(TrPnt[1],TrPnt[2]-1);
if (Tree[TrPnt[1]].score < 0) BookDepth = -1;
}
ShowDepth(ch)
char ch;
{
#ifdef DISPLAY
gotoXY(75,1); printz("%2d%c",Sdepth,ch); ClrEoln();
#endif DISPLAY
}
ShowResults(ch)
char ch;
{
#ifndef DISPLAY
#ifndef CHESSTOOL
register int i;
printz("%2d%c %5d %4ld %7ld ",Sdepth,ch,root->score,et,NodeCnt);
for (i = 1; PrVar[i] > 0; i++)
{
algbr((short)(PrVar[i] >> 8),(short)(PrVar[i] & 0xFF),false);
if (i == 9 || i == 17) printz("\n ");
printz("%5s ",mvstr1);
}
printz("\n");
fflush(stdout);
#endif CHESSTOOL
#endif DISPLAY
}
int SelectMove(side,iop)
short side,iop;
/*
Select a move by calling function search() at progressively deeper
ply until time is up or a mate or draw is reached. An alpha-beta
window of -9000 to +90 points is set around the score returned from the
previous iteration.
*/
{
static short i,j,alpha,beta,score,tempb,tempc,temps,xside,rpt;
#ifndef MSDOS
(void) times(&tmbuf1);
signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch);
#endif MSDOS
timeout = false;
xside = otherside[side];
if (iop != 2) player = side;
if (TCflag)
{
ResponseTime = (TimeControl.clock[side]) /
(TimeControl.moves[side] + 3) -
OperatorTime;
ResponseTime += (ResponseTime*TimeControl.moves[side])/(2*TCmoves+1);
}
else ResponseTime = Level;
if (iop == 2) ResponseTime = 999;
if (Sdepth > 0 && root->score > Zscore-zwndw) ResponseTime -= ft;
else if (ResponseTime < 1) ResponseTime = 1;
ExtraTime = 0;
if (Sdepth == 0)
{
ExaminePosition();
ptbl = ttable;
for (i = 0; i < ttblsz; i++,ptbl++) ptbl->depth = 0;
for (i = 0; i < 64; i++)
for (j = 0; j < 64; j++)
history[0][i][j] = history[1][i][j] = 0;
TOsquare = -1;
PV = 0;
if (iop != 2) hint = 0;
for (i = 0; i < maxdepth; i++)
PrVar[i] = killr0[i] = killr1[i] = killr2[i] = killr3[i] = Qkillr[i] = 0;
#ifdef DISPLAY
for (i = 1; i < 17; i++)
{
gotoXY(50,i); ClrEoln();
}
#else
post = false;
#ifndef CHESSTOOL
printz("\nMove# %d Target= %ld Clock: %ld\n",TimeControl.moves[side],
ResponseTime,TimeControl.clock[side]);
#endif CHESSTOOL
#endif DISPLAY
alpha = -9000; beta = 9000; rpt = 0;
TrPnt[1] = 0; root = &Tree[0];
MoveList(side,1);
if (GameCnt < BookDepth) OpeningBook(); else BookDepth = -1;
if (BookDepth > 0) timeout = true;
NodeCnt = ETnodes = EvalNodes = HashCnt = 0;
Zscore = 0; zwndw = 25;
}
while (!timeout && Sdepth < MaxSearchDepth)
{
Sdepth++;
ShowDepth(' ');
score = search(side,1,Sdepth,alpha,beta,PrVar,&rpt);
for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i];
if (score < alpha)
{
ShowDepth('-');
ExtraTime = 5*ResponseTime;
score = search(side,1,Sdepth,-9000,beta,PrVar,&rpt);
}
if (score > beta && !(root->flags & exact))
{
ShowDepth('+');
ExtraTime = 0;
score = search(side,1,Sdepth,alpha,9000,PrVar,&rpt);
}
score = root->score;
ShowResults('.');
beta = score + Bwindow;
if (Awindow != 9000) alpha = score - Awindow;
for (i = 1; i <= Sdepth; i++) killr0[i] = PrVar[i];
if (!timeout) sort(0,TrPnt[2]-1);
if (score > Zscore-zwndw && score > Tree[1].score+250) ExtraTime = 0;
else if (score > Zscore-3*zwndw) ExtraTime = ResponseTime;
else ExtraTime = 3*ResponseTime;
if (root->flags & exact) timeout = true;
if (Tree[1].score < -9000) timeout = true;
if (4*et > 2*ResponseTime + ExtraTime) timeout = true;
if (!timeout)
{
Tscore[0] = score;
if (Zscore == 0) Zscore = score;
else Zscore = (Zscore+score)/2;
}
zwndw = 25+absv(Zscore/12);
}
score = root->score;
if (rpt >= 2 || score < -12000) root->flags |= draw;
if (iop == 2) return(0);
if (BookDepth < 0) hint = PrVar[2];
ElapsedTime(1);
#ifdef DISPLAY
gotoXY(50,22); printz("Nodes= %6ld",NodeCnt); ClrEoln();
gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); ClrEoln();
#else
#ifndef CHESSTOOL
printz("Nodes= %ld Eval= %ld Hash= %ld Rate= %ld ",
NodeCnt,EvalNodes,HashCnt,evrate);
printz("CPU= %.2ld:%.2ld.%.2ld\n",
cputimer/6000,(cputimer % 6000)/100,cputimer % 100);
#endif CHESSTOOL
#endif DISPLAY
if (score > -9999 && rpt <= 2)
{
MakeMove(side,root,&tempb,&tempc,&temps);
algbr(root->f,root->t,root->flags & cstlmask);
}
else algbr(PieceList[side][0],PieceList[side][0],false);
if (root->flags & epmask) UpdateDisplay(0,0,1,0);
else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask);
#ifdef CHESSTOOL
gotoXY(50,17); printz("%d. ... %s",++mycnt1,mvstr1); ClrEoln();
if (root->flags & draw) printz("Draw\n");
if (score == -9999)
if (opponent == white) printz("White\n"); else printz("Black\n");
if (score == 9998)
if (computer == white) printz("White\n"); else printz("Black\n");
#else
gotoXY(50,17); printz("My move is: %s",mvstr1);
if (beep) printz("%c",7);
ClrEoln();
gotoXY(50,24);
if (root->flags & draw) printz("Draw game!");
if (score == -9999) printz("opponent mates!");
else if (score == 9998) printz("computer mates!");
else if (score < -9000) printz("opponent will soon mate!");
else if (score > 9000) printz("computer will soon mate!");
ClrEoln();
#endif CHESSTOOL
#ifndef DISPLAY
printz("\n");
#endif DISPLAY
if (score == -9999 || score == 9998) mate = true;
if (mate) hint = 0;
if (post) post_move(root);
if (root->flags & cstlmask) Game50 = GameCnt;
else if (board[root->t] == pawn || (root->flags & capture))
Game50 = GameCnt;
GameList[GameCnt].score = score;
GameList[GameCnt].nodes = NodeCnt;
GameList[GameCnt].time = (short)et;
GameList[GameCnt].depth = Sdepth;
if (TCflag)
{
TimeControl.clock[side] -= (et + OperatorTime);
if (--TimeControl.moves[side] == 0)
SetTimeControl();
}
#ifdef MSDOS
if (kbhit()) bothsides = false;
#endif
if ((root->flags & draw) && bothsides) quit = true;
if (GameCnt > 238) quit = true;
player = xside;
Sdepth = 0;
fflush(stdin);
return(0);
}
#ifdef CHESSTOOL
#define illegalmsg printz("illegal move\n")
#else
#define illegalmsg {gotoXY(50,24); printz("illegal move!"); ClrEoln();}
#endif
int VerifyMove(s,iop,mv)
char s[];
short iop;
unsigned short *mv;
{
static short pnt,tempb,tempc,temps,cnt;
static struct leaf xnode;
struct leaf *node;
*mv = 0;
if (iop == 2)
{
UnmakeMove(opponent,&xnode,&tempb,&tempc,&temps);
return(false);
}
cnt = 0;
MoveList(opponent,2);
pnt = TrPnt[2];
while (pnt < TrPnt[3])
{
node = &Tree[pnt]; pnt++;
algbr(node->f,node->t,node->flags & cstlmask);
if (strcmp(s,mvstr1) == 0 || strcmp(s,mvstr2) == 0)
{
cnt++; xnode = *node;
}
}
if (cnt == 0)
if (isdigit(s[1]) || isdigit(s[2])) illegalmsg;
if (cnt == 1)
{
MakeMove(opponent,&xnode,&tempb,&tempc,&temps);
if (SqAtakd(PieceList[opponent][0],computer))
{
UnmakeMove(opponent,&xnode,&tempb,&tempc,&temps);
illegalmsg;
return(false);
}
else
{
if (iop == 1) return(true);
if (xnode.flags & epmask) UpdateDisplay(0,0,1,0);
else UpdateDisplay(xnode.f,xnode.t,0,xnode.flags & cstlmask);
if (xnode.flags & cstlmask) Game50 = GameCnt;
else if (board[xnode.t] == pawn || (xnode.flags & capture))
Game50 = GameCnt;
GameList[GameCnt].depth = GameList[GameCnt].score = 0;
GameList[GameCnt].nodes = 0;
ElapsedTime(1);
GameList[GameCnt].time = (short)et;
TimeControl.clock[opponent] -= et;
--TimeControl.moves[opponent];
*mv = (xnode.f << 8) + xnode.t;
return(true);
}
}
else if (cnt > 1)
{
gotoXY(50,24); printz("ambiguous move!"); ClrEoln();
}
return(false);
}
input_command()
{
short ok,i,f,t,c,p,tc,tp;
unsigned short mv;
char s[80],fname[20];
ok=quit=false;
player = opponent;
ataks(white,atak[white]); ataks(black,atak[black]);
#ifdef DISPLAY
gotoXY(50,19); printz("Your move is? "); ClrEoln();
#endif
ft = 0;
if (hint > 0 && !easy && BookDepth < 0)
{
fflush(stdout);
time0 = time((long *)0);
algbr(hint>>8,hint & 0xFF,false);
strcpy(s,mvstr1);
f = epsquare;
if (VerifyMove(s,1,&mv))
{
SelectMove(computer,2);
VerifyMove(mvstr1,2,&mv);
if (Sdepth > 0) Sdepth--;
}
ft = time((long *)0) - time0;
epsquare = f;
}
fflush(stdin);
while (!(ok || quit))
{
#ifndef CHESSTOOL
gotoXY(50,19); printz("Your move is? "); ClrEoln();
#endif CHESSTOOL
scanz("%s",s);
player = opponent;
ok = VerifyMove(s,0,&mv);
if (ok && mv != hint)
{
Sdepth = 0;
ft = 0;
}
if (strcmp(s,"bd") == 0)
{
#ifdef DISPLAY
ClrScreen(); UpdateDisplay(0,0,1,0);
#else
PrintBoard();
#endif DISPLAY
}
if (strcmp(s,"quit") == 0) quit = true;
if (strcmp(s,"post") == 0) post = !post;
if (strcmp(s,"set") == 0) SetBoard();
if (strcmp(s,"go") == 0) ok = true;
if (strcmp(s,"help") == 0) help();
if (strcmp(s,"force") == 0) force = !force;
if (strcmp(s,"random") == 0) randflag = !randflag;
if (strcmp(s,"book") == 0) BookDepth = -1;
if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo();
if (strcmp(s,"new") == 0) NewGame();
if (strcmp(s,"list") == 0) ListGame();
if (strcmp(s,"clock") == 0) SetTimeControl();
if (strcmp(s,"hash") == 0) hashflag = !hashflag;
if (strcmp(s,"beep") == 0) beep = !beep;
if (strcmp(s,"Awindow") == 0)
{
gotoXY(50,24); printz("window: "); ClrEoln();
scanz("%hd",&Awindow);
}
if (strcmp(s,"Bwindow") == 0)
{
gotoXY(50,24); printz("window: "); ClrEoln();
scanz("%hd",&Bwindow);
}
if (strcmp(s,"hint") == 0)
{
algbr((short)(hint>>8),(short)(hint & 0xFF),false);
gotoXY(50,24); printz("try %5s",mvstr1); ClrEoln();
}
if (strcmp(s,"both") == 0)
{
bothsides = !bothsides;
Sdepth = 0;
SelectMove(opponent,1);
ok = true;
}
if (strcmp(s,"reverse") == 0)
{
reverse = !reverse;
ClrScreen();
UpdateDisplay(0,0,1,0);
}
if (strcmp(s,"switch") == 0)
{
computer = otherside[computer];
opponent = otherside[opponent];
UpdateDisplay(0,0,1,0);
force = false;
ok = true;
Sdepth = 0;
}
if (strcmp(s,"white") == 0)
{
computer = white; opponent = black;
UpdateDisplay(0,0,1,0);
ok = true; force = false;
Sdepth = 0;
}
if (strcmp(s,"black") == 0)
{
computer = black; opponent = white;
UpdateDisplay(0,0,1,0);
ok = true; force = false;
Sdepth = 0;
}
if (strcmp(s,"time") == 0)
{
gotoXY(50,24); printz("enter time: "); ClrEoln();
scanz("%ld",&Level);
TCflag = false;
}
if (strcmp(s,"remove") == 0 && GameCnt >= 1)
{
Undo(); Undo();
}
if (strcmp(s,"get") == 0)
{
gotoXY(50,24); printz("fname? "); ClrEoln(); scanz("%s",fname);
GetGame(fname);
InitializeStats();
UpdateDisplay(0,0,1,0);
Sdepth = 0;
}
if (strcmp(s,"save") == 0)
{
gotoXY(50,24); printz("fname? "); ClrEoln(); scanz("%s",fname);
SaveGame(fname);
}
if (strcmp(s,"depth") == 0)
{
gotoXY(50,24); printz("depth= "); ClrEoln();
scanz("%hd",&MaxSearchDepth);
}
if (strcmp(s,"verify") == 0) VerifyBook();
if (strcmp(s,"easy") == 0) easy = !easy;
if (strcmp(s,"contempt") == 0)
{
gotoXY(50,24); printz("contempt= "); ClrEoln();
scanz("%hd",&c);
contempt[computer] = c;
contempt[opponent] = -c;
}
if (strcmp(s,"prune") == 0)
{
gotoXY(50,24); printz("prune= "); ClrEoln();
scanz("%hd",&prune);
}
if (strcmp(s,"debug") == 0)
{
ExaminePosition();
gotoXY(50,24); printz("enter piece: "); ClrEoln();
scanz("%s",s);
if (s[0] == 'w') c = white; else c = black;
if (s[1] == 'p') p = pawn;
else if (s[1] == 'n') p = knight;
else if (s[1] == 'b') p = bishop;
else if (s[1] == 'r') p = rook;
else if (s[1] == 'q') p = queen;
else if (s[1] == 'k') p = king;
else p = no_piece;
for (i = 0; i < 64; i++)
{
gotoXY(4+5*col[i],5+2*(7-row[i]));
tp = board[i]; tc = color[i];
board[i] = p; color[i] = c;
c1 = c; c2 = otherside[c1];
printz("%3d ",SqValue(i,opponent));
board[i] = tp; color[i] = tc;
}
refresh();
}
}
#ifdef CHESSTOOL
printf("%d. %s\n",++mycnt2,s);
#endif CHESSTOOL
gotoXY(50,24); ClrEoln();
ElapsedTime(1);
if (force)
{
computer = opponent; opponent = otherside[computer];
}
}
gotoXY(x,y)
short x,y;
{
#ifdef DISPLAY
#ifdef MSDOS
union REGS r1,r2;
r1.h.ah = 0x02; r1.h.bh = 0x00;
r1.h.dl = x-1; r1.h.dh = y-1;
int86(0x10,&r1,&r2);
#else
move(y-1,x-1);
#endif MSDOS
#else
#ifndef CHESSTOOL
printz("\n");
#endif CHESSTOOL
#endif DISPLAY
}
ClrScreen()
{
#ifdef DISPLAY
#ifdef MSDOS
union REGS r1,r2;
gotoXY(1,1);
r1.h.ah = 0x08; r1.h.bh = 0x00;
int86(0x10,&r1,&r2);
r1.h.ah = 0x09; r1.h.al = 0x20;
r1.h.bh = 0x00; r1.h.bl = r2.h.ah;
r1.h.ch = 0x07; r1.h.cl = 0xD0;
int86(0x10,&r1,&r2);
gotoXY(1,1);
#else
clear(); refresh();
#endif MSDOS
#else
printz("\n\n");
#endif DISPLAY
}
ClrEoln()
{
#ifdef DISPLAY
#ifdef MSDOS
union REGS r1,r2;
char x,y;
r1.h.ah = 0x03; r1.h.bh = 0x00;
int86(0x10,&r1,&r2);
x = r2.h.dl+1; y = r2.h.dh+1;
r1.h.ah = 0x08; r1.h.bh = 0x00;
int86(0x10,&r1,&r2);
r1.h.ah = 0x09; r1.h.al = 0x20;
r1.h.bh = 0x00; r1.h.bl = r2.h.ah;
r1.h.ch = 0x00; r1.h.cl = 81-x;
int86(0x10,&r1,&r2);
gotoXY(x,y);
#else
clrtoeol(); refresh();
#endif MSDOS
#endif DISPLAY
}
algbr(f,t,iscastle)
short f,t,iscastle;
{
mvstr1[0] = cx[col[f]]; mvstr1[1] = rx[row[f]];
mvstr1[2] = cx[col[t]]; mvstr1[3] = rx[row[t]];
mvstr2[0] = qx[board[f]];
mvstr2[1] = mvstr1[2]; mvstr2[2] = mvstr1[3];
mvstr1[4] = '\0'; mvstr2[3] = '\0';
if (iscastle)
if (t > f) strcpy(mvstr2,"o-o");
else strcpy(mvstr2,"o-o-o");
}
Undo()
{
short f,t;
f = GameList[GameCnt].gmove>>8;
t = GameList[GameCnt].gmove & 0xFF;
if (board[t] == king && distance(t,f) > 1)
castle(GameList[GameCnt].color,f,t,2);
else
{
board[f] = board[t]; color[f] = color[t];
board[t] = GameList[GameCnt].piece;
color[t] = GameList[GameCnt].color;
if (board[f] == king) --kingmoved[color[f]];
}
if (TCflag) ++TimeControl.moves[color[f]];
GameCnt--; mate = false; Sdepth = 0;
UpdateDisplay(0,0,1,0);
InitializeStats();
}
parse(s,m,j)
unsigned short *m; char s[];
short j;
{
short r1,r2,c1,c2;
if (s[4] == 'o')
if (j & 1) *m = 0x3C3A; else *m = 0x0402;
else if (s[0] == 'o')
if (j & 1) *m = 0x3C3E; else *m = 0x0406;
else
{
c1 = s[0] - 'a'; r1 = s[1] - '1';
c2 = s[2] - 'a'; r2 = s[3] - '1';
*m = (locn[r1][c1]<<8) + locn[r2][c2];
}
}
GetOpenings()
{
FILE *fd;
int c,j;
char s[80],*p;
if ((fd = fopen("gnuchess.book","r")) != NULL)
{
BookSize = 0; j = 0; c = '?'; p = s;
while ((c = getc(fd)) != EOF)
if (c != '\n') *(p++) = c;
else
{
*p = '\0';
if (s[0] == '!')
{
if (j > 0)
{
while (j < BookDepth) Book[BookSize][j++] = 0;
BookSize++; j = 0;
}
}
else
{
parse(&s[0],&Book[BookSize][j],j); j++;
parse(&s[6],&Book[BookSize][j],j); j++;
}
p = s;
}
fclose(fd);
}
}
GetGame(fname)
char fname[20];
{
FILE *fd;
int c;
short loc;
unsigned short m;
if (fname[0] == '\0') strcpy(fname,"chess.000");
if ((fd = fopen(fname,"r")) != NULL)
{
fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
fscanf(fd,"%hd%hd%hd%hd",
&castld[white],&castld[black],
&kingmoved[white],&kingmoved[black]);
fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
fscanf(fd,"%ld%ld%hd%ld",
&TimeControl.clock[white],&TimeControl.clock[black],
&TimeControl.moves[white],&TimeControl.moves[black]);
for (loc = 0; loc < 64; loc++)
{
fscanf(fd,"%hd",&m); board[loc] = (m >> 8); color[loc] = (m & 0xFF);
}
GameCnt = -1; c = '?';
while (c != EOF)
{
++GameCnt;
c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
&GameList[GameCnt].score,&GameList[GameCnt].depth,
&GameList[GameCnt].nodes,&GameList[GameCnt].time,
&GameList[GameCnt].piece,&GameList[GameCnt].color);
}
GameCnt--;
}
fclose(fd);
}
SaveGame(fname)
char fname[20];
{
FILE *fd;
short loc,i;
if (fname[0] == '\0') strcpy(fname,"chess.000");
fd = fopen(fname,"w");
fprintf(fd,"%d %d %d\n",computer,opponent,Game50);
fprintf(fd,"%d %d %d %d\n",
castld[white],castld[black],kingmoved[white],kingmoved[black]);
fprintf(fd,"%d %d\n",TCflag,OperatorTime);
fprintf(fd,"%ld %ld %d %ld\n",
TimeControl.clock[white],TimeControl.clock[black],
TimeControl.moves[white],TimeControl.moves[black]);
for (loc = 0; loc < 64; loc++)
fprintf(fd,"%d\n",256*board[loc] + color[loc]);
for (i = 0; i <= GameCnt; i++)
fprintf(fd,"%d %d %d %ld %d %d %d\n",
GameList[i].gmove,GameList[i].score,GameList[i].depth,
GameList[i].nodes,GameList[i].time,
GameList[i].piece,GameList[i].color);
fclose(fd);
}
ListGame()
{
FILE *fd;
short i,f,t;
fd = fopen("chess.lst","w");
fprintf(fd,"\n");
fprintf(fd," score depth nodes time ");
fprintf(fd," score depth nodes time\n");
for (i = 0; i <= GameCnt; i++)
{
f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
algbr(f,t,false);
if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," ");
fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1,
GameList[i].score,GameList[i].depth,
GameList[i].nodes,GameList[i].time);
}
fprintf(fd,"\n\n");
fclose(fd);
}
VerifyBook()
{
short i,j,side,found,pnt,tempb,tempc,temps;
unsigned short mv;
struct leaf *node;
ClrScreen();
for (i = 0; i < BookSize; i++)
{
CopyBoard(Stboard,board); CopyBoard(Stcolor,color);
InitializeStats(); GameCnt = 0;
kingmoved[white] = kingmoved[black] = false;
castld[white] = castld[black] = false;
side = white;
for (j = 0; Book[i][j] > 0; j++)
{
MoveList(side,1);
found = false;
for (pnt = TrPnt[1]; pnt < TrPnt[2]; pnt++)
{
node = &Tree[pnt];
mv = (node->f << 8) + node->t;
if (mv == Book[i][j])
{
found = true;
MakeMove(side,node,&tempb,&tempc,&temps);
break;
}
}
if (!found) break;
side = otherside[side];
}
if (found) printz("%d ok\n",i);
else printz("%d bad (%d)\n",i,j);
}
}
SetTimeControl()
{
long minutes;
TCmoves = 0; OperatorTime = 30000;
while (TCmoves <= 0)
{
gotoXY(50,24); printz("Enter #moves #minutes: "); ClrEoln();
scanz("%hd %ld",&TCmoves,&minutes);
}
while (OperatorTime * TCmoves > 60*minutes + TCmoves)
{
gotoXY(50,24); printz("Operator time= "); ClrEoln();
scanz("%ld",&OperatorTime);
}
TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
TimeControl.clock[white] = TimeControl.clock[black] = 60*minutes;
TCflag = true;
et = 0;
#ifndef MSDOS
(void) times(&tmbuf1);
#endif MSDOS
ElapsedTime(1);
}
ElapsedTime(iop)
short iop;
{
short m,s;
et = time((long *)0) - time0;
if (et < 0) et = 0;
ETnodes += 50;
if (et > et0 || iop == 1)
{
if (et > ResponseTime+ExtraTime) timeout = true;
#ifdef MSDOS
if (kbhit()) timeout = true;
#endif MSDOS
et0 = et;
if (iop == 1)
{
time0 = time((long *)0); et0 = 0;
}
#ifdef DISPLAY
m = et/60; s = (et - 60*m);
if (TCflag)
{
m = (TimeControl.clock[player] - et) / 60;
s = absv(TimeControl.clock[player]) - et - 60*m;
}
if (player == white)
if (reverse) gotoXY(20,2); else gotoXY(20,23);
else
if (reverse) gotoXY(20,23); else gotoXY(20,2);
printz("%d:%2d ",m,s);
#endif DISPLAY
#ifdef MSDOS
cputimer = 100*et;
if (et > 0) evrate = NodeCnt/(et+ft); else evrate = 0;
#else
(void) times(&tmbuf2);
cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ;
if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft);
else evrate = 0;
#endif MSDOS
ETnodes = NodeCnt + 50;
if (post)
{
gotoXY(50,22); printz("Nodes= %6ld",NodeCnt);
gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate);
}
refresh();
}
}
post_move(node)
struct leaf *node;
{
short c,d,e,ply;
e = lpost; c = player;
gotoXY(50,3); printz("Score= %6d",node->score);
if (c == white) d = 4; else d = 5;
for (ply = 1; PrVar[ply] > 0; ply++)
{
algbr((short)(PrVar[ply]>>8),(short)(PrVar[ply] & 0x00FF),false);
if (c == white) gotoXY(50,++d); else gotoXY(60,d);
printz("%5s",mvstr1);
c = otherside[c];
}
ClrEoln();
lpost = d;
while (++d <= e)
{
gotoXY(50,d); ClrEoln();
}
}
DrawPiece(loc)
short loc;
{
#ifdef DISPLAY
short r,c; char x;
if (reverse) r = 7-row[loc]; else r = row[loc];
if (reverse) c = 7-col[loc]; else c = col[loc];
if (color[loc] == black) x = '*'; else x = ' ';
gotoXY(5+5*c,5+2*(7-r)); printz("%c%c ",x,px[board[loc]]);
#endif DISPLAY
}
UpdateDisplay(f,t,flag,iscastle)
short f,t,flag,iscastle;
{
#ifdef DISPLAY
short i,l,c,z;
if (flag)
{
i = 3;
gotoXY(3,++i);
printz("|----|----|----|----|----|----|----|----|");
while (i<19)
{
gotoXY(1,++i);
if (reverse) z = (i/2)-1; else z = 10-(i/2);
printz("%d | | | | | | | | |",z);
gotoXY(3,++i);
printz("|----|----|----|----|----|----|----|----|");
}
gotoXY(3,21);
if (reverse) printz(" h g f e d c b a");
else printz(" a b c d e f g h");
if (reverse) gotoXY(5,23); else gotoXY(5,2);
if (computer == black) printz("Computer"); else printz("Human ");
if (reverse) gotoXY(5,2); else gotoXY(5,23);
if (computer == white) printz("Computer"); else printz("Human ");
for (l = 0; l < 64; l++) DrawPiece(l);
}
else
{
DrawPiece(f); DrawPiece(t);
if (iscastle)
if (t > f)
{ DrawPiece(f+3); DrawPiece(t-1); }
else
{ DrawPiece(f-4); DrawPiece(t+1); }
}
refresh();
#endif DISPLAY
}
PrintBoard()
{
short r,c,l;
#ifndef DISPLAY
printz("\n");
for (r = 7; r >= 0; r--)
{
for (c = 0; c <= 7; c++)
{
if (reverse) l = locn[7-r][7-c]; else l = locn[r][c];
if (color[l] == neutral) printz(" -");
else if (color[l] == white) printz(" %c",qx[board[l]]);
else printz(" %c",px[board[l]]);
}
printz("\n");
}
#endif DISPLAY
}
SetBoard()
{
short a,r,c,loc;
char s[80];
ClrScreen(); UpdateDisplay(0,0,1,0);
gotoXY(50,2); printz(". exit to main");
gotoXY(50,3); printz("# clear board");
a = white;
do
{
gotoXY(49,5);
printz("enter piece & location: "); ClrEoln(); scanz("%s",s);
if (s[0] == '#')
{
for (loc = 0; loc < 64; loc++)
{ board[loc] = no_piece; color[loc] = neutral; }
UpdateDisplay(0,0,1,0);
}
if (s[0] == 'c' || s[0] == 'C') a = otherside[a];
c = s[1]-'a'; r = s[2]-'1';
if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
{
loc = locn[r][c];
color[loc] = a;
if (s[0] == 'p') board[loc] = pawn;
else if (s[0] == 'n') board[loc] = knight;
else if (s[0] == 'b') board[loc] = bishop;
else if (s[0] == 'r') board[loc] = rook;
else if (s[0] == 'q') board[loc] = queen;
else if (s[0] == 'k') board[loc] = king;
else { board[loc] = no_piece; color[loc] = neutral; }
DrawPiece(loc);
}
}
while (s[0] != '.');
if (board[4] != king) kingmoved[white] = 10;
if (board[60] != king) kingmoved[black] = 10;
GameCnt = -1; Game50 = 0; BookDepth = -1; Sdepth = 0;
InitializeStats(); ClrScreen(); UpdateDisplay(0,0,1,0);
}
NewGame()
{
short l,r,c,p;
mate = quit = reverse = bothsides = post = randflag = TCflag = false;
hashflag = force = easy = false;
beep = true;
mycnt1 = mycnt2 = 0;
lpost = NodeCnt = epsquare = et0 = 0;
Awindow = 9000;
Bwindow = 90;
MaxSearchDepth = 30;
prune = 50;
contempt[white] = contempt[black] = 0;
#ifdef MSDOS
BookDepth = 24;
#else
BookDepth = 50;
#endif MSDOS
GameCnt = -1; Game50 = 0;
Zwmtl = Zbmtl = 0;
Developed[white] = Developed[black] = false;
castld[white] = castld[black] = false;
kingmoved[white] = kingmoved[black] = 0;
PawnThreat[0] = CptrFlag[0] = Threat[0] = false;
Pscore[0] = 12000; Tscore[0] = 12000;
TimeControl.clock[white] = TimeControl.clock[black] = 0;
TimeControl.moves[white] = TimeControl.moves[black] = 0;
opponent = white; computer = black;
for (r = 0; r < 8; r++)
for (c = 0; c < 8; c++)
{
l = 8*r+c; locn[r][c] = l;
row[l] = r; col[l] = c;
board[l] = Stboard[l]; color[l] = Stcolor[l];
}
for (c = white; c <= black; c++)
for (p = pawn; p <= king; p++)
for (l = 0; l < 64; l++)
{
hashcode[c][p][l].key = (unsigned short)rand();
hashcode[c][p][l].bd = ((unsigned long)rand() << 16) +
(unsigned long)rand();
}
#ifdef CHESSTOOL
printf("Chess\n");
easy = true;
#else
ClrScreen(); gotoXY(1,20);
printz("enter response time: "); ClrEoln();
scanz("%ld",&Level);
ClrScreen();
#endif CHESSTOOL
UpdateDisplay(0,0,1,0);
InitializeStats();
time0 = time((long *)0);
ElapsedTime(1);
GetOpenings();
}
help()
{
ClrScreen();
gotoXY(28,1); printz("CHESS command summary");
gotoXY(1,3); printz("g1f3 move from g1 to f3");
gotoXY(1,4); printz("nf3 move knight to f3");
gotoXY(1,5); printz("o-o castle king side");
gotoXY(1,6); printz("o-o-o castle queen side");
gotoXY(1,7); printz("set edit board");
gotoXY(1,8); printz("switch sides with computer");
gotoXY(1,9); printz("white computer plays white");
gotoXY(1,10); printz("black computer plays black");
gotoXY(1,11); printz("reverse board display");
gotoXY(1,12); printz("both computer match");
gotoXY(1,13); printz("random randomize play");
gotoXY(1,14); printz("undo undo last move");
gotoXY(42,3); printz("time change level");
gotoXY(42,4); printz("depth set search depth");
gotoXY(42,5); printz("post principle variation");
gotoXY(42,6); printz("hint suggest a move");
gotoXY(42,7); printz("bd redraw board");
gotoXY(42,8); printz("clock set time control");
gotoXY(42,9); printz("force enter game moves");
gotoXY(42,10); printz("list game to chess.lst");
gotoXY(42,11); printz("save game to file");
gotoXY(42,12); printz("get game from file");
gotoXY(42,13); printz("new start new game");
gotoXY(42,14); printz("quit exit CHESS");
gotoXY(10,21); printz("Computer: ");
if (computer == white) printz("WHITE"); else printz("BLACK");
gotoXY(10,22); printz("Opponent: ");
if (opponent == white) printz("WHITE"); else printz("BLACK");
gotoXY(10,23); printz("Response time: %ld",Level," sec.");
gotoXY(10,24); printz("Easy mode: ");
if (easy) printz("ON"); else printz("OFF");
gotoXY(40,21); printz("Depth: %d",MaxSearchDepth);
gotoXY(40,22); printz("Random: ");
if (randflag) printz("ON"); else printz("OFF");
gotoXY(40,23); printz("Transposition table: ");
if (hashflag) printz("ON"); else printz("OFF");
refresh();
while (getchar() != '\n');
ClrScreen();
UpdateDisplay(0,0,1,0);
}
UpdateHashbd(side,piece,f,t)
short side,piece,f,t;
/*
hashbd contains a 32 bit "signature" of the board position.
hashkey contains a 16 bit code used to address the hash table.
When a move is made, XOR'ing the hashcode of moved piece on the from and
to squares with the hashbd and hashkey values keeps things current.
*/
{
if (f >= 0)
{
hashbd ^= hashcode[side][piece][f].bd;
hashkey ^= hashcode[side][piece][f].key;
}
if (t >= 0)
{
hashbd ^= hashcode[side][piece][t].bd;
hashkey ^= hashcode[side][piece][t].key;
}
}
UpdatePieceList(side,loc,iop)
short side,loc,iop;
/*
Array PieceList[side][Pindx] contains the location of all the pieces of
either side. Array Pindex[loc] contains the indx into PieceList for a
given square.
*/
{
register short i;
if (iop == 1)
{
PieceCnt[side]--;
for (i = Pindex[loc]; i <= PieceCnt[side]; i++)
{
PieceList[side][i] = PieceList[side][i+1];
Pindex[PieceList[side][i]] = i;
}
}
else
{
PieceCnt[side]++;
PieceList[side][PieceCnt[side]] = loc;
Pindex[loc] = PieceCnt[side];
}
}