module DataTypes where import Data.List data TableMove = TableMove Board History CurrentMove deriving (Show,Ord) data Move = X | O deriving (Eq, Show, Enum, Ord) type History = [Integer] type CurrentMove = Maybe Move type Board = [[Maybe Move]] size :: Int size = 3 empty :: Board empty = replicate size (replicate size Nothing) -- make use of symmetries -- we try to see if there is a symmetry if the move we are about to make -- has across from it, either horizontally, vertically, or diagonally, a Nothing slot. -- The only position that may change is the position of the move we are about to make. -- If the symmetrical move is already included in the current ply, we may take it out. instance Eq TableMove where (TableMove m1 h1 c1) == (TableMove m2 h2 c2) = (horizontalSym m1 == m2) || (leftDiagonalSym m1 == m2) || (verticalSym m1 == m2) || (rightDiagonalSym m1 == m2) horizontalSym = reverse leftDiagonalSym = transpose verticalSym = transpose.reverse.transpose rightDiagonalSym = verticalSym.reverse.transpose -- these are our accessors accessMaybeMove :: TableMove -> [[Maybe Move]] accessMaybeMove (TableMove m _ _) = m accessHistory :: TableMove -> [Integer] accessHistory (TableMove _ h _) = h accessCurrentMove :: TableMove -> CurrentMove accessCurrentMove (TableMove _ _ c) = c getOtherMove :: CurrentMove -> CurrentMove getOtherMove (Just X) = Just (succ X) getOtherMove (Just O) = Just (pred O) getOtherMove Nothing = Nothing toTableMove :: [[Maybe Move]] -> History -> CurrentMove -> TableMove toTableMove m h c = TableMove m h c chop :: Int -> [a] -> [[a]] chop n [] = [] chop n xs = take n xs : chop n (drop n xs) infinity :: Float infinity = 1/0 -- gives us a list of the diagonal elements diag :: [[a]] -> [a] diag xss = [xss !! n !! n | n <- [0 .. length xss - 1]]