The CellGrid package provides a type for representing a rectangular grid of cells. CellGrids can be created, transformed, and rendered with either SVG or WebGL.
A value of type CellGrid a
is a rectangular array
of values of type a.
{ rows : Basics.Int
, columns : Basics.Int
}
The size of a cell grid
{ row : Basics.Int
, column : Basics.Int
}
A position in a cell grid
empty : CellGrid a
The empty cell grid. Useful in conjunction with Maybe.withDefault
initialize : Dimensions -> (Basics.Int -> Basics.Int -> a) -> CellGrid a
Initialize a cell grid. initialize (Dimensions row column) f
creates a
cell grid of size (Dimensions row column)
with the element at (Position i j)
set to the result of f i j
.
import Array
grid1 : CellGrid Int
grid1 = CellGrid.initialize (Dimensions 2 2) (\i j -> i)
toLists grid1
--> [ [0,0]
--> , [1,1]
--> ]
CellGrid.initialize (Dimensions 2 3) (\i j -> toFloat (i + j))
--> CellGrid (Dimensions 2 3) (Array.fromList [ 0, 1, 2, 1, 2, 3 ])
repeat : Dimensions -> a -> CellGrid a
Fill a cell grid with a constant value
import Array
CellGrid.repeat (Dimensions 2 2) 42
--> CellGrid (Dimensions 2 2) (Array.fromList [ 42, 42, 42, 42 ])
fromList : Dimensions -> List a -> Maybe (CellGrid a)
Construct cell grid from a list of values. Grid construction fails when an amount of values incompatible with the dimensions is given.
import Array
fromList (Dimensions 2 2 ) [ 1.0, 2.0, 3.0, 4.0 ]
--> Just (CellGrid (Dimensions 2 2) (Array.fromList [1,2,3,4]))
fromList (Dimensions 2 2 ) [ 1.0, 2.0, 3.0, 4.0, 5.0 ]
--> Nothing
map : (a -> b) -> CellGrid a -> CellGrid b
Map a function over a cell grid.
grid : CellGrid Int
grid = CellGrid.incrementing (Dimensions 2 2)
toLists grid
--> [ [0,1]
--> , [2,3]
--> ]
doubled : CellGrid Int
doubled = CellGrid.map (\v -> v * 2) grid
toLists doubled
--> [ [0,2]
--> , [4,6]
--> ]
indexedMap : (Basics.Int -> Basics.Int -> a -> b) -> CellGrid a -> CellGrid b
Transform a cell grid while having access to a cell's position
indexedMap (\i j value -> value + i * j) cellGrid
foldl : (a -> b -> b) -> b -> CellGrid a -> b
Fold a function of type a -> b -> b
over a CellGrid a
, associating to the left.
foldr : (a -> b -> b) -> b -> CellGrid a -> b
Fold a reducer a -> b -> b
over a CellGrid a
, associating to the right.
toList : CellGrid a -> List a
toList grid =
CellGrid.foldr (::) [] grid
transform : (Basics.Int -> Basics.Int -> CellGrid a -> b) -> CellGrid a -> CellGrid b
Modify a cell while having access to the full cell grid. The supplied cell grid is always the original input. Useful for simulations that need neighbor information, like Conway's game of life.
get : Position -> CellGrid a -> Maybe a
Get a value.
grid : CellGrid Int
grid = CellGrid.incrementing (Dimensions 2 2)
toLists grid
--> [ [0, 1]
--> , [2, 3]
--> ]
CellGrid.get (Position 1 1) grid
--> Just 3
set : Position -> a -> CellGrid a -> CellGrid a
Set a value.
grid : CellGrid Int
grid = CellGrid.repeat (Dimensions 2 2) 42
toLists grid
--> [ [42, 42]
--> , [42, 42]
--> ]
new : CellGrid Int
new = CellGrid.set (Position 1 1) 84 grid
toLists new
--> [ [42, 42]
--> , [42, 84]
--> ]
update : Position -> (a -> a) -> CellGrid a -> CellGrid a
Update a value.
grid : CellGrid Int
grid = CellGrid.repeat (Dimensions 2 2) 42
toLists grid
--> [ [42, 42]
--> , [42, 42]
--> ]
new : CellGrid Int
new = CellGrid.update (Position 1 1) (\v -> 2 * v) grid
toLists new
--> [ [42, 42]
--> , [42, 84]
--> ]
adjacent : Position -> CellGrid a -> List a
Get the list of cell values of the four adjacent cells.
grid : CellGrid Int
grid = CellGrid.incrementing (Dimensions 3 3)
toLists grid
--> [ [0,1,2]
--> , [3,4,5]
--> , [6,7,8]
--> ]
CellGrid.adjacent (Position 1 1) grid
--> [5,1,3,7]
neighbors : Position -> CellGrid a -> List a
Get the list of cell values of the eight neighboring cells.
grid : CellGrid Int
grid = CellGrid.incrementing (Dimensions 3 3)
toLists grid
--> [ [0,1,2]
--> , [3,4,5]
--> , [6,7,8]
--> ]
CellGrid.neighbors ( Position 1 1 ) grid
--> [5,2,1,0,3,6,7,8]
A cell can be in the interior of the grid, on an edge, on in a corner.
classifyCell : Position -> CellGrid a -> CellType
return the type of the cell.
grid : CellGrid (Int, Int)
grid = CellGrid.initialize (Dimensions 3 3) Tuple.pair
toLists grid
--> [[(0,0),(0,1),(0,2)]
--> ,[(1,0),(1,1),(1,2)]
--> ,[(2,0),(2,1),(2,2)]
--> ]
CellGrid.classifyCell (Position 0 0) grid --> Corner
CellGrid.classifyCell (Position 0 1) grid --> Edge
CellGrid.classifyCell (Position 1 1) grid --> Interior
arrayIndex : { a | columns : Basics.Int } -> Position -> Basics.Int
Convert a Position
into an index into the flat array.
arrayIndex (Dimensions 3 2) (Position 0 1) --> 1
arrayIndex (Dimensions 3 2) (Position 2 1) --> 5
matrixIndex : { a | columns : Basics.Int } -> Basics.Int -> Position
Convert an index into the flat array into a Position
.
matrixIndex (Dimensions 3 2) 1 --> (Position 0 1)
matrixIndex (Dimensions 3 2) 5 --> (Position 2 1)
matrixIndices : CellGrid a -> List Position
Return a list of all matrix indices (i,j) of a grid. Useful for mapping.
grid : CellGrid Bool
grid =
CellGrid.repeat (Dimensions 2 3) True
CellGrid.matrixIndices grid
--> [ (Position 0 0)
--> , (Position 0 1)
--> , (Position 0 2)
--> , (Position 1 0)
--> , (Position 1 1)
--> , (Position 1 2)
--> ]
toLists : CellGrid a -> List (List a)
Convert a cell grid to a list of rows of values
incrementing : Dimensions -> CellGrid Basics.Int
An incrementing integer cell grid
toLists (incrementing (Dimensions 3 3))
--> [[0,1,2]
--> ,[3,4,5]
--> ,[6,7,8]
--> ]
Defined as
incrementing : Dimensions -> CellGrid Int
incrementing dimensions =
let
initializer : Int -> Int -> Int
initializer i j =
arrayIndex dimensions (Position i j)
in
initialize dimensions initializer