Advertisement
Guest User

GameOfLife.hs

a guest
Dec 27th, 2014
406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. -- GameOfLife.hs
  3.  
  4. import Control.Comonad
  5.  
  6. import ListZipper
  7.  
  8. --- Beginning of game logic
  9.  
  10. countNeighbours :: ListZipT ListZip Bool -> Int
  11. -- Counts number of living cells in current 3x3 square (including this one in the center)
  12. countNeighbours llwonad =
  13.     let countNeighbours1 lwonad = length $ filter (== True) $ [extract lwonad, head $ l lwonad, r lwonad !! 1]
  14.     in  sum $ fmap countNeighbours1 [tget llwonad, head $ tl llwonad, tr llwonad !! 1]
  15.  
  16. rule :: ListZipT ListZip Bool -> Bool
  17. -- Decides wether current cell should be alive or dead in next turn
  18. rule llwonad =
  19.     let n = countNeighbours llwonad
  20.     in n == 3 || (n == 4 && extract llwonad)
  21.  
  22. life :: ListZipT ListZip Bool -> [ListZipT ListZip Bool]
  23. life = iterate $ extend rule
  24.  
  25. --- End of game logic
  26.  
  27. window :: Int -> Int -> ListZipT ListZip a -> [[a]]
  28. -- Returns values of x*y rectagle in the zipper
  29. window x y llwonad =
  30.     fmap (take x) $ fmap r $ take y $ tr llwonad
  31.  
  32. toStr :: [[Bool]] -> String
  33. -- Translates a 2D Bool array into a readable representation,
  34. -- Each line -> line in the array,
  35. -- in each line True -> '#', False -> '-'
  36. toStr =
  37.     let toStr1 :: [Bool] -> String
  38.         toStr1 = map (\x -> if x then '#' else '-')
  39.     in  unlines . map toStr1
  40.  
  41. fromStr :: String -> [[Bool]]
  42. -- Translates a readable representation of a 2D Bool grid
  43. fromStr = map (map (== '#')) . lines
  44.  
  45. falseLine :: ListZip Bool
  46. -- An infinite False line
  47. falseLine = fromList (repeat False) (repeat False)
  48.  
  49. gridFromStr :: String -> ListZipT ListZip Bool
  50. -- Translates a string representation into an infinite grid
  51. gridFromStr lsts =
  52.     let infFlsLZ = fromList (repeat False) (repeat False)
  53.     in  LZ (repeat infFlsLZ) ((map (\x -> fromList (repeat False) (x ++ repeat False)) (fromStr lsts)) ++ repeat infFlsLZ)
  54.  
  55. play :: Int -> Int -> ListZipT ListZip Bool -> IO ()
  56. play turns windowSize p0 = foldl1 (\x y -> x >> putStrLn "" >> y) (take turns $ map (putStr . toStr . window windowSize windowSize) $ life p0)
  57.  
  58. main :: IO ()
  59. main = play 6 10 $ gridFromStr "\n\n...###\n..#####\n...###"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement