hstzaar-0.9: src/AI/Eval.hs
{-# LANGUAGE BangPatterns #-}
-- Static evaluation functions for board positions
module AI.Eval where
import Board
import AI.Tree (infinity)
-- | Static board evaluation function
-- considers material and positional scores
eval1 :: Board -> Int
eval1 b
| null moves = -infinity
-- | any (==0) counts' = infinity -- this should *NOT* be necessary
| otherwise = material b + positional b
where moves = nextMoves b -- active player's moves
-- | Material score
-- * multiply sum of heights by counts
-- * height weights for kinds with lowest counts
material :: Board -> Int
{-# INLINE material #-}
material b = (sum [(30-n)*h | (n,h)<-zip counts heights] -
sum [(30-n)*h | (n,h)<-zip counts' heights'])
where
-- stacks counts by piece kinds for each player
counts = activeCounts b
counts'= inactiveCounts b
-- sum of heights by piece kinds
heights = activeHeights b
heights'= inactiveHeights b
-- | Positional score
-- for each kind, count opponent's pieces in each player's zone of control
positional :: Board -> Int
{-# INLINE positional #-}
positional b = (sum [pw*m`div`n | (n,m)<-zip counts' zoc_counts] -
sum [pw*m`div`n | (n,m)<-zip counts zoc_counts'])
where
counts = activeCounts b
counts'= inactiveCounts b
-- zone of control of each player
zoc = zoneOfControl (active b) (pieces b)
zoc'= zoneOfControl (inactive b) (pieces b)
-- count pieces in each zone of control
zoc_counts= countStacks (inactive b) zoc
zoc_counts'= countStacks (active b) zoc'
pw = 100