Packages

Create Hexagonal grids and Maps. Useful if you're building Hex-based games.

Current section

Files

Jump to
hexgrid lib map.ex
Raw

lib/map.ex

defmodule HexGrid.Map do
@moduledoc """
Map for Hexes. Allows for adding/removing tiles
and setting data on them.
"""
defstruct [data: Map.new]
@typedoc "Map"
@type t :: %HexGrid.Map{data: Map.t}
@typedoc "Result returned from Map functions"
@type result :: {:ok, term} | {:error, term}
@doc ~S"""
Creates an empty map
Examples:
iex> HexGrid.Map.new()
{:ok, %HexGrid.Map{}}
"""
@spec new() :: result
def new() do
{:ok, %HexGrid.Map{}}
end
@doc ~S"""
Creates a Hexagonal-shaped map with a given radius
Examples:
iex> HexGrid.Map.new_hex(0)
{:ok, %HexGrid.Map{data: %{%HexGrid.Hex{q: 0, r: 0, s: 0} => %{}}}}
"""
@spec new_hex(non_neg_integer) :: result
def new_hex(radius) do
data = for q <- (-radius)..radius,
r1 = max(-radius, -q - radius),
r2 = min( radius, -q + radius),
r <- r1..r2,
do: {HexGrid.Hex.new!(q, r, -q - r), %{}},
into: Map.new
{:ok, %HexGrid.Map{data: data}}
end
@doc ~S"""
Adds the tile to the map
"""
@spec insert(t, HexGrid.Hex.t) :: result
def insert(map, hex) do
case Map.get(map.data, hex) do
nil -> {:ok, update_in(map.data, &(Map.put(&1, hex, %{})))}
_ -> {:error, "Tile already exists"}
end
end
@doc """
Sets the arbitrary value on a map.
"""
@spec set(t, HexGrid.Hex.t, Map.key, Map.value) :: result
def set(map, hex, key, value) do
# we only want to set if tile exists
case Map.get(map.data, hex) do
nil -> {:error, "Tile does not exist"}
_ -> {:ok, %HexGrid.Map{data: put_in(map.data, [hex, key], value)}}
end
end
@doc """
Gets the value from the map.
"""
@spec get(t, HexGrid.Hex.t, Map.key) :: result
def get(map, hex, key) do
case Map.get(map.data, hex) do
nil -> {:error, "Tile does not exist"}
_ -> {:ok, get_in(map.data, [hex, key])}
end
end
end