Skip to content

Instantly share code, notes, and snippets.

@rickardlindberg
Created November 26, 2011 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rickardlindberg/1395519 to your computer and use it in GitHub Desktop.
Save rickardlindberg/1395519 to your computer and use it in GitHub Desktop.
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