static PawnScore EvaluatePawns(Board b) { int[] eval = new int[2]; var fileMask = Board.FileMask; var returnVal = new PawnScore(); for (int side = 0; side < 2; side++) { ulong pawns = b.Pawns[side]; int xside = side ^ 1; ulong opponentPawns = b.Pawns[side ^ 1]; //evaluate file by file for (int i = 0; i < 8; i++) { returnVal.Files[side, i] = pawns & Board.FileMask[i]; returnVal.Files[xside, i] = opponentPawns & Board.FileMask[i]; //evaluate my doubled pawns if (returnVal.Files[side, i].Count() > 1) { //doubled pawns if (i > 0 && i < 7) //ignoring outside pawns //check for isolated doubled pawns { if ((pawns & Board.FileMask[i - 1]) == 0 && (pawns & Board.FileMask[i + 1]) == 0) { eval[side] += 4 * DoubledPawnPenalty; } else { eval[side] += 2 * DoubledPawnPenalty; } } } } //individual pawns var p = pawns; while (p > 0) { var pawnsq = p.BitScanForward(); p ^= BitMask.Mask[pawnsq]; //passed pawns if ((PassedPawnMask[side, pawnsq] & opponentPawns) == 0) { var distanceMultiplier = side == 1 ? pawnsq.Rank() : 8 - pawnsq.Rank(); eval[side] += PassedPawnBonus * distanceMultiplier; } //blocked pawns if (side == 0 && pawnsq > 7) { if ((b.AllPieces & BitMask.Mask[pawnsq - 8]) > 0) { eval[side] += BlockedPawnPenalty; } else if (side == 1 && pawnsq < 56) { if ((b.AllPieces & BitMask.Mask[pawnsq + 8]) > 0) { eval[side] += BlockedPawnPenalty; } } } } } returnVal.Eval = eval[b.SideToMove] - eval[b.SideToMove ^ 1]; return(returnVal); }
static int EvaluateKingSafety(Board b, PawnScore pawnScore) { int[] eval = new int[2]; for (int side = 0; side < 2; side++) { var xside = side ^ 1; if ((kingside & b.King[side]) > 0) { // if my king is on the kingside if ((b.Rooks[side] & Board.FileMask[7]) > 0) // if I have a rook in the corner { //if the opponent has a queen and rook on the board, evaluate castle status if ((b.Queens[xside] > 0) && (b.Rooks[xside] > 0)) { eval[side] += NotCastledPenalty; } } else { //king looks safely tucked //evaluate the pawns in front of my king for (int f = 5; f < 8; f++) { //if I have no pawns on the file if (pawnScore.Files[side, f] == 0) { eval[side] += OpenFileInFrontOfCastledKingPenalty; // //look for case where the opponent has an opening // //and a major piece, and has not castled in that direction // if (pawnScore.Files[xside, f] == 0 && //opponent has opened the file // ((b.Rooks[xside] | b.Queens[xside]) & Board.FileMask[f]) > 0 && //heavypiece // ((b.King[xside] & queenside) > 0))//opponents king is safely on the other side // { // //major probjem // eval[side] += KingUnderAttack; // } } } } } else if ((queenside & b.King[side]) > 0) { //my king is on the queenside if ((b.Rooks[side] & Board.FileMask[0]) > 0) //there is a rook in the corner { //if the opponent has a queen and rook on the board, evaluate castle status if ((b.Queens[xside] > 0) && (b.Rooks[xside] > 0)) { eval[side] += NotCastledPenalty; } } else { //king is tucked //evaluate the pawns in front of my king for (int f = 2; f >= 0; f--) { //if I have no pawns on the file if (pawnScore.Files[side, f] == 0) { eval[side] += OpenFileInFrontOfCastledKingPenalty; // //look for case where the opponent has an opening // //and a major piece, and has not castled in that direction // if (pawnScore.Files[xside, f] == 0 && //opponent has opened the file // ((b.Rooks[xside] | b.Queens[xside]) & kingside) > 0 && //heavypiece // ((b.King[xside] & kingside) > 0)) //opponents king is safely on the other side // { // //major probjem // eval[side] += KingUnderAttack; // } } } } } else { //king is in the middle of the board if ((b.Queens[xside] > 0) && (b.Rooks[xside] > 0)) { eval[side] += NotCastledPenalty; } } } return(eval[b.SideToMove] - eval[b.SideToMove ^ 1]); }