1 module Game where
    2 
    3 import Board
    4 import Wins
    5 import Tree
    6 
    7 type Player = Evaluation -> Evaluation -> Evaluation
    8 type Move = (Board,Evaluation)
    9 
   10 
   11 
   12 alternate :: Piece -> Player -> Player -> Board -> [Move]
   13 alternate _ _ _ b | fullBoard b = []
   14 alternate _ _ _ b | static b == XWin = []
   15 alternate _ _ _ b | static b == OWin = []
   16 alternate player f g board = move:alternate opposition g f board'
   17         where
   18         move@(board',eval) = best f possibles scores
   19         scores = map (bestMove opposition g f) possibles
   20         possibles = newPositions player board
   21         opposition = opposite player
   22 
   23 opposite :: Piece -> Piece
   24 opposite X = O
   25 opposite O = X
   26 
   27 
   28 best :: Player -> [Board] -> [Evaluation] -> Move
   29 best f (b:bs) (s:ss) = best' b s bs ss
   30         where
   31         best' b s [] [] = (b,s)
   32         best' b s (b':bs) (s':ss) | s==(f s s') = best' b s bs ss
   33                                   | otherwise           = best' b' s' bs ss
   34 
   35 showMove :: Move -> String
   36 showMove (b,e) = show e ++ "\n" ++ showBoard b
   37 
   38 bestMove :: Piece -> Player -> Player -> Board -> Evaluation
   39 bestMove p f g = (mise f g).cropTree.mapTree static.searchTree p
   40 
   41 cropTree :: (Tree Evaluation) -> (Tree Evaluation)
   42 cropTree (Branch a []) = (Branch a [])
   43 cropTree (Branch (Score x) l) = Branch (Score x) (map cropTree l)
   44 cropTree (Branch x l) = Branch x []
   45 
   46 searchTree :: Piece -> Board -> (Tree Board)
   47 searchTree p board = prune 5 (repTree (newPositions p) (newPositions (opposite p)) board)
   48 
   49 mise :: Player -> Player -> (Tree Evaluation) -> Evaluation
   50 mise f g (Branch a []) = a
   51 mise f g (Branch _ l) = foldr f (g OWin XWin) (map (mise g f) l)
   52 
   53 
   54 max' :: Evaluation -> Evaluation -> Evaluation
   55 max' XWin _ = XWin
   56 max' _ XWin = XWin
   57 max' b OWin = b
   58 max' OWin b = b
   59 max' a@(Score x) b@(Score y)    | x>y = a
   60                                 | otherwise = b
   61 
   62 min' :: Evaluation -> Evaluation -> Evaluation
   63 min' OWin _ = OWin
   64 min' _ OWin = OWin
   65 min' b XWin = b
   66 min' XWin b = b
   67 min' a@(Score x) b@(Score y)    | x<y = a
   68                                 | otherwise = b
   69