jxxcarlson/elm-cell-grid/8.0.0

NOTE: the latest version is 8.0.1

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 : Int
, columns : Int
}

The size of a cell grid

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

A position in a cell grid

Constructing and rendering CellGrids

The empty cell grid. Useful in conjunction with Maybe.withDefault

initialize : Dimensions -> (Int -> 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 : (Int -> 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 : (Int -> 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

= 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 : Int } -> Position -> 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 : Int } -> 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 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