packages feed

babylon-0.1: Minimax.hs

{-
  Generic Minimax algorithm for game playing
  Based in Bird & Wadler "Introduction to Functional Programming"
  Pedro Vasconcelos, 2009
-}
module Minimax where
import Data.Tree
--import Data.List

-- annotate something with an evaluation estimate 
data Eval a = Eval Int a deriving (Show)

instance Eq (Eval a) where
    (Eval x _) == (Eval y _) = x==y

instance Ord (Eval a) where
    compare (Eval x _) (Eval y _) = compare x y

instance (Show a) => Num (Eval a) where
    fromInteger = undefined
    (+) = undefined
    (-) = undefined
    (*) = undefined
    abs = undefined
    signum= undefined
    negate (Eval x a) = Eval (-x) a

fromEval :: Eval a -> a
fromEval (Eval _ x) = x



-- naive minimax algorithm
-- nodes are decorated with the static evaluation scores
minimax :: (Num a, Ord a) => Tree a -> a
minimax (Node n []) = n
minimax (Node n ts) = - minimum (map minimax ts)


-- branch-and-bound minimax (alpha-beta prunning)
-- nodes are decorated with the static evaluation scores
bbminimax :: (Num a, Ord a) => a -> a -> Tree a -> a
bbminimax a b (Node x []) = a `max` x `min` b
bbminimax a b (Node x ts) = cmx a ts
    where
      cmx a []  = a
      cmx a (t:ts) | a'>=b     = a'
                   | otherwise = cmx a' ts
                   where a' = -(bbminimax (-b) (-a) t)


-- some generic functions follow
-- prune a tree to a fixed depth
prune :: Int -> Tree a -> Tree a
prune n (Node x ts) 
    | n>0       = Node x (map (prune (n-1)) ts)
    | otherwise = Node x []

-- breadth and depth of a tree
breadth :: Tree a -> Int
breadth (Node x ts) = length ts

depth :: Tree a -> Int
depth (Node x []) = 1
depth (Node x ts) = 1 + maximum (map depth ts)