📄 init.c
字号:
/*
* init.c - C source for GNU CHESS for Windows
*
* Copyright (c) 1988,1989,1990 John Stanback
* Copyright (c) 1992 Free Software Foundation
* Additions for the Windows version Copyright (c) 1996 Conor McCarthy
*
* 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"
#ifdef HAVE_GETTIMEOFDAY
#include <sys/time.h>
#endif
extern SHORT CompColorExt,WhoseTurnExt,CompMoveExt;
extern SHORT notime;
extern SHORT selected;
extern DWORD CustCols[16];
SHORT WinSizeX,WinSizeY,WinPosX,WinPosY;
RECT wr;
SHORT maximized;
char lpStatic[]="STATIC";
char IniFile[]="gnuchess.ini";
char hexuint[]="%06X";
char shortfs[]="%hd";
char BrdSection[]="board";
char OptSection[]="options";
char skillsectn[]="skill";
char szboardsize[]="boardsize";
char szsquarebd[]="squarebd";
char szwinsizeX[]="winsizeX";
char szwinsizeY[]="winsizeY";
char szwinposX[]="winposX";
char szwinposY[]="winposY";
char szmaximized[]="maximized";
char szbkgrnd[]="background";
char szwhitesq[]="whitesquare";
char szblacksq[]="blacksquare";
char szwhitepc[]="whitepiece";
char szblackpc[]="blackpiece";
char sztext[]="text";
char szedge[]="edge";
char szcustcols[]="cc00";
char szbeep[]="beep";
char szcoords[]="coords";
char szstats[]="stats";
char szbook[]="book";
char szhash[]="hash";
char szhdepth[]="hashdepth";
char szmvlim[]="movelimit";
char szWA[]="WAwindow";
char szWB[]="WBwindow";
char szWX[]="WXwindow";
char szBA[]="BAwindow";
char szBB[]="BBwindow";
char szBX[]="BXwindow";
char szcontempt[]="contempt";
char szmaterial[]="material";
char szrcptr[]="recapture";
char szthreat[]="threat";
char szpvs[]="pvs";
char szne[]="neweval";
char szgamein[]="gamein";
char szXCmv0[]="XCmoves0";
char szXCmin0[]="XCminutes0";
char szXCmv1[]="XCmoves1";
char szXCmin1[]="XCminutes1";
char szXCmv2[]="XCmoves2";
char szXCmin2[]="XCminutes2";
char szXC[]="XC";
char szMRT[]="MaxResponseTime";
char szdither[]="dither";
char szeasy[]="easy";
char szmaxdepth[]="maxdepth";
char sznull[]="";
DWORD CCdefs[16]={CBLACK,BLUE,GREEN,CYAN,RED,PINK,YELLOW,PALEGRAY,DARKGRAY,
DARKBLUE,DARKGREEN,DARKCYAN,DARKRED,DARKPINK,BROWN,CWHITE};
/* .... MOVE GENERATION VARIABLES AND INITIALIZATIONS .... */
SHORT distdata[64][64], taxidata[64][64];
#ifdef KILLT
/* put moves to the center first */
void
Initialize_killt (void)
{
register UTSHORT f, t, s;
register SHORT d;
for (f = 0; f < 64; f++)
for (t = 0; t < 64; t++)
{
d = taxidata[f][0x1b];
if (taxidata[f][0x1c] < d)
d = taxidata[f][0x1c];
if (taxidata[f][0x23] < d)
d = taxidata[f][0x23];
if (taxidata[f][0x24] < d)
d = taxidata[f][0x24];
s = d;
d = taxidata[t][0x1b];
if (taxidata[t][0x1c] < d)
d = taxidata[t][0x1c];
if (taxidata[t][0x23] < d)
d = taxidata[t][0x23];
if (taxidata[t][0x24] < d)
d = taxidata[t][0x24];
s -= d;
killt[(f << 8) | t] = s;
killt[(f << 8) | t | 0x80] = s;
}
}
#endif
void
Initialize_dist (void)
{
register SHORT a, b, d, di;
for (a = 0; a < 64; a++)
for (b = 0; b < 64; b++)
{
d = abs (column (a) - column (b));
di = abs (row (a) - row (b));
taxidata[a][b] = d + di;
distdata[a][b] = (d > di ? d : di);
}
#ifdef KILLT
Initialize_killt ();
#endif
}
const 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};
const SHORT Stcolor[64] =
{white, white, white, white, white, white, white, white,
white, white, white, white, white, white, white, white,
neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
neutral, neutral, neutral, neutral, neutral, neutral, neutral, neutral,
black, black, black, black, black, black, black, black,
black, black, black, black, black, black, black, black};
SHORT board[64], color[64];
/* given epsquare, from where can a pawn be taken? */
const SHORT epmove1[64] =
{0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 24, 25, 26, 27, 28, 29, 30,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 32, 33, 34, 35, 36, 37, 38,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63};
const SHORT epmove2[64] =
{0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
25, 26, 27, 28, 29, 30, 31, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
33, 34, 35, 36, 37, 38, 39, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63};
/*
* nextpos[piece][from-square] , nextdir[piece][from-square] gives vector of
* positions reachable from from-square in ppos with piece such that the
* sequence ppos = nextpos[piece][from-square]; pdir =
* nextdir[piece][from-square]; u = ppos[sq]; do { u = ppos[u]; if(color[u]
* != neutral) u = pdir[u]; } while (sq != u); will generate the sequence of
* all squares reachable from sq.
*
* If the path is blocked u = pdir[sq] will generate the continuation of the
* sequence in other directions.
*/
UCHAR nextpos[8][64][64];
UCHAR nextdir[8][64][64];
/*
* ptype is used to separate white and black pawns, like this; ptyp =
* ptype[side][piece] piece can be used directly in nextpos/nextdir when
* generating moves for pieces that are not black pawns.
*/
const SHORT ptype[2][8] =
{ { no_piece, pawn, knight, bishop, rook, queen, king, no_piece },
{ no_piece, bpawn, knight, bishop, rook, queen, king, no_piece } };
/* data used to generate nextpos/nextdir */
static const SHORT direc[8][8] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 10, 9, 11, 0, 0, 0, 0, 0 },
{ 8, -8, 12, -12, 19, -19, 21, -21 },
{ 9, 11, -9, -11, 0, 0, 0, 0 },
{ 1, 10, -1, -10, 0, 0, 0, 0 },
{ 1, 10, -1, -10, 9, 11, -9, -11 },
{ 1, 10, -1, -10, 9, 11, -9, -11 },
{ -10, -9, -11, 0, 0, 0, 0, 0 } };
static const SHORT max_steps[8] =
{0, 2, 1, 7, 7, 7, 1, 2};
static const SHORT nunmap[120] =
{
-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, 8, 9, 10, 11, 12, 13, 14, 15, -1,
-1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
-1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
-1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
-1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
-1, 48, 49, 50, 51, 52, 53, 54, 55, -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};
int InitFlag = false;
void
Initialize_moves (void)
/*
* This procedure pre-calculates all moves for every piece from every square.
* This data is stored in nextpos/nextdir and used later in the move
* generation routines.
*/
{
SHORT ptyp, po, p0, d, di, s, delta;
UCHAR *ppos, *pdir;
SHORT dest[8][8];
SHORT steps[8];
SHORT sorted[8];
for (ptyp = 0; ptyp < 8; ptyp++)
for (po = 0; po < 64; po++)
for (p0 = 0; p0 < 64; p0++)
{
nextpos[ptyp][po][p0] = (UCHAR) po;
nextdir[ptyp][po][p0] = (UCHAR) po;
}
for (ptyp = 1; ptyp < 8; ptyp++)
for (po = 21; po < 99; po++)
if (nunmap[po] >= 0)
{
ppos = nextpos[ptyp][nunmap[po]];
pdir = nextdir[ptyp][nunmap[po]];
/* dest is a function of direction and steps */
for (d = 0; d < 8; d++)
{
dest[d][0] = nunmap[po];
delta = direc[ptyp][d];
if (delta != 0)
{
p0 = po;
for (s = 0; s < max_steps[ptyp]; s++)
{
p0 = p0 + delta;
/*
* break if (off board) or (pawns only move two
* steps from home square)
*/
if ((nunmap[p0] < 0) || (((ptyp == pawn) || (ptyp == bpawn))
&& ((s > 0) && ((d > 0) || (Stboard[nunmap[po]] != pawn)))))
break;
else
dest[d][s] = nunmap[p0];
}
}
else
s = 0;
/*
* sort dest in number of steps order currently no sort
* is done due to compability with the move generation
* order in old gnu chess
*/
steps[d] = s;
for (di = d; s > 0 && di > 0; di--)
if (steps[sorted[di - 1]] == 0) /* should be: < s */
sorted[di] = sorted[di - 1];
else
break;
sorted[di] = d;
}
/*
* update nextpos/nextdir, pawns have two threads (capture
* and no capture)
*/
p0 = nunmap[po];
if (ptyp == pawn || ptyp == bpawn)
{
for (s = 0; s < steps[0]; s++)
{
ppos[p0] = (UCHAR) dest[0][s];
p0 = dest[0][s];
}
p0 = nunmap[po];
for (d = 1; d < 3; d++)
{
pdir[p0] = (UCHAR) dest[d][0];
p0 = dest[d][0];
}
}
else
{
pdir[p0] = (UCHAR) dest[sorted[0]][0];
for (d = 0; d < 8; d++)
for (s = 0; s < steps[sorted[d]]; s++)
{
ppos[p0] = (UCHAR) dest[sorted[d]][s];
p0 = dest[sorted[d]][s];
if (d < 7)
pdir[p0] = (UCHAR) dest[sorted[d + 1]][0];
/*
* else is already initialized
*/
}
}
}
}
void
NewGame (void)
/*
* Reset the board and other variables to start a new game.
*/
{
SHORT l;
#ifdef HAVE_GETTIMEOFDAY
struct timeval tv;
#endif
#ifdef CLIENT
if(GameCnt >0)ListGame();
fflush(stdout);
#endif
compptr = oppptr = 0;
stage = stage2 = -1; /* the game is not yet started */
notime = true;
if (flag.reverse)InvalidateRect(hWnd,0,true);
flag.illegal=flag.mate=flag.quit=flag.bothsides=flag.onemove=false;
flag.force=flag.back=flag.musttimeout=flag.reverse=false;
#ifdef DEBUG
flag.nott = flag.noft = flag.nocache = false;
#endif
computer = black;
opponent = white;
GenCnt = NodeCnt = et0 = epsquare = XCmore = 0;
xwndw = BXwindow;
if (!MaxSearchDepth)
MaxSearchDepth = MAXDEPTH - 1;
GameCnt = 0;
Game50 = 1;
hint = 0x0C14;
selected=0;
ZeroRPT ();
Developed[white] = Developed[black] = false;
castld[white] = castld[black] = false;
PawnThreat[0] = CptrFlag[0] = false;
Pscore[0] = Tscore[0] = 12000;
for (l = 0; l < TREE; l++)
Tree[l].f = Tree[l].t = 0;
if (!InitFlag)
InitHashCode((unsigned int)1);
for (l = 0; l < 64; l++)
{
board[l] = Stboard[l];
color[l] = Stcolor[l];
Mvboard[l] = 0;
}
InitializeStats ();
#ifdef HAVE_GETTIMEOFDAY
gettimeofday(&tv, NULL);
time0 = tv.tv_sec*100+tv.tv_usec/10000;
#else
time0 = GetTickCount();
#endif
ElapsedTime (1);
flag.regularstart = true;
Book = flag.usebook ? BOOKFAIL : 0;
TimeControl.clock[white] = TimeControl.clock[black] = 0;
SetTimeControl();
player^=1;
UpdateClocks();
player^=1;
UpdateClocks();
if (!InitFlag)
{
GetOpenings ();
#ifdef CACHE
etab[0] = (struct etable *)malloc(ETABLE*sizeof(struct etable));
etab[1] = (struct etable *)malloc(ETABLE*sizeof(struct etable));
if(etab[0] == NULL || etab[1] == NULL){ ShowMessage(CP[70]);Exit(1);}
#endif
#if ttblsz
Initialize_ttable();
#endif
InitFlag = true;
}
#if ttblsz
ZeroTTable(0);
#endif /* ttblsz */
#ifdef CACHE
memset ((CHAR *) etab[0], 0, ETABLE*sizeof(struct etable));
memset ((CHAR *) etab[1], 0, ETABLE*sizeof(struct etable));
#endif
#ifdef NODITHER
PCRASH = PCRASHS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -