-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X if ((u = unmap`5Bm0+Dir`5Bj`5D`5D) >= 0) X if (color`5Bu`5D == xside) LinkCapture(ply,*aloc,u,ck); X aloc++; X `7D X sort(TrPnt`5Bply`5D,TrPnt`5Bply+1`5D-1); X`7D X X Xdistance(a,b) Xshort a,b; X`7B Xshort d1,d2; X X d1 = col`5Ba`5D-col`5Bb`5D; if (d1 < 0) d1 = -d1; X d2 = row`5Ba`5D-row`5Bb`5D; if (d2 < 0) d2 = -d2; X if (d1 > d2) return(d1); else return(d2); X`7D X X XScorePosition(side,score) Xshort side,*score; X X/* X Calculate a positional score for each piece as follows: X pawns: X material value : 100 pts X d,e file, not moved: -10 pts X & also blocked: -10 pts X doubled : -12 pts (each pawn) X isolated : -24 pts X backward : -8 pts X & attacked : -6 pts X passed : depends on rank, material balance, X position of opponents king, blocked X knights: X material value : 330 pts X centre proximity : array pknight`20 X bishops: X material value : 330 pts X discourage edges : array pbishop X mobility : +2 pts per move `20 X rooks: X material value : 500 pts X mobility : +2 pts per move X open file : +12 pts X half open : +6 pts X queen: X material value : 950 pts X king: X castled : `7E +10 pts (depends on material) X king moved : `7E -15 pts (depends on material) X adjacent pawn : +5 pts before endgame X attacks to : -5 pts each if more than 1 attack X adjacent square before endgame X pawn missing from : -10 pts before endgame X adjacent column X centre proximity : -2 pts before endgame, during endgame X switches to a bonus for center proximity X dependent on opponents control of adjacent X squares X `20 X "hung" pieces : -8 (1 hung piece) X -24 (more than 1) X*/ X X`7B Xregister short i,j,a; Xshort loc,e,m0,u,piece,wking,bking,cwking,cbking; Xshort r,db,dw,s,stage1,stage2,c1,c2,a1,a2; Xshort pscore`5B3`5D,xside,rank,column,in_square; X X xside = otherside`5Bside`5D; X pscore`5Bwhite`5D = pscore`5Bblack`5D = 0; X emtl`5Bwhite`5D = mtl`5Bwhite`5D - pmtl`5Bwhite`5D - value`5Bking`5D; X emtl`5Bblack`5D = mtl`5Bblack`5D - pmtl`5Bblack`5D - value`5Bking`5D; X wking = PieceList`5Bwhite`5D`5B0`5D; bking = PieceList`5Bblack`5D`5B0`5D; X cwking = col`5Bwking`5D; cbking = col`5Bbking`5D; X stage1 = 10 - (emtl`5Bwhite`5D+emtl`5Bblack`5D) / 670; X stage2 = (stage1*stage1) / 10; X X for (c1 = white; c1 <= black; c1++) X `7B X c2 = otherside`5Bc1`5D; X for (i = 0; i <= PieceCnt`5Bc1`5D; i++) X `7B X loc = PieceList`5Bc1`5D`5Bi`5D; piece = board`5Bloc`5D; X a1 = atak`5Bc1`5D`5Bloc`5D; a2 = atak`5Bc2`5D`5Bloc`5D; X rank = row`5Bloc`5D; column = col`5Bloc`5D; X s = svalue`5Bloc`5D; X X if (piece == pawn && c1 == white) X `7B X if (column == 3 `7C`7C column == 4) X if (rank == 1) X `7B X s -= 10; X if (color`5Bloc+8`5D == white) s -=10; X `7D X else if (rank == 4 && a1 == pawn) s += 8; X if (column-cwking > 1 `7C`7C cwking-column > 1) s += stage1*rank V; X if (PawnCnt`5Bwhite`5D`5Bcolumn`5D > 1) s -= 12; X if (column > 0 && PawnCnt`5Bwhite`5D`5Bcolumn-1`5D == 0 && X column < 7 && PawnCnt`5Bwhite`5D`5Bcolumn+1`5D == 0) s -= 24 V; X if (a1 != pawn && atak`5Bc1`5D`5Bloc+8`5D != pawn) X `7B X s -= 8; X if (a2 > 0) s -= 6; X `7D X if (PawnCnt`5Bblack`5D`5Bcolumn`5D == 0) X `7B X dw = distance(loc,wking); X db = distance(loc,bking); X s += stage2*(db-dw); X if (side == white) r = rank-1; else r = rank; X if (row`5Bbking`5D >= r && db < 8-r) in_square = true; X else in_square = false; X e = 0;`20 X for (a = loc+8; a < 64; a += 8) X if (atak`5Bblack`5D`5Ba`5D == pawn) a = 99; X else if (atak`5Bblack`5D`5Ba`5D > 0 `7C`7C color`5Ba`5D != V neutral) e = 1;`20 X if (a == 99) s += stage1*passed_pawn3`5Brank`5D; X else if (in_square `7C`7C e == 1) s += stage1*passed_pawn2`5 VBrank`5D; X else s += stage1*passed_pawn1`5Brank`5D; X `7D X `7D X else if (piece == pawn && c1 == black) X `7B X if (column == 3 `7C`7C column == 4) X if (rank == 6) X `7B X s -= 10; X if (color`5Bloc-8`5D == black) s -= 10; X `7D X else if (rank == 3 && a1 == pawn) s += 8; X if (column-cbking > 1 `7C`7C cbking-column > 1) s += stage1*(7-r Vank); X if (PawnCnt`5Bblack`5D`5Bcolumn`5D > 1) s -= 12; X if (column > 0 && PawnCnt`5Bblack`5D`5Bcolumn-1`5D == 0 && X column < 7 && PawnCnt`5Bblack`5D`5Bcolumn+1`5D == 0) s -= 24 V; X if (a1 != pawn && atak`5Bc1`5D`5Bloc-8`5D != pawn) X `7B X s -= 8; X if (a2 > 0) s -= 6; X `7D X if (PawnCnt`5Bwhite`5D`5Bcolumn`5D == 0) X `7B X dw = distance(loc,wking); X db = distance(loc,bking); X s += stage2*(dw-db); X if (side == black) r = rank+1; else r = rank; X if (row`5Bwking`5D <= r && dw < r+1) in_square = true; X else in_square = false; X e = 0;`20 X for (a = loc-8; a >= 0 ; a -= 8) X if (atak`5Bwhite`5D`5Ba`5D == pawn) a = -99; X else if (atak`5Bwhite`5D`5Ba`5D > 0 `7C`7C color`5Ba`5D != V neutral) e = 1;`20 X if (a == -99) s += stage1*passed_pawn3`5B7-rank`5D; X else if (in_square `7C`7C e == 1) s += stage1*passed_pawn2`5 VB7-rank`5D; X else s += stage1*passed_pawn1`5B7-rank`5D; X `7D X `7D X else if (piece == knight) X `7B X s = pknight`5Bloc`5D; X `7D X else if (piece == bishop) X `7B X s += pbishop`5Bloc`5D; X `7D X else if (piece == rook) X `7B X if (PawnCnt`5Bwhite`5D`5Bcolumn`5D == 0) s += 6; X if (PawnCnt`5Bblack`5D`5Bcolumn`5D == 0) s += 6; X `7D X else if (piece == queen) X `7B X s = s/3; X `7D X else if (piece == king) X `7B X m0 = map`5Bloc`5D; X if (castld`5Bc1`5D) s += (20/(stage1+1)); X else if (kingmoved`5Bc1`5D > 0) s -= (30/(stage1+1)); X if (emtl`5Bc1`5D > 1300) X `7B X s -= 2*edge`5Bloc`5D; a = 0; X for (j = Dstart`5Bking`5D; j <= Dstop`5Bking`5D; j++) X if ((u = unmap`5Bm0+Dir`5Bj`5D`5D) >= 0) X `7B X if (atak`5Bc2`5D`5Bu`5D > 0) a++; X if (board`5Bu`5D == pawn) s += 5; X `7D X if (a > 1) s -= 5*a;`20 X if (column > 0 && PawnCnt`5Bc1`5D`5Bcolumn-1`5D == 0) s -= 1 V0; X if (column < 7 && PawnCnt`5Bc1`5D`5Bcolumn+1`5D == 0) s -= 1 V0; X if (PawnCnt`5Bc1`5D`5Bcolumn`5D == 0) s -= 12; X `7D X else X `7B X e = edge`5Bloc`5D; X for (j = Dstart`5Bking`5D; j <= Dstop`5Bking`5D; j++) X if ((u=unmap`5Bm0+Dir`5Bj`5D`5D) >= 0) X if (atak`5Bc2`5D`5Bu`5D == 0) e += edge`5Bu`5D; X s += (e*((1300-emtl`5Bc1`5D)/100))/8; X `7D X if (mtl`5Bc1`5D<1000 && mtl`5Bc2`5D<1990 && distance(wking,bking V)==2 X && e<12) s -= 30; X `7D X if (a2 > 0 && (a1 == 0 `7C`7C a2 < piece)) ++hung`5Bc1`5D; X if (a2 > 0) s -= 3; X pscore`5Bc1`5D += s; svalue`5Bloc`5D = s; X `7D X `7D X if (hung`5Bside`5D > 1) pscore`5Bside`5D -= 12; X if (hung`5Bxside`5D == 1) pscore`5Bxside`5D -= 8; X if (hung`5Bxside`5D > 1) pscore`5Bxside`5D -= 24; X *score = mtl`5Bside`5D - mtl`5Bxside`5D + pscore`5Bside`5D - pscore`5Bxsid Ve`5D - 5; X if (*score > 0 && pmtl`5Bside`5D == 0 && emtl`5Bside`5D <= value`5Bbishop` V5D) X *score = 0; X if (*score < 0 && pmtl`5Bxside`5D == 0 && emtl`5Bxside`5D <= value`5Bbisho Vp`5D) X *score = 0; X`7D X X XCaptureSearch(side,xside,ply,depth,alpha,beta,qscore,best,bstline) Xshort side,xside,ply,depth,alpha,beta,qscore,*best; Xunsigned short bstline`5B`5D; X X/* X Perform alpha-beta search on captures up to 9 ply past X nominal search depth. X*/ X X`7B Xregister short j,f,t; Xshort v,q,pnt,tempb,tempc,pbst,sv; Xunsigned short nxtline`5B30`5D; Xstruct leaf *node; X X *best = -qscore; bstline`5Bply`5D = 0; X CaptureList(side,xside,ply); X pnt = TrPnt`5Bply`5D; pbst = 0; X while (pnt < TrPnt`5Bply+1`5D && *best <= beta) X `7B X node = &Tree`5Bpnt`5D; pnt++; X f = node->f; t = node->t; X v = value`5Bboard`5Bt`5D`5D-qscore+svalue`5Bt`5D;`20 X if (v > alpha) X `7B X if (board`5Bt`5D == king) node->score = 10000; X else if (depth == 1) node->score = v; X else X `7B X ykillr = t; NodeCnt++; X sv = svalue`5Bt`5D; svalue`5Bt`5D = svalue`5Bf`5D; X tempb = board`5Bt`5D; tempc = color`5Bt`5D; X UpdatePieceList(tempc,t,1); X board`5Bt`5D = board`5Bf`5D; color`5Bt`5D = color`5Bf`5D; X Index`5Bt`5D = Index`5Bf`5D; PieceList`5Bside`5D`5BIndex`5Bt`5 VD`5D = t; X board`5Bf`5D = no_piece; color`5Bf`5D = neutral; X CaptureSearch(xside,side,ply+1,depth-1,-beta,-alpha,v, X &q,nxtline); X node->score = -q; X board`5Bf`5D = board`5Bt`5D; color`5Bf`5D = color`5Bt`5D; X Index`5Bf`5D = Index`5Bt`5D; PieceList`5Bside`5D`5BIndex`5Bf`5 VD`5D = f; X board`5Bt`5D = tempb; color`5Bt`5D = tempc; X UpdatePieceList(xside,t,2); X svalue`5Bf`5D = svalue`5Bt`5D; svalue`5Bt`5D = sv; X `7D X if (node->score > *best) X `7B X pbst = pnt; X *best = node->score; X if (*best > alpha) alpha = *best; X for (j = ply; j < 30; j++) bstline`5Bj`5D = nxtline`5Bj`5D; X bstline`5Bply`5D = (f<<8) + t; X `7D`20 X `7D X `7D X if (pbst == 0) Ckillr`5Bside`5D = -1; X else Ckillr`5Bside`5D = (Tree`5Bpbst`5D.f<<8) + Tree`5Bpbst`5D.t; X`7D X X Xexpand(side,node,depth,ply,alpha,beta,nxtline) Xshort side,depth,alpha,beta,ply; Xunsigned short nxtline`5B`5D; Xstruct leaf *node; X X/* X Generate a score for current position by calling search routine X to generate opponents best response. X*/ X X`7B Xshort s,xside; Xstruct leaf *reply; X X xside = otherside`5Bside`5D; X nxtline`5Bply`5D = (node->f<<8) + node->t; X nxtline`5Bply+1`5D = node->reply; X search(xside,ply+1,depth-1,-beta,-alpha,nxtline); X if (!timeout) X `7B X reply = &Tree`5BTrPnt`5Bply+1`5D`5D; X s = -reply->score; X if (s >= alpha && s <= beta) node->score = s; X else if (s < alpha && s < node->score) node->score = s; X else if (s > beta && s > node->score) node->score = s; X if ((reply->flags & incheck) && !(node->flags & check)) X `7B X node->flags `7C= draw; node->score = 0; X `7D X if ((node->flags & draw) `7C`7C (node->score <= -9000) `7C`7C X (node->score >= 9000)) node->flags `7C= exact; X node->reply = nxtline`5Bply+1`5D; X `7D X`7D X X Xevaluate(side,node,ply,depth,alpha,beta,nxtline) Xshort side,ply,alpha,beta; Xunsigned short nxtline`5B`5D; Xstruct leaf *node; X X/* X See if either king is in check. If positional score estimate X passed forward from previous ply warrants, score the position. X If positional score is greater than alpha, perform CaptureSearch X to modify score based on ensuing capture sequence. X*/ X X`7B Xshort xside,s,x,t; X X hung`5Bwhite`5D = hung`5Bblack`5D = 0; X xside = otherside`5Bside`5D; X ataks(xside,atak`5Bxside`5D); X if (atak`5Bxside`5D`5BPieceList`5Bside`5D`5B0`5D`5D > 0) X `7B X node->score = ply-10000; X node->flags `7C= incheck; X node->flags `7C= exact; X `7D X else X `7B X ataks(side,atak`5Bside`5D); X if (atak`5Bside`5D`5BPieceList`5Bxside`5D`5B0`5D`5D) node->flags `7C= V check; X if (ply > Sdepth) t = 0; else t = 90; X s = -PPscore`5Bply-1`5D+mtl`5Bside`5D-mtl`5Bxside`5D; X if (s+t > alpha `7C`7C (node->flags & check) `7C`7C X (node->flags & pwnthrt)) ScorePosition(side,&s); X PPscore`5Bply`5D = s-mtl`5Bside`5D+mtl`5Bxside`5D; X if (s < alpha `7C`7C depth > 1) X `7B X if (node->score < -12000) node->score = s; X `7D X else X `7B X ykillr = xkillr; X CaptureSearch(xside,side,ply+1,9,-s-1,-alpha,s,&x,nxtline); X node->score = -x; X node->reply = nxtline`5Bply+1`5D; X `7D X repetition(node); X `7D X`7D X X Xsearch(side,ply,depth,alpha,beta,bstline) Xshort side,ply,depth,alpha,beta; Xunsigned short bstline`5B`5D; X X/* X Perform the main alpha-beta search. Extensions up to 3 ply X beyond the nominal iterative search depth MAY occur for checks, X check evasions, pawn promotion threats, and threats to multiple X pieces. `20 X*/ X X`7B Xregister short j; Xshort best,tempb,tempc,xside,pnt,pbst,hhh,d; Xunsigned short mv,nxtline`5B30`5D; Xstruct leaf *node; X X xside = otherside`5Bside`5D; X if (ply == 1) InChk = false; else InChk = ChkFlag`5Bply-1`5D; X PV = bstline`5Bply`5D; X if (ply < 3) X `7B X Swag1 = Swag2 = 0; X `7D X else X `7B X Swag1 = (Tree`5BTrPnt`5Bply-2`5D`5D.f<<8) + Tree`5BTrPnt`5Bply-2`5D`5D V.t; +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-