📄 search.c
字号:
if (PutInTTable (side, best, depth, ply, alpha, beta, mv)
&& hashfile && (depth > HashDepth) && (GameCnt < HashMoveLimit))
{
PutInFTable (side, best, depth, ply, alpha, beta, node->f, node->t);
}
}
#endif /* ttblsz */
if (depth > 0)
{
#ifdef HISTORY
j = (node->f << 8) | node->t;
if (side == black)
j |= 0x4000;
if (history[j] < HISTORYLIM)
history[j] |= (unsigned short) 1 << depth;
#endif
if (node->t != (SHORT) (GameList[GameCnt].gmove & 0xFF))
if (best > beta && mv != killr1[ply])
{
killr2[ply] = killr1[ply];
killr1[ply] = mv;
}
killr0[ply] = ((best > 9000) ? mv : 0);
}
DepthBeyond -= extdb;
return (best);
}
int
castle (SHORT side, SHORT kf, SHORT kt, SHORT iop)
/* Make or Unmake a castling move. */
{
register SHORT rf, rt, t0, xside;
xside = side ^ 1;
if (kt > kf)
{
rf = kf + 3;
rt = kt - 1;
}
else
{
rf = kf - 4;
rt = kt + 1;
}
if (iop == 0)
{
if (kf != kingP[side] ||
board[kf] != king ||
board[rf] != rook ||
color[kf] != side ||
color[rf] != side ||
Mvboard[kf] != 0 ||
Mvboard[rf] != 0 ||
color[kt] != neutral ||
color[rt] != neutral ||
color[kt - 1] != neutral ||
SqAtakd (kf, xside) ||
SqAtakd (kt, xside) ||
SqAtakd (rt, xside))
return (false);
}
else
{
if (iop == 1)
{
castld[side] = true;
Mvboard[kf]++;
Mvboard[rf]++;
}
else
{
castld[side] = false;
Mvboard[kf]--;
Mvboard[rf]--;
t0 = kt;
kt = kf;
kf = t0;
t0 = rt;
rt = rf;
rf = t0;
}
board[kt] = king;
color[rt] = color[kt] = side;
Pindex[kt] = 0;
board[kf] = no_piece;
color[rf] = color[kf] = neutral;
board[rt] = rook;
Pindex[rt] = Pindex[rf];
board[rf] = no_piece;
PieceList[side][Pindex[kt]] = kt;
PieceList[side][Pindex[rt]] = rt;
UpdateHashbd (side, king, kf);
UpdateHashbd (side, king, kt);
UpdateHashbd (side, rook, rf);
UpdateHashbd (side, rook, rt);
}
return (true);
}
void
EnPassant (SHORT xside, SHORT f, SHORT t, SHORT iop)
/*
* Make or unmake an en passant move.
*/
{
register SHORT l;
l = t + ((t > f) ? -8 : 8);
if (iop == 1)
{
board[l] = no_piece;
color[l] = neutral;
}
else
{
board[l] = pawn;
color[l] = xside;
}
InitializeStats ();
}
void
UpdatePieceList (SHORT side, SHORT sq, SHORT iop,short piece)
/*
* Update the PieceList and Pindex arrays when a piece is captured or when a
* capture is unmade.
*/
{
register SHORT i;
if (iop == 1)
{
i = Pindex[sq];
if (i < PieceCnt[side])
{
PieceList[side][i] = PieceList[side][PieceCnt[side]];
Pindex[PieceList[side][i]] = i;
}
PieceCnt[ side ]--;
}
else
{
if (piece != king)
{
PieceCnt[side]++;
PieceList[side][PieceCnt[side]] = sq;
Pindex[sq] = PieceCnt[side];
}
else
{
PieceCnt[side]++;
for (i = PieceCnt[side]; i > 0; i--)
{
PieceList[side][i] = PieceList[side][i - 1];
Pindex[PieceList[side][i]] = i;
}
PieceList[side][0] = sq;
Pindex[sq] = 0;
}
}
}
void
MakeMove (SHORT side,
struct leaf *node,
SHORT *tempb, /* color of to square */
SHORT *tempc, /* piece at to square */
SHORT *tempsf, /* static value of piece on from */
SHORT *tempst) /* static value of piece on to */
/*
* Update Arrays board[], color[], and Pindex[] to reflect the new board
* position obtained after making the move pointed to by node. Also update
* miscellaneous stuff that changes when a move is made.
*/
{
register SHORT f, t, xside, ct, cf;
register struct GameRec *g;
xside = side ^ 1;
g = &GameList[++GameCnt];
g->hashkey = hashkey;
g->hashbd = hashbd;
g->epssq = epsquare;
f = node->f;
t = node->t;
epsquare = -1;
/* FROMsquare = f;*/
TOsquare = t;
INCscore = 0;
g->Game50 = Game50;
g->gmove = (f << 8) | t;
g->flags = node->flags;
if (node->flags & cstlmask)
{
g->piece = no_piece;
g->color = side;
(void) castle (side, f, t, 1);
Game50 = GameCnt;
}
else
{
if (!(node->flags & capture) && (board[f] != pawn))
{ IncrementRPThash(side,hashkey); }
else
Game50 = GameCnt;
*tempsf = svalue[f];
*tempst = svalue[t];
g->piece = *tempb = board[t];
g->color = *tempc = color[t];
if (*tempc != neutral)
{
UpdatePieceList (*tempc, t, 1,*tempb);
/* if capture decrement pawn count */
if (*tempb == pawn)
{
--PawnCnt[*tempc][column (t)];
}
if (board[f] == pawn)
{
cf = column (f);
ct = column (t);
/* move count from from to to */
--PawnCnt[side][cf];
++PawnCnt[side][ct];
/*
* calculate increment for pawn structure
* changes
*/
/* doubled or more - */
if (PawnCnt[side][ct] > (1 + PawnCnt[side][cf]))
INCscore -= 15;
/* went to empty column + */
else if (PawnCnt[side][ct] < 1 + PawnCnt[side][cf])
INCscore += 15;
/*
* went to outside col or empty col on one
* side ????????
*/
else if (ct == 0 || ct == 7 || PawnCnt[side][ct + ct - cf] == 0)
INCscore -= 15;
}
mtl[xside] -= value[*tempb];
if (*tempb == pawn)
pmtl[xside] -= valueP;
UpdateHashbd (xside, *tempb, t);
INCscore += *tempst;
Mvboard[t]++;
}
color[t] = color[f];
board[t] = board[f];
svalue[t] = svalue[f];
Pindex[t] = Pindex[f];
PieceList[side][Pindex[t]] = t;
color[f] = neutral;
board[f] = no_piece;
if (board[t] == pawn)
if (t - f == 16)
epsquare = f + 8;
else if (f - t == 16)
epsquare = f - 8;
if (node->flags & promote)
{
board[t] = node->flags & pmask;
--PawnCnt[side][column (t)];
mtl[side] += value[board[t]] - valueP;
pmtl[side] -= valueP;
UpdateHashbd (side, pawn, f);
UpdateHashbd (side, board[t], f);
INCscore -= *tempsf;
}
if (node->flags & epmask)
EnPassant (xside, f, t, 1);
else
{
UpdateHashbd (side, board[t], f);
UpdateHashbd (side, board[t], t);
}
Mvboard[f]++;
}
if (flag.animate && (flag.bothsides || player==computer))
{
UpdateDisplay(node->f,node->t,0,node->flags,0);
flag.searching=true;
CheckMessage();
flag.searching=false;
}
}
void
UnmakeMove (SHORT side,
struct leaf *node,
SHORT *tempb, /* -> piece */
SHORT *tempc, /* -> side */
SHORT *tempsf,
SHORT *tempst)
/*
* Take back a move.
*/
{
register SHORT f, t, xside;
xside = side ^ 1;
f = node->f;
t = node->t;
Game50 = GameList[GameCnt].Game50;
if (node->flags & cstlmask)
(void) castle (side, f, t, 2);
else
{
color[f] = color[t];
board[f] = board[t];
svalue[f] = *tempsf;
Pindex[f] = Pindex[t];
PieceList[side][Pindex[f]] = f;
color[t] = *tempc;
board[t] = *tempb;
svalue[t] = *tempst;
if (node->flags & promote)
{
board[f] = pawn;
++PawnCnt[side][column (t)];
mtl[side] += valueP - value[node->flags & pmask];
pmtl[side] += valueP;
UpdateHashbd (side, (SHORT) node->flags & pmask, t);
UpdateHashbd (side, pawn, t);
}
if (*tempc != neutral)
{
UpdatePieceList (*tempc, t, 2,*tempb);
if (*tempb == pawn)
{
++PawnCnt[*tempc][column (t)];
}
if (board[f] == pawn)
{
--PawnCnt[side][column (t)];
++PawnCnt[side][column (f)];
}
mtl[xside] += value[*tempb];
if (*tempb == pawn)
pmtl[xside] += valueP;
UpdateHashbd (xside, *tempb, t);
Mvboard[t]--;
}
if (node->flags & epmask)
{
EnPassant (xside, f, t, 2);
}
else
{
UpdateHashbd (side, board[f], f);
UpdateHashbd (side, board[f], t);
}
Mvboard[f]--;
if (!(node->flags & capture) && (board[f] != pawn))
{ DecrementRPThash(side,hashkey); }
}
epsquare = GameList[GameCnt--].epssq;
if (flag.animate) UpdateDisplay(node->f,node->t,0,node->flags,0);
}
void
InitializeStats (void)
/*
* Scan thru the board seeing what's on each square. If a piece is found,
* update the variables PieceCnt, PawnCnt, Pindex and PieceList. Also
* determine the material for each side and set the hashkey and hashbd
* variables to represent the current board position. Array
* PieceList[side][indx] contains the location of all the pieces of either
* side. Array Pindex[sq] contains the indx into PieceList for a given
* square.
*/
{
register SHORT i, sq;
epsquare = -1;
for (i = 0; i < 8; i++)
{
PawnCnt[white][i] = PawnCnt[black][i] = 0;
}
mtl[white] = mtl[black] = pmtl[white] = pmtl[black] = 0;
PieceCnt[white] = PieceCnt[black] = 0;
hashbd = hashkey = 0;
for (sq = 0; sq < 64; sq++)
if (color[sq] != neutral)
{
mtl[color[sq]] += value[board[sq]];
if (board[sq] == pawn)
{
pmtl[color[sq]] += valueP;
++PawnCnt[color[sq]][column (sq)];
}
Pindex[sq] = ((board[sq] == king) ? 0 : ++PieceCnt[color[sq]]);
PieceList[color[sq]][Pindex[sq]] = sq;
UpdateHashbd(color[sq], board[sq], sq);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -