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