Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
My first complete implementation of game of life
import Control.Concurrent
import System.Console.ANSI
-- Logic
data Cell = Alive | Dead
deriving (Eq, Show)
type Neighbours = [Cell]
evolveCell :: (Cell, Int) -> Cell
evolveCell (Alive, 2) = Alive
evolveCell (Alive, 3) = Alive
evolveCell (Dead, 3) = Alive
evolveCell _ = Dead
evolveCells :: [(Cell, Neighbours)] -> [Cell]
evolveCells l = map evolveCell lCount
where
lCount = zip cells count
(cells, neighbours) = unzip l
count = map countAliveCells neighbours
countAliveCells = length . filter (== Alive)
-- Representation
data Board = Board {
boardWidth :: Int,
boardHeight :: Int,
boardCells :: [Cell]
} deriving (Show)
printBoard :: Board -> String
printBoard (Board width height cells) = printRows cells
where
printRows [] = ""
printRows xs = map cellChar (take width xs) ++ "\n" ++ printRows (drop width xs)
cellChar Alive = '0'
cellChar Dead = '~'
boardToCellNeighbourList :: Board -> [(Cell, Neighbours)]
boardToCellNeighbourList b = map getCellAndNeighbours [(x, y) | y <- [0..(boardHeight b)-1], x <- [0..(boardWidth b)-1]]
where
getCellAndNeighbours pos = (cellAt b pos, neighboursTo pos b)
cellAt (Board width height cells) (x, y)
| x < 0 = cellAt (Board width height cells) (width+x, y)
| x >= width = cellAt (Board width height cells) (x-width, y)
| y < 0 = cellAt (Board width height cells) (x, height+y)
| y >= height = cellAt (Board width height cells) (x, y-height)
| otherwise = head $ drop (width * y + x) cells
neighboursTo pos b = map (cellAt b) (neighboursPos pos)
neighboursPos (x, y) = map (\(x', y') -> (x+x', y+y')) [
(-1, -1), (0, -1), (1, -1),
(-1, 0), (1, 0),
(-1, 1), (0, 1), (1, 1)
]
evolveBoard :: Board -> Board
evolveBoard (Board width height cells) = Board width height newCells
where
newCells = evolveCells $ boardToCellNeighbourList (Board width height cells)
boardFromString :: [String] -> Board
boardFromString lines = Board width height cells
where
width = length $ head lines
height = length lines
cells = map toCell (concat lines)
toCell '-' = Dead
toCell '0' = Alive
-- Glue
main = loop $ boardFromString [
"------------------------------",
"---00-----------------0-------",
"---000---------------000------",
"----------------------0-------",
"------------------------------",
"--------------00--------------",
"--------------0-0-------------",
"--------------0---------------",
"---------------------000------",
"------------------------------",
"------------------------------",
"----0-------------------------"
]
where loop board = do
putStr (printBoard board)
threadDelay 100000
scrollPageDown (boardHeight board)
loop (evolveBoard board)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.