While I was fiddling around with my weird hack project (more on that someday), I had an idea for how to use maps in Elixir.
I hadn’t noticed, but you can use more than just strings and atoms as keys…and so, I give you a quick and dirty grid implementation.
defmodule SvgWorld.Simulation.Grid do
require Record
Record.defrecord(:grid, map: %{})
def init(), do: grid(map: %{})
def insert_into_grid(grid(map: map) = g, x, y, value) do
new_map = Map.put(map, {x,y}, value)
grid(g, map: new_map)
end
def get_from_grid(grid(map: map), x, y) do
Map.get(map, {x,y}, :not_found)
end
def values_in_grid(grid(map: map), start_x, start_y, end_x, end_y) do
Map.keys(map)
|> Enum.filter( fn {x,y} -> x >= start_x and x < end_x and y >= start_y and y < end_y end)
|> Enum.reduce( %{}, fn(key, acc) -> Map.put( acc, key, Map.get(map, key) ) end)
end
@spec values_near_point_in_grid({:grid, map}, any, any, any) :: any
def values_near_point_in_grid( grid(map: map), x, y, radius) do
Map.keys(map)
|> Enum.filter( fn {gx,gy} ->
dx = gx - x
dy = gy - y
(radius * radius) >= ((dx*dx) + (dy*dy))
end)
|> Enum.reduce( %{}, fn(key, acc) -> Map.put( acc, key, Map.get(map, key) ) end)
end
end
You can’t do reverse lookups, but that’s an easy enough addition you can make to this.
The typespecs are also super loose (when they exist at all), but that’s fine.
Anyways, I thought it was a cute litte project.
Until next time. :3