📄 gnuchess.c
字号:
}ZeroTTable(){int i; if (hashflag) for (i = 0; i < ttblsz; i++) { ptbl = (ttable + i); ptbl->depth = 0; }}MoveList(side,ply)short side,ply;/* Fill the array Tree[] with all available moves for side to play. Array TrPnt[ply] contains the index into Tree[] of the first move at a ply. */ {register short i;short xside,f; xside = otherside[side]; if (PV == 0) Swag0 = killr0[ply]; else Swag0 = PV; Swag1 = killr1[ply]; Swag2 = killr2[ply]; Swag3 = killr3[ply]; Swag4 = 0; if (ply > 2) Swag4 = killr1[ply-2]; TrPnt[ply+1] = TrPnt[ply]; Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1; for (i = PieceCnt[side]; i >= 0; i--) GenMoves(ply,PieceList[side][i],side,xside); if (kingmoved[side] == 0 && !castld[side]) { f = PieceList[side][0]; if (castle(side,f,f+2,0)) { LinkMove(ply,f,f+2,xside); Tree[TrPnt[ply+1]-1].flags |= cstlmask; } if (castle(side,f,f-2,0)) { LinkMove(ply,f,f-2,xside); Tree[TrPnt[ply+1]-1].flags |= cstlmask; } }}#if (NEWMOVE < 11)GenMoves(ply,sq,side,xside)short ply,sq,side,xside;/* Generate moves for a piece. The from square is mapped onto a special board and offsets (taken from array Dir[]) are added to the mapped location. The newly generated square is tested to see if it falls off the board by ANDing the square with 88 HEX. Legal moves are linked into the tree. */ {register short m,u,d;short i,m0,piece; piece = board[sq]; m0 = map[sq]; if (sweep[piece]) for (i = Dstart[piece]; i <= Dstop[piece]; i++) { d = Dir[i]; m = m0+d; while (!(m & 0x88)) { u = unmap[m]; if (color[u] == neutral) { LinkMove(ply,sq,u,xside); m += d; } else if (color[u] == xside) { LinkMove(ply,sq,u,xside); break; } else break; } } else if (piece == pawn) { if (side == white && color[sq+8] == neutral) { LinkMove(ply,sq,sq+8,xside); if (row[sq] == 1) if (color[sq+16] == neutral) LinkMove(ply,sq,sq+16,xside); } else if (side == black && color[sq-8] == neutral) { LinkMove(ply,sq,sq-8,xside); if (row[sq] == 6) if (color[sq-16] == neutral) LinkMove(ply,sq,sq-16,xside); } for (i = Dstart[piece]; i <= Dstop[piece]; i++) if (!((m = m0+Dir[i]) & 0x88)) { u = unmap[m]; if (color[u] == xside || u == epsquare) LinkMove(ply,sq,u,xside); } } else { for (i = Dstart[piece]; i <= Dstop[piece]; i++) if (!((m = m0+Dir[i]) & 0x88)) { u = unmap[m]; if (color[u] != side) LinkMove(ply,sq,u,xside); } }}#endifLinkMove(ply,f,t,xside)short ply,f,t,xside;/* Add a move to the tree. Assign a bonus to order the moves as follows: 1. Principle variation 2. Capture of last moved piece 3. Other captures (major pieces first) 4. Killer moves 5. "history" killers */{register short s,z;unsigned short mv;struct leaf *node; node = &Tree[TrPnt[ply+1]]; ++TrPnt[ply+1]; node->flags = node->reply = 0; node->f = f; node->t = t; mv = (f<<8) + t; s = 0; if (mv == Swag0) s = 2000; else if (mv == Swag1) s = 60; else if (mv == Swag2) s = 50; else if (mv == Swag3) s = 40; else if (mv == Swag4) s = 30; if (color[t] != neutral) { node->flags |= capture; if (t == TOsquare) s += 500; s += value[board[t]] - board[f]; } if (board[f] == pawn) if (row[t] == 0 || row[t] == 7) { node->flags |= promote; s += 800; } else if (row[t] == 1 || row[t] == 6) { node->flags |= pwnthrt; s += 600; } else if (t == epsquare) node->flags |= epmask; z = (f<<6) + t; if (xside == white) z |= 0x1000; s += history[z]; node->score = s - 20000;}#if (NEWMOVE < 10)CaptureList(side,xside,ply)short side,xside,ply;/* Generate captures and Pawn promotions only.*/#define LinkCapture\{\ node->f = sq; node->t = u;\ node->reply = 0;\ node->flags = capture;\ node->score = value[board[u]] + svalue[board[u]] - piece;\ if (piece == pawn && (u < 8 || u > 55))\ {\ node->flags |= promote;\ node->score = valueQ;\ }\ ++node;\ ++TrPnt[ply+1];\}{register short m,u;short d,sq,i,j,j1,j2,m0,r7,d0,piece,*PL;struct leaf *node; TrPnt[ply+1] = TrPnt[ply]; node = &Tree[TrPnt[ply]]; Dstart[pawn] = Dpwn[side]; Dstop[pawn] = Dstart[pawn] + 1; if (side == white) { r7 = 6; d0 = 8; } else { r7 = 1; d0 = -8; } PL = PieceList[side]; for (i = 0; i <= PieceCnt[side]; i++) { sq = PL[i]; m0 = map[sq]; piece = board[sq]; j1 = Dstart[piece]; j2 = Dstop[piece]; if (sweep[piece]) for (j = j1; j <= j2; j++) { d = Dir[j]; m = m0+d; while (!(m & 0x88)) { u = unmap[m]; if (color[u] == neutral) m += d; else { if (color[u] == xside) LinkCapture; break; } } } else { for (j = j1; j <= j2; j++) if (!((m = m0+Dir[j]) & 0x88)) { u = unmap[m]; if (color[u] == xside) LinkCapture; } if (piece == pawn && row[sq] == r7) { u = sq+d0; if (color[u] == neutral) LinkCapture; } } }}#endif int castle(side,kf,kt,iop)short side,kf,kt,iop;/* Make or Unmake a castling move.*/{short rf,rt,d,t0,xside; xside = otherside[side]; if (kt > kf) { rf = kf+3; rt = kt-1; d = 1; } else { rf = kf-4; rt = kt+1; d = -1; } if (iop == 0) { if (board[kf] != king || board[rf] != rook || color[rf] != side) return(false); if (color[kt] != neutral || color[rt] != neutral) return(false); if (d == -1 && color[kt+d] != neutral) return(false); if (SqAtakd(kf,xside)) return(false); if (SqAtakd(kt,xside)) return(false); if (SqAtakd(kf+d,xside)) return(false); } else { if (iop == 1) castld[side] = true; else castld[side] = false; if (iop == 2) { t0 = kt; kt = kf; kf = t0; t0 = rt; rt = rf; rf = t0; } board[kt] = king; color[kt] = side; Pindex[kt] = 0; board[kf] = no_piece; color[kf] = neutral; board[rt] = rook; color[rt] = side; Pindex[rt] = Pindex[rf]; board[rf] = no_piece; color[rf] = neutral; PieceList[side][Pindex[kt]] = kt; PieceList[side][Pindex[rt]] = rt; if (hashflag) { UpdateHashbd(side,king,kf,kt); UpdateHashbd(side,rook,rf,rt); } } return(true);}EnPassant(xside,f,t,iop)short xside,f,t,iop;/* Make or unmake an en passant move.*/{short l; if (t > f) l = t-8; else l = t+8; if (iop == 1) { board[l] = no_piece; color[l] = neutral; } else { board[l] = pawn; color[l] = xside; } InitializeStats();}MakeMove(side,node,tempb,tempc,tempsf,tempst)short side,*tempc,*tempb,*tempsf,*tempst;struct leaf *node;/* 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;short xside,ct,cf; xside = otherside[side]; f = node->f; t = node->t; epsquare = -1; FROMsquare = f; TOsquare = t; INCscore = 0; GameList[++GameCnt].gmove = (f<<8) + t; if (node->flags & cstlmask) { GameList[GameCnt].piece = no_piece; GameList[GameCnt].color = side; castle(side,f,t,1); } else { *tempc = color[t]; *tempb = board[t]; *tempsf = svalue[f]; *tempst = svalue[t]; GameList[GameCnt].piece = *tempb; GameList[GameCnt].color = *tempc; if (*tempc != neutral) { UpdatePieceList(*tempc,t,1); if (*tempb == pawn) --PawnCnt[*tempc][column[t]]; if (board[f] == pawn) { --PawnCnt[side][column[f]]; ++PawnCnt[side][column[t]]; cf = column[f]; ct = column[t]; if (PawnCnt[side][ct] > 1+PawnCnt[side][cf]) INCscore -= 15; else if (PawnCnt[side][ct] < 1+PawnCnt[side][cf]) INCscore += 15; else if (ct == 0 || ct == 7 || PawnCnt[side][ct+ct-cf] == 0) INCscore -= 15; } mtl[xside] -= value[*tempb]; if (*tempb == pawn) pmtl[xside] -= valueP; if (hashflag) UpdateHashbd(xside,*tempb,-1,t); INCscore += *tempst; } 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] = queen; --PawnCnt[side][column[t]]; mtl[side] += valueQ - valueP; pmtl[side] -= valueP; HasQueen[side] = true; if (hashflag) { UpdateHashbd(side,pawn,f,-1); UpdateHashbd(side,queen,f,-1); } INCscore -= *tempsf; } if (board[t] == king) ++kingmoved[side]; if (node->flags & epmask) EnPassant(xside,f,t,1); else if (hashflag) UpdateHashbd(side,board[t],f,t); }}UnmakeMove(side,node,tempb,tempc,tempsf,tempst)short side,*tempc,*tempb,*tempsf,*tempst;struct leaf *node;/* Take back a move.*/{register short f,t;short xside; xside = otherside[side]; f = node->f; t = node->t; epsquare = -1; GameCnt--; if (node->flags & cstlmask) 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 - valueQ; pmtl[side] += valueP; if (hashflag) { UpdateHashbd(side,queen,-1,t); UpdateHashbd(side,pawn,-1,t); } } if (*tempc != neutral) { UpdatePieceList(*tempc,t,2); 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; if (hashflag) UpdateHashbd(xside,*tempb,-1,t); } if (board[f] == king) --kingmoved[side]; if (node->flags & epmask) EnPassant(xside,f,t,2); else if (hashflag) UpdateHashbd(side,board[f],f,t); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -