Created
March 2, 2021 03:01
-
-
Save anargu/ddacadc2d185311a286410b0988a3675 to your computer and use it in GitHub Desktop.
asciified_tiny_gol
This file contains 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
........... | |
...oo.oo... | |
...oo.oo... | |
....o.o.... | |
..o.o.o.o.. | |
..o.o.o.o.. | |
..oo...oo.. | |
........... | |
........... |
This file contains 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 System.Environment | |
import Control.Concurrent | |
import Data.Maybe | |
-- Any live cell with fewer than two live neighbors dies, as if by under-population. | |
-- Any live cell with two or three live neighbors lives on to the next generation. | |
-- Any live cell with more than three live neighbors dies, as if by overpopulation. | |
-- Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. | |
type Point = (Int, Int) | |
type Status = Bool | |
type Node = (Point, Status) | |
type Game = [Node] | |
type Generation = Integer | |
isCharLiving :: Char -> Bool | |
isCharLiving char | |
| char == 'o' = True | |
| otherwise = False | |
makeRow :: String -> Int -> [Node] | |
makeRow row y = | |
[((x,y), isCharLiving $ row !! x) | x <- [0..length row - 1]] | |
prepareData :: [String] -> Game | |
prepareData rawData = | |
concat [ makeRow (rawData !! y) y | y <- [0..length rawData - 1]] | |
nextState :: Game -> Game | |
nextState game = map (`makeNode` game) game | |
makeNode :: Node -> Game -> Node | |
makeNode node game = | |
( | |
fst node, | |
nextNodeState (aliveNeighbours game node directions 0) (snd node) | |
) | |
nextNodeState :: Integer -> Bool -> Bool | |
nextNodeState aliveNeighbours status | |
| aliveNeighbours == 3 && not status = True | |
| aliveNeighbours == 2 && status = True | |
| aliveNeighbours == 3 && status = True | |
| otherwise = False | |
aliveNeighbours :: Game -> Node -> [Point] -> Integer -> Integer | |
aliveNeighbours game ((x,y), status) dirs count | |
| null dirs = count | |
| isAlive game (x + fst (head dirs), y + snd (head dirs)) | |
= aliveNeighbours game ((x, y), status) (tail dirs) (count + 1) | |
| otherwise = aliveNeighbours game ((x, y), status) (tail dirs) count | |
directions :: [Point] | |
directions = [(0,-1), (1,-1), (1,0), (1,1), (0,1), (-1,1), (-1,0), (-1,-1)] | |
isAlive :: Game -> Point -> Bool | |
isAlive game node | |
| isNothing(getCell node game) = False | |
| snd(fromJust(getCell node game)) = True | |
| otherwise = False | |
type Cell = Node | |
getCell :: Point -> Game -> Maybe Node | |
getCell pos [] = Nothing | |
getCell pos (((x,y), status) : rest) | |
| pos == (x,y) = Just ((x,y), status) | |
| otherwise = getCell pos rest | |
main :: IO() | |
main = do | |
rawData <- readFile "./pentadecathlon" | |
get (prepareData $ lines rawData) | |
representation :: Status -> String | |
representation cell | |
| cell = "[●]" | |
| otherwise = "[ ]" | |
putCell :: Cell -> IO() | |
putCell cell | |
| fst (fst cell) == 0 = putStr $ "\n" ++ representation (snd cell) | |
| otherwise = putStr $ representation (snd cell) | |
clearScreen :: IO() | |
clearScreen = putStr "\ESC[2J" | |
get :: Game -> IO() | |
get game = do | |
sequence_ [putCell cell | cell <- game] | |
clearScreen | |
threadDelay 200000 | |
get (nextState game) | |
-- input file pentadecathlon: | |
-- ........... | |
-- ...oo.oo... | |
-- ...oo.oo... | |
-- ....o.o.... | |
-- ..o.o.o.o.. | |
-- ..o.o.o.o.. | |
-- ..oo...oo.. | |
-- ........... | |
-- ........... | |
-- execute this: ghc -o tiny_gol src/tiny_gol.hs && ./tiny_gol |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment