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)); }
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); }