module Evaluation.Evaluation (evaluatePosition, evaluatePositionBreakdown, evaluateExchange, evaluateMvvLva) where import AppPrelude import Evaluation.Material import Evaluation.Parameters import Evaluation.ScoreBreakdown import Models.Move import Models.Piece import Models.Position import Models.Score import MoveGen.MakeMove import MoveGen.PieceAttacks import MoveGen.PieceCaptures import MoveGen.PositionQueries import Utils.Board evaluatePosition :: Position -> Score evaluatePosition :: Position -> Int16 evaluatePosition = ScoreBreakdown -> Int16 forall a. EvalScore a => a -> Int16 evalScore (ScoreBreakdown -> Int16) -> (Position -> ScoreBreakdown) -> Position -> Int16 forall b c a. (b -> c) -> (a -> b) -> a -> c forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c . Position -> ScoreBreakdown evaluatePositionBreakdown evaluatePositionBreakdown :: Position -> ScoreBreakdown evaluatePositionBreakdown :: Position -> ScoreBreakdown evaluatePositionBreakdown Position pos = let !enemyPos :: Position enemyPos = Position -> Position makeNullMove Position pos !scoresBatch :: ScoresBatch scoresBatch = (?phase::Int16) => Position -> ScoresBatch Position -> ScoresBatch getScoresBatch Position pos !enemyScoresBatch :: ScoresBatch enemyScoresBatch = (?phase::Int16) => Position -> ScoresBatch Position -> ScoresBatch getScoresBatch Position enemyPos !playerBreakdown :: PlayerScoreBreakdown playerBreakdown = (?phase::Int16, ?colorToMove::Color) => ScoresBatch -> ScoresBatch -> Position -> PlayerScoreBreakdown ScoresBatch -> ScoresBatch -> Position -> PlayerScoreBreakdown evaluatePlayerBreakdown ScoresBatch scoresBatch ScoresBatch enemyScoresBatch Position pos !enemyBreakdown :: PlayerScoreBreakdown enemyBreakdown = (?phase::Int16, ?colorToMove::Color) => ScoresBatch -> ScoresBatch -> Position -> PlayerScoreBreakdown ScoresBatch -> ScoresBatch -> Position -> PlayerScoreBreakdown evaluatePlayerBreakdown ScoresBatch enemyScoresBatch ScoresBatch scoresBatch Position enemyPos !materialScore :: Int16 materialScore = MaterialBreakdown -> Int16 forall a. EvalScore a => a -> Int16 evalScore PlayerScoreBreakdown playerBreakdown.materialBreakdown Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a - MaterialBreakdown -> Int16 forall a. EvalScore a => a -> Int16 evalScore PlayerScoreBreakdown enemyBreakdown.materialBreakdown !materialTradesScore :: Int16 materialTradesScore = Int16 -> Position -> Int16 evaluateMaterialTrades Int16 materialScore Position pos in ScoreBreakdown {Int16 PlayerScoreBreakdown playerBreakdown :: PlayerScoreBreakdown enemyBreakdown :: PlayerScoreBreakdown materialTradesScore :: Int16 $sel:playerBreakdown:ScoreBreakdown :: PlayerScoreBreakdown $sel:enemyBreakdown:ScoreBreakdown :: PlayerScoreBreakdown $sel:materialTradesScore:ScoreBreakdown :: Int16 ..} where ?phase = Position pos.phase ?colorToMove = Position pos.color evaluatePlayerBreakdown :: (?phase :: Phase, ?colorToMove :: Color) => ScoresBatch -> ScoresBatch -> Position -> PlayerScoreBreakdown evaluatePlayerBreakdown :: (?phase::Int16, ?colorToMove::Color) => ScoresBatch -> ScoresBatch -> Position -> PlayerScoreBreakdown evaluatePlayerBreakdown ScoresBatch scoresBatch ScoresBatch enemyScoresBatch Position pos = PlayerScoreBreakdown { $sel:materialBreakdown:PlayerScoreBreakdown :: MaterialBreakdown materialBreakdown = (?phase::Int16) => Position -> Board -> Color -> MaterialBreakdown Position -> Board -> Color -> MaterialBreakdown evaluatePlayerMaterial Position pos Position pos.player Position pos.color , $sel:bonusBreakdown:PlayerScoreBreakdown :: BonusBreakdown bonusBreakdown = (?phase::Int16, ?colorToMove::Color) => ScoresBatch -> Position -> BonusBreakdown ScoresBatch -> Position -> BonusBreakdown evaluatePositionBonuses ScoresBatch scoresBatch Position pos , $sel:penaltyBreakdown:PlayerScoreBreakdown :: PenaltyBreakdown penaltyBreakdown = ScoresBatch -> ScoresBatch -> Position -> PenaltyBreakdown evaluatePositionPenalties ScoresBatch scoresBatch ScoresBatch enemyScoresBatch Position pos } evaluatePositionBonuses :: (?phase :: Phase, ?colorToMove :: Color) => ScoresBatch -> Position -> BonusBreakdown evaluatePositionBonuses :: (?phase::Int16, ?colorToMove::Color) => ScoresBatch -> Position -> BonusBreakdown evaluatePositionBonuses ScoresBatch {Int16 mobility :: Int16 threats :: Int16 kingThreats :: Int16 $sel:mobility:ScoresBatch :: ScoresBatch -> Int16 $sel:threats:ScoresBatch :: ScoresBatch -> Int16 $sel:kingThreats:ScoresBatch :: ScoresBatch -> Int16 ..} Position pos = BonusBreakdown { $sel:mobility:BonusBreakdown :: Int16 mobility = Int16 mobility , $sel:passedPawns:BonusBreakdown :: Int16 passedPawns = (?phase::Int16, ?colorToMove::Color) => Position -> Int16 Position -> Int16 evaluatePassedPawns Position pos , $sel:bishopPair:BonusBreakdown :: Int16 bishopPair = (?phase::Int16) => Position -> Int16 Position -> Int16 evaluateBishopPair Position pos , $sel:knightOutposts:BonusBreakdown :: Int16 knightOutposts = (?phase::Int16) => Position -> Int16 Position -> Int16 evaluateKnightOutposts Position pos , $sel:rooksOnOpenFile:BonusBreakdown :: Int16 rooksOnOpenFile = (?phase::Int16) => Position -> Int16 Position -> Int16 evaluateRooksOnOpenFiles Position pos , $sel:kingPawnShield:BonusBreakdown :: Int16 kingPawnShield = (?phase::Int16) => Position -> Int16 Position -> Int16 evaluateKingPawnShield Position pos , $sel:castlingRights:BonusBreakdown :: Int16 castlingRights = Position -> Int16 evaluateCastlingRights Position pos } evaluatePositionPenalties :: ScoresBatch -> ScoresBatch -> Position -> PenaltyBreakdown evaluatePositionPenalties :: ScoresBatch -> ScoresBatch -> Position -> PenaltyBreakdown evaluatePositionPenalties ScoresBatch {Int16 $sel:threats:ScoresBatch :: ScoresBatch -> Int16 threats :: Int16 threats} ScoresBatch {Int16 $sel:kingThreats:ScoresBatch :: ScoresBatch -> Int16 kingThreats :: Int16 kingThreats} Position {Board player :: Board $sel:player:Position :: Position -> Board player, Board pawns :: Board $sel:pawns:Position :: Position -> Board pawns} = PenaltyBreakdown { $sel:threats:PenaltyBreakdown :: Int16 threats = Int16 threats , $sel:kingThreats:PenaltyBreakdown :: Int16 kingThreats = Int16 kingThreats , $sel:isolatedPawns:PenaltyBreakdown :: Int16 isolatedPawns = Board -> Int16 evaluateIsolatedPawns (Board player Board -> Board -> Board & Board pawns) , $sel:doubledPawns:PenaltyBreakdown :: Int16 doubledPawns = Board -> Int16 evaluateDoubledPawns (Board player Board -> Board -> Board & Board pawns) } evaluateBishopPair :: (?phase :: Phase) => Position -> Score evaluateBishopPair :: (?phase::Int16) => Position -> Int16 evaluateBishopPair Position {Board $sel:player:Position :: Position -> Board player :: Board player, Board bishops :: Board $sel:bishops:Position :: Position -> Board bishops} = Int16 (?phase::Int16) => Int16 bishopPairBonus Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral ((Int, Int) -> Int -> Int forall a. Ord a => (a, a) -> a -> a clamp (Int 0, Int 1) (Board -> Int popCount (Board player Board -> Board -> Board & Board bishops) Int -> Int -> Int forall a. Num a => a -> a -> a - Int 1)) evaluateKnightOutposts :: (?phase :: Phase) => Position -> Score evaluateKnightOutposts :: (?phase::Int16) => Position -> Int16 evaluateKnightOutposts Position {Int16 [ZKey] Word8 Board Color $sel:player:Position :: Position -> Board $sel:pawns:Position :: Position -> Board $sel:bishops:Position :: Position -> Board previousPositions :: [ZKey] halfMoveClock :: Word8 phase :: Int16 color :: Color player :: Board enemy :: Board pawns :: Board knights :: Board bishops :: Board rooks :: Board queens :: Board kings :: Board enPassant :: Board castling :: Board attacked :: Board leapingCheckers :: Board sliderCheckers :: Board pinnedPieces :: Board $sel:previousPositions:Position :: Position -> [ZKey] $sel:halfMoveClock:Position :: Position -> Word8 $sel:phase:Position :: Position -> Int16 $sel:color:Position :: Position -> Color $sel:enemy:Position :: Position -> Board $sel:knights:Position :: Position -> Board $sel:rooks:Position :: Position -> Board $sel:queens:Position :: Position -> Board $sel:kings:Position :: Position -> Board $sel:enPassant:Position :: Position -> Board $sel:castling:Position :: Position -> Board $sel:attacked:Position :: Position -> Board $sel:leapingCheckers:Position :: Position -> Board $sel:sliderCheckers:Position :: Position -> Board $sel:pinnedPieces:Position :: Position -> Board ..} = Int16 (?phase::Int16) => Int16 knightOutpostBonus Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral (Board -> (Board -> Board -> Board) -> (Int -> Board) -> Board -> Board forall a b. a -> (a -> b -> a) -> (Int -> b) -> Board -> a foldlBoard Board 0 Board -> Board -> Board forall a. Num a => a -> a -> a (+) Int -> Board mapFn (Board knightsBoard -> Board -> Board &Board player Board -> Board -> Board & Board defended Board -> Board -> Board & Board ranks Board -> Board -> Board & Board knightOupostFiles)) where defended :: Board defended = Color -> Board -> Board pawnAttacks Color color (Board playerBoard -> Board -> Board &Board pawns) mapFn :: Int -> Board mapFn !Int n = Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Vector Board attackersVec Vector Board -> Int -> Board forall a. Storable a => Vector a -> Int -> a !! Int n Board -> Board -> Board & Board enemyBoard -> Board -> Board &Board pawns) (!Board ranks, !Vector Board attackersVec) = case Color color of Color White -> (Board whiteKnightOutpostRanks , Vector Board whiteKnightOutpostAttackersVec) Color Black -> (Board blackKnightOutpostRanks , Vector Board blackKnightOutpostAttackersVec) evaluateRooksOnOpenFiles :: (?phase :: Phase) => Position -> Score evaluateRooksOnOpenFiles :: (?phase::Int16) => Position -> Int16 evaluateRooksOnOpenFiles Position {Int16 [ZKey] Word8 Board Color $sel:player:Position :: Position -> Board $sel:pawns:Position :: Position -> Board $sel:bishops:Position :: Position -> Board $sel:previousPositions:Position :: Position -> [ZKey] $sel:halfMoveClock:Position :: Position -> Word8 $sel:phase:Position :: Position -> Int16 $sel:color:Position :: Position -> Color $sel:enemy:Position :: Position -> Board $sel:knights:Position :: Position -> Board $sel:rooks:Position :: Position -> Board $sel:queens:Position :: Position -> Board $sel:kings:Position :: Position -> Board $sel:enPassant:Position :: Position -> Board $sel:castling:Position :: Position -> Board $sel:attacked:Position :: Position -> Board $sel:leapingCheckers:Position :: Position -> Board $sel:sliderCheckers:Position :: Position -> Board $sel:pinnedPieces:Position :: Position -> Board previousPositions :: [ZKey] halfMoveClock :: Word8 phase :: Int16 color :: Color player :: Board enemy :: Board pawns :: Board knights :: Board bishops :: Board rooks :: Board queens :: Board kings :: Board enPassant :: Board castling :: Board attacked :: Board leapingCheckers :: Board sliderCheckers :: Board pinnedPieces :: Board ..} = Int16 (?phase::Int16) => Int16 rookOnSemiOpenFileBonus Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * (Board -> Int16 forall {a}. Num a => Board -> a eval Board file_A Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_B Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_C Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_D Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_E Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_F Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_G Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Board -> Int16 forall {a}. Num a => Board -> a eval Board file_H) where eval :: Board -> a eval Board fileBoard | Board playerRooksInFile Board -> Board -> Bool forall a. Eq a => a -> a -> Bool == Board 0 = a 0 | Board pawnsInFile Board -> Board -> Bool forall a. Eq a => a -> a -> Bool == Board 0 Bool -> Bool -> Bool || Board -> Int lastPieceSquare Board pawnsInFile Int -> Int -> Bool <! Int n = a 2 | Board playerPawnsInFile Board -> Board -> Bool forall a. Eq a => a -> a -> Bool == Board 0 Bool -> Bool -> Bool || Board -> Int lastPieceSquare Board playerPawnsInFile Int -> Int -> Bool <! Int n = a 1 | Bool otherwise = a 0 where playerRooksInFile :: Board playerRooksInFile = Board player Board -> Board -> Board & Board rooks Board -> Board -> Board & Board fileBoard playerPawnsInFile :: Board playerPawnsInFile = Board player Board -> Board -> Board & Board pawnsInFile pawnsInFile :: Board pawnsInFile = Board pawns Board -> Board -> Board & Board fileBoard n :: Int n = Board -> Int lastPieceSquare Board playerRooksInFile (!Int -> Int -> Bool (<!), !Board -> Int lastPieceSquare) = case Color color of Color White -> (Int -> Int -> Bool forall a. Ord a => a -> a -> Bool (<), Board -> Int msb) Color Black -> (Int -> Int -> Bool forall a. Ord a => a -> a -> Bool (>), Board -> Int lsb) evaluatePassedPawns :: (?phase :: Phase, ?colorToMove :: Color) => Position -> Score evaluatePassedPawns :: (?phase::Int16, ?colorToMove::Color) => Position -> Int16 evaluatePassedPawns pos :: Position pos@Position {Int16 [ZKey] Word8 Board Color $sel:player:Position :: Position -> Board $sel:pawns:Position :: Position -> Board $sel:bishops:Position :: Position -> Board $sel:previousPositions:Position :: Position -> [ZKey] $sel:halfMoveClock:Position :: Position -> Word8 $sel:phase:Position :: Position -> Int16 $sel:color:Position :: Position -> Color $sel:enemy:Position :: Position -> Board $sel:knights:Position :: Position -> Board $sel:rooks:Position :: Position -> Board $sel:queens:Position :: Position -> Board $sel:kings:Position :: Position -> Board $sel:enPassant:Position :: Position -> Board $sel:castling:Position :: Position -> Board $sel:attacked:Position :: Position -> Board $sel:leapingCheckers:Position :: Position -> Board $sel:sliderCheckers:Position :: Position -> Board $sel:pinnedPieces:Position :: Position -> Board previousPositions :: [ZKey] halfMoveClock :: Word8 phase :: Int16 color :: Color player :: Board enemy :: Board pawns :: Board knights :: Board bishops :: Board rooks :: Board queens :: Board kings :: Board enPassant :: Board castling :: Board attacked :: Board leapingCheckers :: Board sliderCheckers :: Board pinnedPieces :: Board ..} = (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_A Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_B Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_C Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_D Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_E Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_F Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_G Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + (?phase::Int16, ?colorToMove::Color) => Board -> Int16 Board -> Int16 eval Board file_H where eval :: Board -> Int16 eval Board fileBoard | Board pawnsInFile Board -> Board -> Bool forall a. Eq a => a -> a -> Bool == Board 0 Bool -> Bool -> Bool || Vector Board blockersVec Vector Board -> Int -> Board forall a. Storable a => Vector a -> Int -> a !! Int n Board -> Board -> Board & Board enemyBoard -> Board -> Board &Board pawns Board -> Board -> Bool forall a. Eq a => a -> a -> Bool /= Board 0 = Int16 0 | Bool otherwise = Int16 passerScore Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 escortedPasserScore where passerScore :: Int16 passerScore | (?colorToMove::Color) => Int -> Bool Int -> Bool isUnstoppablePawn Int n = Int16 unstoppablePawnBonus | Int -> Int -> Bool forall {p}. (Eq p, Num p) => p -> Int -> Bool isFreePasser Int rank Int n = Vector ScorePair freePassedPawnTable (?phase::Int16) => Vector ScorePair -> Int -> Int16 Vector ScorePair -> Int -> Int16 !!% Int rank | Bool otherwise = Vector ScorePair passedPawnTable (?phase::Int16) => Vector ScorePair -> Int -> Int16 Vector ScorePair -> Int -> Int16 !!% Int rank escortedPasserScore :: Int16 escortedPasserScore = Int16 (?phase::Int16) => Int16 kingEscortedPassedPawnBonus Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int -> Int -> Int getSquareDistance Int n Int enemyKingSquare Int -> Int -> Int forall a. Num a => a -> a -> a - Int -> Int -> Int getSquareDistance Int n Int kingSquare) rank :: Int rank = Int -> Int normalizeRank (Int -> Int) -> Int -> Int forall a b. (a -> b) -> a -> b $ Int -> Int toRank Int n pawnsInFile :: Board pawnsInFile = Board player Board -> Board -> Board & Board pawns Board -> Board -> Board & Board fileBoard n :: Int n = Board -> Int lastPawnSquare Board pawnsInFile kingSquare :: Int kingSquare = Board -> Int lsb (Board player Board -> Board -> Board & Board kings) enemyKingSquare :: Int enemyKingSquare = Board -> Int lsb (Board enemy Board -> Board -> Board & Board kings) isFreePasser :: p -> Int -> Bool isFreePasser p rank Int n = Board -> Int -> Bool testSquare Board noPieces (Int -> Int nextRank Int n) Bool -> Bool -> Bool && Move -> Position -> Int16 evaluateExchange (Piece -> Promotion -> Int -> Int -> Move Move Piece Pawn Promotion promotion Int n (Int -> Move) -> Int -> Move forall a b. (a -> b) -> a -> b $ Int -> Int nextRank Int n) Position pos Int16 -> Int16 -> Bool forall a. Ord a => a -> a -> Bool >= Int16 0 where promotion :: Promotion promotion | p rank p -> p -> Bool forall a. Eq a => a -> a -> Bool == p 7 = Promotion QueenProm | Bool otherwise = Promotion NoProm isUnstoppablePawn :: Int -> Bool isUnstoppablePawn Int pawnSquare = Board enemy Board -> Board -> Board & (Board knights Board -> Board -> Board .| Board bishops Board -> Board -> Board .| Board rooks Board -> Board -> Board .| Board queens) Board -> Board -> Bool forall a. Eq a => a -> a -> Bool == Board 0 Bool -> Bool -> Bool && Int kingDistance Int -> Int -> Bool forall a. Ord a => a -> a -> Bool > Int pawnDistance where pawnDistance :: Int pawnDistance = Int -> Int -> Int getSquareDistance Int pawnSquare Int promotionSquare kingDistance :: Int kingDistance = Int -> Int -> Int getSquareDistance Int kingSquare Int promotionSquare Int -> Int -> Int forall a. Num a => a -> a -> a - Int kingDistanceOffset promotionSquare :: Int promotionSquare = Int 8 Int -> Int -> Int forall a. Num a => a -> a -> a * Int promotionRank Int -> Int -> Int forall a. Num a => a -> a -> a + Int pawnFile pawnFile :: Int pawnFile = Int -> Int toFile Int pawnSquare kingSquare :: Int kingSquare = Board -> Int lsb (Board enemy Board -> Board -> Board & Board kings) kingDistanceOffset :: Int kingDistanceOffset | Color color Color -> Color -> Bool forall a. Eq a => a -> a -> Bool /= ?colorToMove::Color Color ?colorToMove = Int 1 | Bool otherwise = Int 0 (!Int -> Int normalizeRank, !Int -> Int nextRank, !Board -> Int lastPawnSquare, !Vector Board blockersVec, !Int promotionRank) = case Color color of Color White -> (Int -> Int forall a. a -> a forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a id , (Int -> Int -> Int forall a. Num a => a -> a -> a + Int 8) , Board -> Int msb, Vector Board whitePassedPawnBlockersVec, Int 7) Color Black -> ((Int 7 -), \Int n -> Int n Int -> Int -> Int forall a. Num a => a -> a -> a - Int 8, Board -> Int lsb, Vector Board blackPassedPawnBlockersVec, Int 0) !noPieces :: Board noPieces = Board -> Board (~) (Board player Board -> Board -> Board .| Board enemy) evaluateKingPawnShield :: (?phase :: Phase) => Position -> Score evaluateKingPawnShield :: (?phase::Int16) => Position -> Int16 evaluateKingPawnShield Position {Int16 [ZKey] Word8 Board Color $sel:player:Position :: Position -> Board $sel:pawns:Position :: Position -> Board $sel:bishops:Position :: Position -> Board $sel:previousPositions:Position :: Position -> [ZKey] $sel:halfMoveClock:Position :: Position -> Word8 $sel:phase:Position :: Position -> Int16 $sel:color:Position :: Position -> Color $sel:enemy:Position :: Position -> Board $sel:knights:Position :: Position -> Board $sel:rooks:Position :: Position -> Board $sel:queens:Position :: Position -> Board $sel:kings:Position :: Position -> Board $sel:enPassant:Position :: Position -> Board $sel:castling:Position :: Position -> Board $sel:attacked:Position :: Position -> Board $sel:leapingCheckers:Position :: Position -> Board $sel:sliderCheckers:Position :: Position -> Board $sel:pinnedPieces:Position :: Position -> Board previousPositions :: [ZKey] halfMoveClock :: Word8 phase :: Int16 color :: Color player :: Board enemy :: Board pawns :: Board knights :: Board bishops :: Board rooks :: Board queens :: Board kings :: Board enPassant :: Board castling :: Board attacked :: Board leapingCheckers :: Board sliderCheckers :: Board pinnedPieces :: Board ..} = Int16 -> (Board -> Int16) -> Maybe Board -> Int16 forall b a. b -> (a -> b) -> Maybe a -> b maybe Int16 0 (?phase::Int16) => Board -> Int16 Board -> Int16 go (Maybe Board -> Int16) -> Maybe Board -> Int16 forall a b. (a -> b) -> a -> b $ (Element [Board] -> Bool) -> [Board] -> Maybe (Element [Board]) forall seq. SemiSequence seq => (Element seq -> Bool) -> seq -> Maybe (Element seq) find ((Board -> Int -> Bool `testSquare` Int kingSquare) (Board -> Bool) -> (Board -> Board) -> Board -> Bool forall b c a. (b -> c) -> (a -> b) -> a -> c forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c . (Board kingRank &)) [Board shortCastleFiles, Board longCastleFiles] where go :: Board -> Int16 go Board board = Int16 (?phase::Int16) => Int16 pawnShield1RankBonus Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 popCountToScore (Board pawnShield1Rank Board -> Board -> Board & Board board Board -> Board -> Board & Board player Board -> Board -> Board & Board pawns) Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 (?phase::Int16) => Int16 pawnShield2RankBonus Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 popCountToScore (Board pawnShield2Rank Board -> Board -> Board & Board board Board -> Board -> Board & Board player Board -> Board -> Board & Board pawns) (Board kingRank, Board pawnShield1Rank, Board pawnShield2Rank) = case Color color of Color White -> (Board rank_1, Board rank_2, Board rank_3) Color Black -> (Board rank_8, Board rank_7, Board rank_6) kingSquare :: Int kingSquare = Board -> Int lsb (Board player Board -> Board -> Board & Board kings) evaluateCastlingRights :: Position -> Score evaluateCastlingRights :: Position -> Int16 evaluateCastlingRights Position{Board $sel:castling:Position :: Position -> Board castling :: Board castling} | Board castling Board -> Board -> Bool forall a. Eq a => a -> a -> Bool /= Board 0 = Int16 castlingRightsBonus | Bool otherwise = Int16 0 evaluateIsolatedPawns :: Board -> Score evaluateIsolatedPawns :: Board -> Int16 evaluateIsolatedPawns Board pawns = Int16 isolatedPawnPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral Board isolatedPawnsCount where isolatedPawnsCount :: Board isolatedPawnsCount = Board -> Board popCountToBoard (Board file_B Board -> Board -> Board & Board pawns) Board -> Board -> Board forall a. Num a => a -> a -> a * Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Board pawns Board -> Board -> Board & (Board file_A Board -> Board -> Board .| Board file_C)) Board -> Board -> Board forall a. Num a => a -> a -> a + Board -> Board popCountToBoard (Board file_C Board -> Board -> Board & Board pawns) Board -> Board -> Board forall a. Num a => a -> a -> a * Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Board pawns Board -> Board -> Board & (Board file_B Board -> Board -> Board .| Board file_D)) Board -> Board -> Board forall a. Num a => a -> a -> a + Board -> Board popCountToBoard (Board file_D Board -> Board -> Board & Board pawns) Board -> Board -> Board forall a. Num a => a -> a -> a * Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Board pawns Board -> Board -> Board & (Board file_C Board -> Board -> Board .| Board file_E)) Board -> Board -> Board forall a. Num a => a -> a -> a + Board -> Board popCountToBoard (Board file_E Board -> Board -> Board & Board pawns) Board -> Board -> Board forall a. Num a => a -> a -> a * Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Board pawns Board -> Board -> Board & (Board file_D Board -> Board -> Board .| Board file_F)) Board -> Board -> Board forall a. Num a => a -> a -> a + Board -> Board popCountToBoard (Board file_F Board -> Board -> Board & Board pawns) Board -> Board -> Board forall a. Num a => a -> a -> a * Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Board pawns Board -> Board -> Board & (Board file_E Board -> Board -> Board .| Board file_G)) Board -> Board -> Board forall a. Num a => a -> a -> a + Board -> Board popCountToBoard (Board file_G Board -> Board -> Board & Board pawns) Board -> Board -> Board forall a. Num a => a -> a -> a * Board -> Board forall a. (Num a, Ord a) => a -> a toReverseCondition (Board pawns Board -> Board -> Board & (Board file_F Board -> Board -> Board .| Board file_H)) evaluateDoubledPawns :: Board -> Score evaluateDoubledPawns :: Board -> Int16 evaluateDoubledPawns Board pawns = Int16 doubledPawnPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral Int doubledPawnsCount where doubledPawnsCount :: Int doubledPawnsCount = Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_A Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_B Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_C Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_D Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_E Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_F Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_G Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int -> Int forall a. Ord a => a -> a -> a max Int 1 (Board -> Int popCount (Board file_H Board -> Board -> Board & Board pawns)) Int -> Int -> Int forall a. Num a => a -> a -> a - Int 8 evaluateMaterialTrades :: Score -> Position -> Score evaluateMaterialTrades :: Int16 -> Position -> Int16 evaluateMaterialTrades Int16 materialScore Position {Int16 [ZKey] Word8 Board Color $sel:player:Position :: Position -> Board $sel:pawns:Position :: Position -> Board $sel:bishops:Position :: Position -> Board $sel:previousPositions:Position :: Position -> [ZKey] $sel:halfMoveClock:Position :: Position -> Word8 $sel:phase:Position :: Position -> Int16 $sel:color:Position :: Position -> Color $sel:enemy:Position :: Position -> Board $sel:knights:Position :: Position -> Board $sel:rooks:Position :: Position -> Board $sel:queens:Position :: Position -> Board $sel:kings:Position :: Position -> Board $sel:enPassant:Position :: Position -> Board $sel:castling:Position :: Position -> Board $sel:attacked:Position :: Position -> Board $sel:leapingCheckers:Position :: Position -> Board $sel:sliderCheckers:Position :: Position -> Board $sel:pinnedPieces:Position :: Position -> Board previousPositions :: [ZKey] halfMoveClock :: Word8 phase :: Int16 color :: Color player :: Board enemy :: Board pawns :: Board knights :: Board bishops :: Board rooks :: Board queens :: Board kings :: Board enPassant :: Board castling :: Board attacked :: Board leapingCheckers :: Board sliderCheckers :: Board pinnedPieces :: Board ..} = Int16 -> Int16 convert (Int16 losingPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a - Int16 winningPenalty) where losingPenalty :: Int16 losingPenalty = Int16 pieceTradesPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int16 losingMissingPieces Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int16 absoluteMaterialScore Int16 -> Int16 -> Int16 forall a. Integral a => a -> a -> a / Int16 700 winningPenalty :: Int16 winningPenalty = Int16 pawnTradesPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int16 winningMissingPawns Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int16 absoluteMaterialScore Int16 -> Int16 -> Int16 forall a. Integral a => a -> a -> a / Int16 800 losingMissingPieces :: Int16 losingMissingPieces = Int16 -> Int16 -> Int16 forall a. Ord a => a -> a -> a max Int16 0 (Int16 7 Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a - Board -> Int16 popCountToScore (Board losingBoard Board -> Board -> Board & (Board knights Board -> Board -> Board .| Board bishops Board -> Board -> Board .| Board rooks Board -> Board -> Board .| Board queens))) winningMissingPawns :: Int16 winningMissingPawns = Int16 8 Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a - Board -> Int16 popCountToScore (Board winningBoard Board -> Board -> Board & Board pawns) absoluteMaterialScore :: Int16 absoluteMaterialScore = Int16 -> Int16 forall a. Num a => a -> a abs Int16 materialScore (Board winningBoard, Board losingBoard, Int16 -> Int16 convert) | Int16 materialScore Int16 -> Int16 -> Bool forall a. Ord a => a -> a -> Bool > Int16 0 = (Board player, Board enemy , Int16 -> Int16 forall a. a -> a forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a id) | Bool otherwise = (Board enemy , Board player, Int16 -> Int16 forall a. Num a => a -> a negate) getScoresBatch :: (?phase :: Phase) => Position -> ScoresBatch getScoresBatch :: (?phase::Int16) => Position -> ScoresBatch getScoresBatch Position pos | Position -> Bool isKingInCheck Position pos = ScoresBatch emptyScoresBatch getScoresBatch Position {Int16 [ZKey] Word8 Board Color $sel:player:Position :: Position -> Board $sel:pawns:Position :: Position -> Board $sel:bishops:Position :: Position -> Board $sel:previousPositions:Position :: Position -> [ZKey] $sel:halfMoveClock:Position :: Position -> Word8 $sel:phase:Position :: Position -> Int16 $sel:color:Position :: Position -> Color $sel:enemy:Position :: Position -> Board $sel:knights:Position :: Position -> Board $sel:rooks:Position :: Position -> Board $sel:queens:Position :: Position -> Board $sel:kings:Position :: Position -> Board $sel:enPassant:Position :: Position -> Board $sel:castling:Position :: Position -> Board $sel:attacked:Position :: Position -> Board $sel:leapingCheckers:Position :: Position -> Board $sel:sliderCheckers:Position :: Position -> Board $sel:pinnedPieces:Position :: Position -> Board previousPositions :: [ZKey] halfMoveClock :: Word8 phase :: Int16 color :: Color player :: Board enemy :: Board pawns :: Board knights :: Board bishops :: Board rooks :: Board queens :: Board kings :: Board enPassant :: Board castling :: Board attacked :: Board leapingCheckers :: Board sliderCheckers :: Board pinnedPieces :: Board ..} = ScoresBatch {Int16 $sel:mobility:ScoresBatch :: Int16 $sel:threats:ScoresBatch :: Int16 $sel:kingThreats:ScoresBatch :: Int16 mobility :: Int16 kingThreats :: Int16 threats :: Int16 ..} where mobility :: Int16 mobility = Int16 knightsMobility Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 bishopsMobility Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 rooksMobility Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 queensMobility kingThreats :: Int16 kingThreats = (Vector Int16 kingThreatPiecesTable Vector Int16 -> Int -> Int16 forall a. Storable a => Vector a -> Int -> a !! Int piecesCount) Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int16 kingThreatScore Int16 -> Int16 -> Int16 forall a. Integral a => a -> a -> a / Int16 100 piecesCount :: Int piecesCount = Int knightsCount Int -> Int -> Int forall a. Num a => a -> a -> a + Int bishopsCount Int -> Int -> Int forall a. Num a => a -> a -> a + Int rooksCount Int -> Int -> Int forall a. Num a => a -> a -> a + Int queensCount threats :: Int16 threats = Int16 queenThreat Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 popCountToScore (Board player Board -> Board -> Board & Board queens Board -> Board -> Board & (Board minorDefended Board -> Board -> Board .| Board pawnDefended)) Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 rookThreat Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 popCountToScore (Board player Board -> Board -> Board & Board rooks Board -> Board -> Board & Board pawnDefended) Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 minorPieceThreat Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Board -> Int16 popCountToScore (Board player Board -> Board -> Board & (Board knights Board -> Board -> Board .| Board bishops) Board -> Board -> Board & Board pawnDefended) kingThreatScore :: Int16 kingThreatScore = Int16 threatByMinorPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int byKnightThreats Int -> Int -> Int forall a. Num a => a -> a -> a + Int byBishopThreats) Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 threatByRookPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral Int byRookThreats Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Int16 threatByQueenPenalty Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a * Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral Int byQueenThreats (Int16 knightsMobility, Int byKnightThreats, Int knightsCount) = (?phase::Int16) => Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) foldBoardScores Vector ScorePair knightMobilityTable Int -> Board knightAttacks Board pawnDefended (Board unpinnedBoard -> Board -> Board &Board knights) (Int16 bishopsMobility, Int byBishopThreats, Int bishopsCount) = (?phase::Int16) => Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) foldBoardScores Vector ScorePair bishopMobilityTable (Board -> Board -> Board -> Int -> Board bishopMoves (Board allPieces Board -> Board -> Board .\ Board player Board -> Board -> Board & Board queens) Board pinnedPieces Board king) Board pawnDefended (Board playerBoard -> Board -> Board &Board bishops) (Int16 rooksMobility, Int byRookThreats, Int rooksCount) = (?phase::Int16) => Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) foldBoardScores Vector ScorePair rookMobilityTable (Board -> Board -> Board -> Int -> Board rookMoves (Board allPieces Board -> Board -> Board .\ Board player Board -> Board -> Board & Board queens) Board pinnedPieces Board king) (Board pawnDefended Board -> Board -> Board .| Board minorDefended) (Board playerBoard -> Board -> Board &Board rooks) (Int16 queensMobility, Int byQueenThreats, Int queensCount) = (?phase::Int16) => Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) foldBoardScores Vector ScorePair queenMobilityTable (Board -> Board -> Board -> Int -> Board queenMoves Board allPieces Board pinnedPieces Board king) (Board pawnDefended Board -> Board -> Board .| Board minorDefended Board -> Board -> Board .| Board rookDefended) (Board playerBoard -> Board -> Board &Board queens) foldBoardScores :: Vector ScorePair -> (Int -> Board) -> Board -> Board -> (Int16, Int, Int) foldBoardScores !Vector ScorePair mobilityTable !Int -> Board movesFn !Board defended !Board board = (Int16, Int, Int) -> ((Int16, Int, Int) -> Board -> (Int16, Int, Int)) -> (Int -> Board) -> Board -> (Int16, Int, Int) forall a b. a -> (a -> b -> a) -> (Int -> b) -> Board -> a foldlBoard (Int16 0, Int 0, Int 0) (?phase::Int16) => (Int16, Int, Int) -> Board -> (Int16, Int, Int) (Int16, Int, Int) -> Board -> (Int16, Int, Int) foldFn Int -> Board movesFn Board board where foldFn :: (Int16, Int, Int) -> Board -> (Int16, Int, Int) foldFn (!Int16 x, !Int y, !Int z) !Board attackArea = (Int16 x Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a + Vector ScorePair mobilityTable (?phase::Int16) => Vector ScorePair -> Int -> Int16 Vector ScorePair -> Int -> Int16 !!% Board -> Int popCount (Board attackArea Board -> Board -> Board .\ (Board player Board -> Board -> Board .| Board defended)), Int y Int -> Int -> Int forall a. Num a => a -> a -> a + Int threatenedSquares, Int z Int -> Int -> Int forall a. Num a => a -> a -> a + Int -> Int forall a. (Ord a, Num a) => a -> a toCondition Int threatenedSquares) where !threatenedSquares :: Int threatenedSquares = Board -> Int popCount (Board enemyKingArea Board -> Board -> Board & Board attackArea) !king :: Board king = Board player Board -> Board -> Board & Board kings !unpinned :: Board unpinned = Board player Board -> Board -> Board .\ Board pinnedPieces !allPieces :: Board allPieces = Board player Board -> Board -> Board .| Board enemy !enemyKingArea :: Board enemyKingArea = Int -> Board kingAttacks (Board -> Int lsb (Board enemyBoard -> Board -> Board &Board kings)) !pawnDefended :: Board pawnDefended = Color -> Board -> Board pawnAttacks (Color -> Color reverseColor Color color) (Board enemyBoard -> Board -> Board &Board pawns) !minorDefended :: Board minorDefended = (Int -> Board) -> Board -> Board foldBoardAttacks Int -> Board knightAttacks (Board enemyBoard -> Board -> Board &Board knights) Board -> Board -> Board .| (Int -> Board) -> Board -> Board foldBoardAttacks (Board -> Int -> Board bishopAttacks Board allPieces) (Board enemyBoard -> Board -> Board &Board bishops) !rookDefended :: Board rookDefended = (Int -> Board) -> Board -> Board foldBoardAttacks (Board -> Int -> Board rookAttacks Board allPieces) (Board enemyBoard -> Board -> Board &Board rooks) evaluateExchange :: Move -> Position -> Score evaluateExchange :: Move -> Position -> Int16 evaluateExchange Move initialMv Position initialPos = let ?phase = Position initialPos.phase in (?phase::Int16) => Move -> Position -> Int16 Move -> Position -> Int16 go Move initialMv Position initialPos where !square :: Int square = Move initialMv.end go :: Move -> Position -> Int16 go !Move mv !Position pos = let newPos :: Position newPos = Move -> Position -> Position makeMove Move mv Position pos in (?phase::Int16) => Move -> Position -> Int16 Move -> Position -> Int16 evaluateCapturedPiece Move mv Position pos Int16 -> Int16 -> Int16 forall a. Num a => a -> a -> a - case [Move] -> Maybe (Element [Move]) forall mono. MonoFoldable mono => mono -> Maybe (Element mono) headMay ([Move] -> Maybe (Element [Move])) -> [Move] -> Maybe (Element [Move]) forall a b. (a -> b) -> a -> b $ Int -> Position -> [Move] staticExchangeCaptures Int square Position newPos of Just Element [Move] newMv -> Int16 -> Int16 -> Int16 forall a. Ord a => a -> a -> a max Int16 0 (Int16 -> Int16) -> Int16 -> Int16 forall a b. (a -> b) -> a -> b $! Move -> Position -> Int16 go Element [Move] Move newMv Position newPos Maybe (Element [Move]) Nothing -> Int16 0 {-# INLINE evaluateMvvLva #-} evaluateMvvLva :: Move -> Position -> Word8 evaluateMvvLva :: Move -> Position -> Word8 evaluateMvvLva Move {Int Promotion Piece piece :: Piece promotion :: Promotion start :: Int end :: Int $sel:piece:Move :: Move -> Piece $sel:promotion:Move :: Move -> Promotion $sel:start:Move :: Move -> Int $sel:end:Move :: Move -> Int ..} Position pos = Word8 promotionValue Word8 -> Word8 -> Word8 forall a. Num a => a -> a -> a + Word8 -> (Piece -> Word8) -> Maybe Piece -> Word8 forall b a. b -> (a -> b) -> Maybe a -> b maybe Word8 0 Piece -> Word8 exchangeValue (Int -> Position -> Maybe Piece maybeCapturedPieceAt Int end Position pos) where exchangeValue :: Piece -> Word8 exchangeValue Piece capturedPiece = Word8 10 Word8 -> Word8 -> Word8 forall a. Num a => a -> a -> a * (Piece -> Word8 getPieceValue Piece capturedPiece Word8 -> Word8 -> Word8 forall a. Num a => a -> a -> a + Word8 1) Word8 -> Word8 -> Word8 forall a. Num a => a -> a -> a - Piece -> Word8 getPieceValue Piece piece promotionValue :: Word8 promotionValue = Word8 10 Word8 -> Word8 -> Word8 forall a. Num a => a -> a -> a * (Word8 promotionPieceValue Word8 -> Word8 -> Word8 forall a. Num a => a -> a -> a + Word8 1) promotionPieceValue :: Word8 promotionPieceValue = case Promotion promotion of Promotion QueenProm -> Piece -> Word8 getPieceValue Piece Queen Promotion KnightProm -> Piece -> Word8 getPieceValue Piece Knight Promotion BishopProm -> Piece -> Word8 getPieceValue Piece Bishop Promotion RookProm -> Piece -> Word8 getPieceValue Piece Rook Promotion NoProm -> Word8 0 data ScoresBatch = ScoresBatch { ScoresBatch -> Int16 mobility :: Score , ScoresBatch -> Int16 threats :: Score , ScoresBatch -> Int16 kingThreats :: Score } emptyScoresBatch :: ScoresBatch emptyScoresBatch :: ScoresBatch emptyScoresBatch = ScoresBatch { $sel:mobility:ScoresBatch :: Int16 mobility = Int16 0 , $sel:threats:ScoresBatch :: Int16 threats = Int16 0 , $sel:kingThreats:ScoresBatch :: Int16 kingThreats = Int16 0 } popCountToScore :: Board -> Score popCountToScore :: Board -> Int16 popCountToScore = Int -> Int16 forall a b. (Integral a, Num b) => a -> b fromIntegral (Int -> Int16) -> (Board -> Int) -> Board -> Int16 forall b c a. (b -> c) -> (a -> b) -> a -> c forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c . Board -> Int popCount