First commit

This commit is contained in:
Aadhavan Srinivasan
2025-01-17 11:38:50 -05:00
commit fa27a5d0ba
8 changed files with 375 additions and 0 deletions

59
src/GameOfLife.hs Normal file
View 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)