packages feed

htzaar-0.0.2: src/AI/Utils.hs

-- | Utilities for AI players.
module AI.Utils
  ( winNext
  , boardHeuristic
  , pruneBoardTree
  ) where

import Data.Function
import Data.List

import Board

-- | Searches BoardTree to a depth of 1 looking for a guaranteed win.
winNext :: Strategy -> Strategy
winNext s (BoardTree a b branches) = s $ BoardTree a b $ if null winning then branches else [head winning]
  where
  winning = [ (t, b) | (t, b@(BoardTree _ _ [])) <- branches ]

-- | Applies board heuristic to all next board states.  Selects the turn at achieves the board with the lowest cost function.
boardHeuristic :: Ord a => (Board -> a) -> Strategy
boardHeuristic cost (BoardTree _ _ branches) g = (optimalTurn, g)
  where
  turns = [ (t, cost board) | (t, BoardTree _ board _) <- branches ]
  (optimalTurn, _) = minimumBy (compare `on` snd) turns

-- | Prunes the board tree with a board predicate.  If pruning removes all turns, no pruning is done.
pruneBoardTree :: (Board -> Bool) -> BoardTree -> BoardTree
pruneBoardTree f bt@(BoardTree a b branches) = if null branches' then bt else BoardTree a b branches'
  where
  branches' = [ (t, bt) | (t, bt@(BoardTree _ b _)) <- branches, f b ]



  {-
  losing  = [ t | (t, (BoardTree _ _ branches)) <- branches, (_, (BoardTree _ _ [])) <- branches ]
  branches1 = if not $ null winning
    then [head winning]
    else if length branches < 100 then [ (t, b) | (t, b) <- branches, notElem t losing ] else branches
  branches2 = if null branches1 then [head branches] else branches1
  -}