packages feed

hstzaar-0.9.2: src/AI/Eval.hs

{-# LANGUAGE BangPatterns #-}
--
-- Static evaluation functions for board positions
--
module AI.Eval (simple_val, full_val) where
import Board
import AI.Gametree


-- simple static board valuation (material score only)
simple_val :: Valuation Board
simple_val b = if null (nextMoves b) then lost else material b

-- better static board valuation (material and positional scores)
full_val :: Valuation Board
full_val b = if null (nextMoves b) then lost else material b + positional b 


-- score for a losing position
-- this should be strictly greater than minBound to avoid "boundary" issues
lost :: Int
lost = minBound`div`2
      
-- | 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