First commit
This commit is contained in:
59
src/GameOfLife.hs
Normal file
59
src/GameOfLife.hs
Normal file
@@ -0,0 +1,59 @@
|
||||
module GameOfLife (tick) where
|
||||
|
||||
type Grid = [[Int]]
|
||||
|
||||
-- Maps a function over every element in a grid
|
||||
gridMap :: (a -> b) -> [[a]] -> [[b]]
|
||||
gridMap f = map (map f)
|
||||
|
||||
-- Param 1: The current value of the cell
|
||||
-- Param 2: The number of living neighbors
|
||||
-- Return value: The next value of the cell
|
||||
nextIterHelper :: Int -> Int -> Int
|
||||
nextIterHelper 1 2 = 1
|
||||
nextIterHelper 1 3 = 1
|
||||
nextIterHelper 0 3 = 1
|
||||
nextIterHelper _ _ = 0
|
||||
|
||||
-- Returns the value of a specific cell in a grid - out-of-bounds is always zero
|
||||
cellVal :: Grid -> (Int, Int) -> Int
|
||||
cellVal grid (x,y)
|
||||
| x < 0 || y < 0 = 0
|
||||
| y >= length (grid) || x >= length (grid!!0) = 0
|
||||
| otherwise = (grid!!y)!!x
|
||||
|
||||
-- Given a tuple (representing the location of a cell),
|
||||
-- it returns a list of tuples that are the locations of the neighbors
|
||||
neighbors :: (Int, Int) -> [(Int, Int)]
|
||||
neighbors (x, y) = [(a,b) | a <- dx, b <- dy, a /= x || b /= y]
|
||||
where dx = [x-1..x+1]
|
||||
dy = [y-1..y+1]
|
||||
|
||||
-- Predicate - returns whether the cell is alive or not
|
||||
isAlive :: Grid -> (Int,Int) -> Bool
|
||||
isAlive grid tup = if (cellVal grid tup) == 1 then True else False
|
||||
|
||||
-- Filter function that takes a list of indexes in a grid, and only returns the ones
|
||||
-- where the cell value is 1
|
||||
keepAliveCells :: Grid -> [(Int,Int)] -> [(Int,Int)]
|
||||
keepAliveCells grid tups = filter (isAlive grid) tups
|
||||
|
||||
-- Returns the number of alive neighbors of the given cell
|
||||
numAliveNeighbors :: Grid -> (Int,Int) -> Int
|
||||
numAliveNeighbors grid tup = (length . keepAliveCells grid . neighbors) tup
|
||||
|
||||
-- Given the grid and the location of a cell, returns the next value of the cell
|
||||
nextIter :: Grid -> (Int, Int) -> Int
|
||||
nextIter grid tup = nextIterHelper (cellVal grid tup) (numAliveNeighbors grid tup)
|
||||
|
||||
-- Returns a grid of all cell indices in the grid
|
||||
cellIndices :: Grid -> [[(Int,Int)]]
|
||||
cellIndices [[]] = [[]]
|
||||
cellIndices grid = [[(x,y) | x <- [0..xdim-1]] | y <- [0..ydim-1]]
|
||||
where xdim = length (grid!!0)
|
||||
ydim = length grid
|
||||
|
||||
tick :: Grid -> Grid
|
||||
tick [] = []
|
||||
tick [[]] = [[]]
|
||||
tick grid = gridMap (nextIter grid) (cellIndices grid)
|
Reference in New Issue
Block a user