Last active
August 29, 2015 14:07
-
-
Save DataKinds/65e247be4b093fb15f78 to your computer and use it in GitHub Desktop.
Fun little game of life implementation, based on https://www.youtube.com/watch?v=a9xAKttWgP4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Applicative | |
import Control.Concurrent | |
import System.Console.ANSI | |
import Data.List.Split | |
import Data.Char | |
mainGridString :: IO String | |
mainGridString = readFile "grid" | |
parseGrid :: String -> Grid | |
parseGrid grid = (map . map) digitToInt (lines grid) | |
type CellInfo = (Int, Int) --Cell alive status, cell population | |
type Grid = [[Int]] | |
type GridWithCellInfo = [[CellInfo]] | |
shiftUp :: Grid -> Grid | |
shiftUp grid = tail grid ++ [head grid] | |
shiftDown :: Grid -> Grid | |
shiftDown grid = last grid : init grid | |
shiftLeft :: Grid -> Grid | |
shiftLeft grid = zipWith (++) (verticalTail) (verticalHead) | |
where verticalHead = map (:[]) (map (head) grid) | |
verticalTail = map (tail) grid | |
shiftRight :: Grid -> Grid | |
shiftRight grid = zipWith (++) (verticalLast) (verticalInit) | |
where verticalInit = map (init) grid | |
verticalLast = map (:[]) (map (last) grid) | |
shiftedGrids :: Grid -> [Grid] | |
shiftedGrids grid = [shiftUp grid, shiftDown grid, shiftLeft grid, shiftRight grid, (shiftDown . shiftRight) grid, (shiftDown . shiftLeft) grid, (shiftUp . shiftRight) grid, (shiftUp . shiftLeft) grid] | |
populationMap :: Grid -> GridWithCellInfo | |
populationMap grid = gridToTuple (grid) (foldr1 (addGrids) (shiftedGrids grid)) | |
where addGrids = (zipWith . zipWith) (+) :: Grid -> Grid -> Grid | |
gridToTuple = (zipWith . zipWith) (\alive population -> (alive, population)) :: Grid -> Grid -> GridWithCellInfo | |
isDedOrNot :: CellInfo -> Int --Takes CellInfo, Outputs whether or not the cell is alive | |
isDedOrNot cellInfo | |
| population < 2 = 0 | |
| population == 2 && alive == 1 = 1 | |
| population == 2 && alive == 0 = 0 | |
| population == 3 = 1 | |
| population > 3 = 0 | |
where population = snd cellInfo | |
alive = fst cellInfo | |
lifeIteration :: Grid -> Grid | |
lifeIteration grid = (map . map) (isDedOrNot) (populationMap grid) | |
animation :: Grid -> IO Grid | |
animation grid = do mapM_ putStrLn $ replicate 500 "" | |
mapM_ putStrLn (map concat ((map . map) numberToString grid)) | |
threadDelay 500000 -- 0.5 second.. in microseconds :/ | |
animation (lifeIteration grid) | |
where numberToString 0 = "." | |
numberToString 1 = "X" | |
main :: IO () | |
--main = do | |
-- mapM_ putStrLn (map show (populationMap mainGrid)) | |
-- putStrLn "" | |
-- mapM_ putStrLn (map show mainGrid) | |
-- putStrLn "" | |
-- mapM_ putStrLn (map show (lifeIteration mainGrid)) | |
-- putStrLn "" | |
-- mapM_ putStrLn (map show (lifeIteration $ lifeIteration mainGrid)) | |
main = do | |
grid <- mainGridString | |
animation (parseGrid grid) | |
putStrLn "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment