Orasund / elm-game-essentials / Grid

A Grid is a dictionary that has a size constraint. Here is an example where such a grid is used: Snake Example.

Grids


type alias Grid a =
Array (Array a)

A grid with a fixes amount of columns and rows.

It will wrap the borders (apply ModBy), making every (Int,Int) valid.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> get ( -1, 0 )
--> grid |> get ( (dimensions |> .columns) - 1, 0 )

If instead you want to have hard border around your grid, use Grid.Bordered instead.

Build

init : (( Basics.Int, Basics.Int ) -> a) -> { rows : Basics.Int, columns : Basics.Int } -> Array (Array a)

Create a grid

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid a
grid =
    empty dimensions

init (always <| Just ()) dimensions |> emptyPositions
--> []

empty : { rows : Basics.Int, columns : Basics.Int } -> Array (Array (Maybe a))

Create an empty grid

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

empty dimensions
--> init (always Nothing ) dimensions

build : List (List a) -> Array (Array a)

Build a grid out of lists

random : { columns : Basics.Int, rows : Basics.Int } -> Random.Generator a -> Random.Generator (Array (Array a))

Generate a random grid based on a cell generator

getMember : ( Basics.Int, Basics.Int ) -> Array (Array (Maybe a)) -> Maybe a

Get the value associated with a (Int,Int). If the (Int,Int) is empty, return Nothing.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> getMember (2,2)
--> Just 42

insert : ( Basics.Int, Basics.Int ) -> a -> Array (Array (Maybe a)) -> Array (Array (Maybe a))

Insert a value at a (Int,Int) in a grid. Replaces value when there is a collision.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> getMember (2,2)
--> Just 42

update : ( Basics.Int, Basics.Int ) -> (Maybe a -> Maybe a) -> Array (Array (Maybe a)) -> Array (Array (Maybe a))

Update the value of a grid for a specific (Int,Int) with a given function.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> update (2,2) (always <| Just 42)
--> grid |> insert (2,2) 42

remove : ( Basics.Int, Basics.Int ) -> Array (Array (Maybe a)) -> Array (Array (Maybe a))

Remove a vlaue from a grid. If the (Int,Int) is empty, no changes are made.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> getMember (2,2) --> Just 42
grid |> insert (2,2) 42 |> remove (2,2) |> getMember (2,2)
--> Nothing

Query

isEmpty : Array (Array (Maybe a)) -> Basics.Bool

Determine if a grid is empty.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> isEmpty --> True
grid |> insert (2,2) 42 |> isEmpty --> False

member : ( Basics.Int, Basics.Int ) -> Array (Array (Maybe a)) -> Basics.Bool

Determine if a (Int,Int) is empty.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> member (2,2)
--> True

get : ( Basics.Int, Basics.Int ) -> Array (Array a) -> Maybe a

Get the element in the grid

set : ( Basics.Int, Basics.Int ) -> a -> Array (Array a) -> Array (Array a)

Set the element in the grid

size : Array (Array (Maybe a)) -> Basics.Int

Determine the number of values in the grid.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> size
--> 1

dimensions : Grid a -> { columns : Basics.Int, rows : Basics.Int }

Return the dimensions of the grid.

dim : { columns:Int , rows:Int }
dim =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dim

grid |> dimensions
--> dim

List

positions : Array (Array (Maybe a)) -> List ( Basics.Int, Basics.Int )

Get all non empty positions in a grid, sorted from lowest to highest.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> positions
--> [(2,2)]

emptyPositions : Array (Array (Maybe a)) -> List ( Basics.Int, Basics.Int )

Get all empty positions in a grid, sorted from lowest to highest.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe Int)
grid =
    init
        (always <| Just <| 42)
        dimensions

grid |> remove (2,2) |> emptyPositions
--> [(2,2)]

values : Array (Array (Maybe a)) -> List a

Get all of the values in a grid, in the order of their (Int,Int)s.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe a)
grid =
    empty dimensions

grid |> insert (2,2) 42 |> values
--> [42]

toList : Array (Array a) -> List ( ( Basics.Int, Basics.Int ), a )

Convert a grid into an association list of (Int,Int)-value pairs, sorted by the (Int,Int).

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=2
    , rows=2
    }

grid : Grid (Maybe Int)
grid =
    empty dimensions

grid |> insert (1,1) 42 |> toList
--> [( (0,0), Nothing ),((1,0), Nothing ),((0,1), Nothing ),( (1,1), Just 42 )]

fromList : { rows : Basics.Int, columns : Basics.Int } -> List ( ( Basics.Int, Basics.Int ), a ) -> Array (Array (Maybe a))

Convert an association list into a grid.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe Int)
grid =
    empty dimensions

[((2,2),42),((2,1),20)] |> fromList dimensions
--> grid |> insert (2,2) 42 |> insert (2,1) 20

Dict

toDict : Array (Array (Maybe a)) -> Dict ( Basics.Int, Basics.Int ) a

Convert a grid into an associated dictionary

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe Int)
grid =
    empty dimensions
        |> insert (2,2) 42

grid |> toDict |> fromDict dimensions |> getMember (2,2)
--> Just 42

fromDict : { rows : Basics.Int, columns : Basics.Int } -> Dict ( Basics.Int, Basics.Int ) a -> Array (Array (Maybe a))

Convert an dictionary to a grid

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe Int)
grid =
    empty dimensions

grid |> toDict |> fromDict dimensions |> getMember (2,2)
--> Nothing

Transform

map : (( Basics.Int, Basics.Int ) -> a -> b) -> Array (Array a) -> Array (Array b)

Apply a function to all positions in a grid.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

empty dimensions |> map (\_ _ -> Just 42)
--> init (always <| Just 42) dimensions

filter : (( Basics.Int, Basics.Int ) -> a -> Basics.Bool) -> Array (Array (Maybe a)) -> Array (Array (Maybe a))

Keep only the values that pass the given test.

dimensions : { columns:Int , rows:Int }
dimensions =
    { columns=42
    , rows=3
    }

grid : Grid (Maybe Int)
grid =
    empty dimensions
        |> insert (2,4) 2
        |> insert (2,2) 42

grid |> filter (\_ -> (==) 42) |> values
--> [42]

find : (( Basics.Int, Basics.Int ) -> a -> Basics.Bool) -> Array (Array a) -> Maybe ( ( Basics.Int, Basics.Int ), a )

Find the first value that passes a given test.