-+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+ X if (board`5Bloc`5D == pawn) X `7B X pmtl`5Bcolor`5Bloc`5D`5D += value`5Bpawn`5D; X ++PawnCnt`5Bcolor`5Bloc`5D`5D`5Bcol`5Bloc`5D`5D; X `7D X if (board`5Bloc`5D == king) Index`5Bloc`5D = 0; X else Index`5Bloc`5D = ++PieceCnt`5Bcolor`5Bloc`5D`5D; X PieceList`5Bcolor`5Bloc`5D`5D`5BIndex`5Bloc`5D`5D = loc; X `7D X`7D X X Xsort(p1,p2) Xshort p1,p2; X`7B Xregister short p,p0,s; Xstruct leaf temp; X X s = 32000; X while (p1 < p2) X if (Tree`5Bp1`5D.score >= s) p1++; X else X `7B X s = Tree`5Bp1`5D.score; p0 = p1; X for (p = p1+1; p <= p2; p++) X if (Tree`5Bp`5D.score > s) X `7B X s = Tree`5Bp`5D.score; p0 = p; X `7D X temp = Tree`5Bp1`5D; Tree`5Bp1`5D = Tree`5Bp0`5D; Tree`5Bp0`5D = tem Vp; X p1++; X `7D X`7D X X Xrepetition(node) Xstruct leaf *node; X X/* X Check for draw by threefold repetition or 50 move rule. X*/ X X`7B Xregister short i,f,t,c; Xshort r,b`5B64`5D; Xunsigned short m; X r = c = 0; X#ifdef`09BSD X bzero((char *)b, sizeof b); X#else X memset(b,0,64*sizeof(short)); X#endif`09/* BSD */ X for (i = GameCnt; i > Game50; i--) X `7B X m = GameList`5Bi`5D; f = m>>8; t = m & 0xFF; X if (t != 255 && f != 255) X `7B X b`5Bf`5D++; b`5Bt`5D--; X if (b`5Bf`5D == 0) c--; else c++; X if (b`5Bt`5D == 0) c--; else c++; X if (c == 0) r++; X `7D X `7D X if (r == 1) X if (node->score > 0) node->score -= 20; X else node->score += 20; X if (GameCnt-Game50 > 99 `7C`7C r == 2) X `7B X node->score = 0; X node->flags `7C= exact; X node->flags `7C= draw; X `7D X`7D X X Xataks(side,a) Xshort side,a`5B`5D; X X/* X Place the lowest value piece attacking a square into array atak`5B`5D`5B V`5D. X*/ X X`7B Xregister short m,u,d,j; Xshort piece,i,m0,*aloc,*s; X`20 X#ifdef`09BSD X bzero((char *)a, sizeof a); X#else X a = (short *)memset(a,0,64*sizeof(short)); X#endif`09/* BSD */ X Dstart`5Bpawn`5D = Dstpwn`5Bside`5D; Dstop`5Bpawn`5D = Dstart`5Bpawn`5D + V 1; X aloc = &PieceList`5Bside`5D`5B0`5D; X for (i = 0; i <= PieceCnt`5Bside`5D; i++) X `7B X piece = board`5B*aloc`5D; m0 = map`5B*aloc`5D; X s = &svalue`5B*aloc`5D; *s = 0; X aloc++; X if (sweep`5Bpiece`5D) X for (j = Dstart`5Bpiece`5D; j <= Dstop`5Bpiece`5D; j++) X `7B X d = Dir`5Bj`5D; m = m0+d; u = unmap`5Bm`5D; X while (u >= 0) X `7B X *s += 2; X if (a`5Bu`5D == 0 `7C`7C piece < a`5Bu`5D) a`5Bu`5D = piece; X if (color`5Bu`5D == neutral) X `7B X m += d; u = unmap`5Bm`5D; X `7D X else u = -1; X `7D X `7D X else X `7B X for (j = Dstart`5Bpiece`5D; j <= Dstop`5Bpiece`5D; j++) X if ((u = unmap`5Bm0+Dir`5Bj`5D`5D) >= 0) X if (a`5Bu`5D == 0 `7C`7C piece < a`5Bu`5D) a`5Bu`5D = piece; X `7D X `7D X`7D X X `20 Xcastle(side,f,t,iop,ok) Xshort side,f,t,iop,*ok; X`7B Xshort i,e,k1,k2,r1,r2,c1,c2,t0,xside; X X xside = otherside`5Bside`5D; X if (side == white) e = 0; else e = 56; X if (f == 255) X `7B X k1 = e+4; k2 = e+6; r1 = e+7; r2 = e+5; c1 = k1; c2 = r1; X `7D X else X `7B X k1 = e+4; k2 = e+2; r1 = e; r2 = e+3; c1 = r1; c2 = k1; X `7D X if (iop == 0) X `7B X *ok = false; X if (board`5Bk1`5D == king && board`5Br1`5D == rook) *ok = true; X for (i = c1; i <= c2; i++) X if (atak`5Bxside`5D`5Bi`5D > 0) *ok = false;`20 X for (i = c1+1; i < c2; i++) X if (color`5Bi`5D != neutral) *ok = false; X `7D X else X `7B X if (iop == 1) castld`5Bside`5D = true; else castld`5Bside`5D = false; X if (iop == 2) X `7B X t0 = k1; k1 = k2; k2 = t0; X t0 = r1; r1 = r2; r2 = t0; X `7D X board`5Bk2`5D = king; color`5Bk2`5D = side; Index`5Bk2`5D = 0; X board`5Bk1`5D = no_piece; color`5Bk1`5D = neutral; X board`5Br2`5D = rook; color`5Br2`5D = side; Index`5Br2`5D = Index`5Br1 V`5D; X board`5Br1`5D = no_piece; color`5Br1`5D = neutral; X PieceList`5Bside`5D`5BIndex`5Bk2`5D`5D = k2; X PieceList`5Bside`5D`5BIndex`5Br2`5D`5D = r2; X `7D X`7D X X Xen_passant(side,xside,f,t,iop) Xshort side,f,t,iop; X`7B Xshort l; X if (t > f) l = t-8; else l = t+8; X if (iop == 1) X `7B X board`5Bl`5D = no_piece; color`5Bl`5D = neutral; X `7D X else`20 X `7B X board`5Bl`5D = pawn; color`5Bl`5D = xside; X `7D X InitializeStats(); X`7D X X XLinkMove(ply,f,t,side,xside) Xshort ply,f,t,side,xside; X`7B X X/* X Add a move to the tree. Assign a bonus (in an attempt to X improve move ordering) if move is a X principle variation, "killer", or capturing move. X*/ X Xregister short s; Xunsigned short mv; Xstruct leaf *node; X X node = &Tree`5BTrPnt`5Bply+1`5D`5D; X ++TrPnt`5Bply+1`5D; X node->flags = node->reply = 0; X node->f = f; node->t = t; mv = (f<<8) + t; X if (f == 255 `7C`7C t == 255) s = 100; X else X `7B X s = 0; X if (mv == PV) s = 150; X else if (mv == killr1`5Bply`5D) s = 90; X else if (mv == killr2`5Bply`5D) s = 70; X else if (mv == killr3`5Bply`5D) s = 50; X else if (mv == Swag1) s = 30; X else if (mv == Swag2) s = 20; X if (color`5Bt`5D != neutral) X `7B X node->flags `7C= capture; X if (t == xkillr) s += 400; X if (atak`5Bxside`5D`5Bt`5D == 0) s += value`5Bboard`5Bt`5D`5D-boar Vd`5Bf`5D; X else if (board`5Bt`5D > board`5Bf`5D) s += value`5Bboard`5Bt`5D`5D V-value`5Bboard`5Bf`5D`5D; X else s += 15; X `7D X if (board`5Bf`5D == pawn) X `7B X if (row`5Bt`5D == 0 `7C`7C row`5Bt`5D == 7) node->flags `7C= promo Vte; X else if (row`5Bt`5D == 1 `7C`7C row`5Bt`5D == 6) node->flags `7C= V pwnthrt; X else if (t == epsquare) node->flags `7C= epmask; X `7D X if (atak`5Bxside`5D`5Bf`5D > 0) s += 15; X if (atak`5Bxside`5D`5Bt`5D > 0) s -= 20; X if (InChk) X `7B X if (board`5Bf`5D == king && atak`5Bxside`5D`5Bt`5D == 0) s += 600; V `20 X if (mv == Qkillr`5Bply`5D) s += 100; X `7D X `7D X node->score = s-20000; X`7D X X XGenMoves(ply,loc,side,xside) Xshort ply,loc,side,xside; X X/* X Generate moves for a piece. The from square is mapped onto a 12 by`20 X 12 board and offsets (taken from array Dir`5B`5D) are added to the`20 X mapped location. Array unmap`5B`5D maps the move back onto array`20 X board`5B`5D (yielding a value of -1 if the to square is off the board). V`20 X This process is repeated for bishops, rooks, and queens until a`20 X piece is encountered or the the move falls off the board. Legal`20 X moves are then linked into the tree.`20 X*/ X `20 X`7B Xregister short m,u,d; Xshort i,m0,piece;`20 X X piece = board`5Bloc`5D; m0 = map`5Bloc`5D; X if (sweep`5Bpiece`5D) X `7B X for (i = Dstart`5Bpiece`5D; i <= Dstop`5Bpiece`5D; i++) X `7B X d = Dir`5Bi`5D; m = m0+d; u = unmap`5Bm`5D; X while (u >= 0) X if (color`5Bu`5D == neutral) X `7B X LinkMove(ply,loc,u,side,xside); X m += d; u = unmap`5Bm`5D; X `7D X else if (color`5Bu`5D == xside) X `7B X LinkMove(ply,loc,u,side,xside); X u = -1; X `7D X else u = -1; X `7D X `7D X else if (piece == pawn) X `7B X if (side == white && color`5Bloc+8`5D == neutral) X `7B X LinkMove(ply,loc,loc+8,side,xside); X if (row`5Bloc`5D == 1) X if (color`5Bloc+16`5D == neutral) X LinkMove(ply,loc,loc+16,side,xside); X `7D X else if (side == black && color`5Bloc-8`5D == neutral) X `7B X LinkMove(ply,loc,loc-8,side,xside); X if (row`5Bloc`5D == 6) X if (color`5Bloc-16`5D == neutral) X LinkMove(ply,loc,loc-16,side,xside); X `7D X for (i = Dstart`5Bpiece`5D; i <= Dstop`5Bpiece`5D; i++) X if ((u = unmap`5Bm0+Dir`5Bi`5D`5D) >= 0) X if (color`5Bu`5D == xside `7C`7C u == epsquare) X LinkMove(ply,loc,u,side,xside); X `7D X else X `7B X for (i = Dstart`5Bpiece`5D; i <= Dstop`5Bpiece`5D; i++) X if ((u = unmap`5Bm0+Dir`5Bi`5D`5D) >= 0) X if (color`5Bu`5D != side) X LinkMove(ply,loc,u,side,xside); X `7D X`7D X X X XMoveList(side,ply) Xshort side,ply; X X/* X Fill the array Tree`5B`5D with all available moves for side to X play. Array TrPnt`5Bply`5D contains the index into Tree`5B`5D X of the first move at a ply. X*/ X `20 X`7B Xregister short i; Xshort ok,xside; X X xside = otherside`5Bside`5D; X TrPnt`5Bply+1`5D = TrPnt`5Bply`5D; X Dstart`5Bpawn`5D = Dstpwn`5Bside`5D; Dstop`5Bpawn`5D = Dstart`5Bpawn`5D + V 1; X for (i = 0; i <= PieceCnt`5Bside`5D; i++) X GenMoves(ply,PieceList`5Bside`5D`5Bi`5D,side,xside); X if (kingmoved`5Bside`5D == 0) X `7B X castle(side,255,0,0,&ok); X if (ok) LinkMove(ply,255,0,side,xside); X castle(side,0,255,0,&ok); X if (ok) LinkMove(ply,0,255,side,xside); X `7D X sort(TrPnt`5Bply`5D,TrPnt`5Bply+1`5D-1); X`7D X X XMakeMove(side,node,tempb,tempc) Xshort side,*tempc,*tempb; Xstruct leaf *node; X X/* X Update Arrays board`5B`5D, color`5B`5D, and Index`5B`5D to reflect the n Vew X board position obtained after making the move pointed to by X node. Also update miscellaneous stuff that changes when a move X is made. X*/ X `20 X`7B Xregister short f,t; Xshort ok,xside; X X xside = otherside`5Bside`5D; X f = node->f; t = node->t; epsquare = -1; xkillr = t; X GameList`5B++GameCnt`5D = (f<<8) + t; X if (f == 255 `7C`7C t == 255) X `7B X GamePc`5BGameCnt`5D = no_piece; GameClr`5BGameCnt`5D = neutral; X castle(side,f,t,1,&ok); X `7D X else X `7B X *tempc = color`5Bt`5D; *tempb = board`5Bt`5D; X GamePc`5BGameCnt`5D = *tempb; GameClr`5BGameCnt`5D = *tempc; X if (*tempc != neutral) X `7B X UpdatePieceList(*tempc,t,1); X if (*tempb == pawn) --PawnCnt`5B*tempc`5D`5Bcol`5Bt`5D`5D; X if (board`5Bf`5D == pawn) X `7B X --PawnCnt`5Bside`5D`5Bcol`5Bf`5D`5D; X ++PawnCnt`5Bside`5D`5Bcol`5Bt`5D`5D; X `7D X mtl`5Bxside`5D -= value`5B*tempb`5D; X if (*tempb == pawn) pmtl`5Bxside`5D -= value`5Bpawn`5D; X `7D X color`5Bt`5D = color`5Bf`5D; board`5Bt`5D = board`5Bf`5D; X Index`5Bt`5D = Index`5Bf`5D; PieceList`5Bside`5D`5BIndex`5Bt`5D`5D = t V; X color`5Bf`5D = neutral; board`5Bf`5D = no_piece; X if (board`5Bt`5D == pawn) X if (t-f == 16) epsquare = f+8; X else if (f-t == 16) epsquare = f-8; X if (node->flags & promote) X `7B X board`5Bt`5D = queen; X mtl`5Bside`5D += value`5Bqueen`5D - value`5Bpawn`5D; X pmtl`5Bside`5D -= value`5Bpawn`5D; X `7D`20 X if (board`5Bt`5D == king) ++kingmoved`5Bside`5D; X if (node->flags & epmask) en_passant(side,xside,f,t,1); X `7D X`7D X X XUnmakeMove(side,node,tempb,tempc) Xshort side,*tempc,*tempb; Xstruct leaf *node; X X/* X Take back the move pointed to by node. X*/ X X`7B Xregister short f,t; Xshort ok,xside; X X xside = otherside`5Bside`5D; X f = node->f; t = node->t; epsquare = -1; X GameCnt--; X if (f == 255 `7C`7C t == 255) castle(side,f,t,2,&ok); X else X `7B X color`5Bf`5D = color`5Bt`5D; board`5Bf`5D = board`5Bt`5D; X Index`5Bf`5D = Index`5Bt`5D; PieceList`5Bside`5D`5BIndex`5Bf`5D`5D = f V; X color`5Bt`5D = *tempc; board`5Bt`5D = *tempb; X if (*tempc != neutral) X `7B X UpdatePieceList(*tempc,t,2); X if (*tempb == pawn) ++PawnCnt`5B*tempc`5D`5Bcol`5Bt`5D`5D; X if (board`5Bf`5D == pawn) X `7B X --PawnCnt`5Bside`5D`5Bcol`5Bt`5D`5D; X ++PawnCnt`5Bside`5D`5Bcol`5Bf`5D`5D; X `7D X mtl`5Bxside`5D += value`5B*tempb`5D; X if (*tempb == pawn) pmtl`5Bxside`5D += value`5Bpawn`5D; X `7D X if (node->flags & promote) X `7B X board`5Bf`5D = pawn; X mtl`5Bside`5D += value`5Bpawn`5D - value`5Bqueen`5D; X pmtl`5Bside`5D += value`5Bpawn`5D; X `7D`20 X if (board`5Bf`5D == king) --kingmoved`5Bside`5D; X if (node->flags & epmask) en_passant(side,xside,f,t,2); X `7D X`7D X X XLinkCapture(ply,f,t,ck) Xshort ply,f,t,ck; X`7B Xstruct leaf *node; X X node = &Tree`5BTrPnt`5Bply+1`5D`5D; X ++TrPnt`5Bply+1`5D; X node->flags = node->reply = 0; X node->f = f; node->t = t; X if (t == ykillr `7C`7C t == ck) node->score = value`5Bboard`5Bt`5D`5D-boar Vd`5Bf`5D; X else node->score = value`5Bboard`5Bt`5D`5D-value`5Bboard`5Bf`5D`5D; X`7D X X XCaptureList(side,xside,ply) Xshort side,xside,ply; X X/* X Generate a list of captures similiarly to GenMoves. X*/ X X`7B Xregister short m,u,d; Xshort i,j,m0,piece,ck,*aloc; X X ck = Ckillr`5Bside`5D & 0x00FF; X TrPnt`5Bply+1`5D = TrPnt`5Bply`5D; X Dstart`5Bpawn`5D = Dstpwn`5Bside`5D; Dstop`5Bpawn`5D = Dstart`5Bpawn`5D + V 1; X aloc = &PieceList`5Bside`5D`5B0`5D; X for (i = 0; i <= PieceCnt`5Bside`5D; i++) X `7B`20 X piece = board`5B*aloc`5D; m0 = map`5B*aloc`5D; X if (sweep`5Bpiece`5D) X for (j = Dstart`5Bpiece`5D; j <= Dstop`5Bpiece`5D; j++) X `7B X d = Dir`5Bj`5D; m = m0+d; u = unmap`5Bm`5D; X while (u >= 0) X if (color`5Bu`5D == neutral) X `7B X m += d; u = unmap`5Bm`5D; X `7D X else X `7B X if (color`5Bu`5D == xside) LinkCapture(ply,*aloc,u,ck); X u = -1; X `7D X `7D X else X for (j = Dstart`5Bpiece`5D; j <= Dstop`5Bpiece`5D; j++) +-+-+-+-+-+-+-+- END OF PART 3 +-+-+-+-+-+-+-+-