public static int Evaluate(BoardState board, int color, int openingPhase, int endingPhase) { var doubledRooks = 0; var rooksOnOpenFile = 0; var pairOfBishops = 0; var enemyColor = ColorOperations.Invert(color); var rooks = board.Pieces[color][Piece.Rook]; while (rooks != 0) { var lsb = BitOperations.GetLsb(rooks); var field = BitOperations.BitScan(lsb); rooks = BitOperations.PopLsb(rooks); var file = FilePatternGenerator.GetPattern(field) | lsb; var rooksOnFile = file & board.Pieces[color][Piece.Rook]; var friendlyPawnsOnFile = file & board.Pieces[color][Piece.Pawn]; var enemyPawnsOnFile = file & board.Pieces[enemyColor][Piece.Pawn]; if (BitOperations.Count(rooksOnFile) > 1) { // We don't assume that there will be more than two rooks - even if, then this color is probably anyway winning doubledRooks = 1; } if (friendlyPawnsOnFile == 0 && enemyPawnsOnFile == 0) { rooksOnOpenFile++; } } var bishops = board.Pieces[color][Piece.Bishop]; if (BitOperations.Count(bishops) > 1) { pairOfBishops = 1; } var doubledRooksOpeningScore = doubledRooks * EvaluationConstants.DoubledRooks; var doubledRooksAdjusted = TaperedEvaluation.AdjustToPhase(doubledRooksOpeningScore, 0, openingPhase, endingPhase); var rooksOnOpenFileOpeningScore = rooksOnOpenFile * EvaluationConstants.RookOnOpenFile; var rooksOnOpenFileAdjusted = TaperedEvaluation.AdjustToPhase(rooksOnOpenFileOpeningScore, 0, openingPhase, endingPhase); var pairOfBishopsOpeningScore = pairOfBishops * EvaluationConstants.PairOfBishops; var pairOfBishopsAdjusted = TaperedEvaluation.AdjustToPhase(pairOfBishopsOpeningScore, 0, openingPhase, endingPhase); return(doubledRooksAdjusted + rooksOnOpenFileAdjusted + pairOfBishopsAdjusted); }
public static int Evaluate(BoardState board, int color, int openingPhase, int endingPhase, ulong fieldsAttackedByEnemy) { var enemyColor = ColorOperations.Invert(color); var king = board.Pieces[color][Piece.King]; var kingField = BitOperations.BitScan(king); var kingPosition = Position.FromFieldIndex(kingField); var fieldsAroundKing = ForwardBoxPatternGenerator.GetPattern(color, kingField); var attackedFieldsAroundKing = fieldsAroundKing & fieldsAttackedByEnemy; var attackersCount = (int)BitOperations.Count(attackedFieldsAroundKing); var attackersCountOpeningScore = attackersCount * EvaluationConstants.KingInDanger; var pawnShieldOpeningScore = 0; var openFilesNextToKingScore = 0; if (board.CastlingDone[color]) { var pawnsNearKing = fieldsAroundKing & board.Pieces[color][Piece.Pawn]; var pawnShield = (int)BitOperations.Count(pawnsNearKing); pawnShieldOpeningScore = pawnShield * EvaluationConstants.PawnShield; var openFileCheckFrom = Math.Max(0, kingPosition.X - 1); var openFileCheckTo = Math.Min(7, kingPosition.X + 1); for (var file = openFileCheckFrom; file <= openFileCheckTo; file++) { if ((FilePatternGenerator.GetPatternForFile(7 - file) & board.Pieces[color][Piece.Pawn]) == 0) { openFilesNextToKingScore += EvaluationConstants.OpenFileNextToKing; } } } var openingScore = pawnShieldOpeningScore + attackersCountOpeningScore + openFilesNextToKingScore; return(TaperedEvaluation.AdjustToPhase(openingScore, 0, openingPhase, endingPhase)); }
public static MagicContainer[] GenerateRookAttacks(ulong[] keys = null) { var masks = new ulong[64]; var permutations = new ulong[64][]; var attacks = new ulong[64][]; for (var fieldIndex = 0; fieldIndex < 64; fieldIndex++) { masks[fieldIndex] = (FilePatternGenerator.GetPatternForField(fieldIndex) & ~BoardConstants.TopBottomEdge) | (RankPatternGenerator.GetPatternForField(fieldIndex) & ~BoardConstants.RightLeftEdge); permutations[fieldIndex] = new ulong[1 << MagicShifts.RookShifts[fieldIndex]]; attacks[fieldIndex] = new ulong[1 << MagicShifts.RookShifts[fieldIndex]]; for (var permutationIndex = 0; permutationIndex < permutations[fieldIndex].Length; permutationIndex++) { permutations[fieldIndex][permutationIndex] = PermutationsGenerator.GetPermutation(masks[fieldIndex], permutationIndex); attacks[fieldIndex][permutationIndex] = AttacksGenerator.GetFileRankAttacks(permutations[fieldIndex][permutationIndex], fieldIndex); } } return(_rookMagicArray = GenerateAttacks(masks, permutations, attacks, MagicShifts.RookShifts, keys)); }
private static (int openingScore, int endingScore) Evaluate(BoardState board, int color, int openingPhase, int endingPhase) { var doubledPawns = 0; var isolatedPawns = 0; var chainedPawns = 0; var passingPawns = 0; for (var file = 0; file < 8; file++) { var friendlyPawnsOnInnerMask = board.Pieces[color][Piece.Pawn] & FilePatternGenerator.GetPatternForFile(file); var friendlyPawnsOnOuterMask = board.Pieces[color][Piece.Pawn] & OuterFilesPatternGenerator.GetPatternForFile(file); var pawnsCount = BitOperations.Count(friendlyPawnsOnInnerMask); if (pawnsCount > 1) { doubledPawns += (int)(pawnsCount - 1); } if (friendlyPawnsOnInnerMask != 0) { if (friendlyPawnsOnOuterMask == 0) { isolatedPawns += (int)BitOperations.Count(pawnsCount); } } } var pieces = board.Pieces[color][Piece.Pawn]; while (pieces != 0) { var lsb = BitOperations.GetLsb(pieces); var field = BitOperations.BitScan(lsb); pieces = BitOperations.PopLsb(pieces); var chain = ChainPatternGenerator.GetPattern(field) & board.Pieces[color][Piece.Pawn]; if (chain != 0) { chainedPawns += (int)BitOperations.Count(chain); } if (board.IsFieldPassing(color, field)) { passingPawns++; } } var doubledPawnsOpeningScore = doubledPawns * EvaluationConstants.DoubledPawns[GamePhase.Opening]; var doubledPawnsEndingScore = doubledPawns * EvaluationConstants.DoubledPawns[GamePhase.Ending]; var isolatedPawnsOpeningScore = isolatedPawns * EvaluationConstants.IsolatedPawns[GamePhase.Opening]; var isolatedPawnsEndingScore = isolatedPawns * EvaluationConstants.IsolatedPawns[GamePhase.Ending]; var chainedPawnsOpeningScore = chainedPawns * EvaluationConstants.ChainedPawns[GamePhase.Opening]; var chainedPawnsEndingScore = chainedPawns * EvaluationConstants.ChainedPawns[GamePhase.Ending]; var passingPawnsOpeningScore = passingPawns * EvaluationConstants.PassingPawns[GamePhase.Opening]; var passingPawnsEndingScore = passingPawns * EvaluationConstants.PassingPawns[GamePhase.Ending]; var openingScore = doubledPawnsOpeningScore + isolatedPawnsOpeningScore + chainedPawnsOpeningScore + passingPawnsOpeningScore; var endingScore = doubledPawnsEndingScore + isolatedPawnsEndingScore + chainedPawnsEndingScore + passingPawnsEndingScore; return(openingScore, endingScore); }