jxxcarlson / elm-cell-grid / CellGrid

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.

Type


type CellGrid a
    = CellGrid Dimensions (Array a)

A value of type CellGrid a is a rectangular array of values of type a.


type alias Dimensions =
{ rows : Basics.Int
, columns : Basics.Int 
}

The size of a cell grid


type alias Position =
{ row : Basics.Int
, column : Basics.Int 
}

A position in a cell grid

Constructing and rendering CellGrids

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

Array-like functions

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.

Individual cell manipulation

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]

Cell types


type CellType
    = Corner
    | Edge
    | Interior

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

Index helpers

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)
--> ]

Documentation helpers

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