support boards that wrap
This commit is contained in:
@@ -2,13 +2,18 @@ defmodule Cartographer.Board do
|
||||
defstruct(
|
||||
tiles: %{},
|
||||
height: nil,
|
||||
width: nil
|
||||
width: nil,
|
||||
wrap: false
|
||||
)
|
||||
|
||||
def new_board(height, width) do
|
||||
def new_board(height, width, :wrap), do: _new_board(height, width, true)
|
||||
def new_board(height, width, :no_wrap), do: _new_board(height, width, false)
|
||||
|
||||
defp _new_board(height, width, wrap) do
|
||||
%__MODULE__{
|
||||
height: height,
|
||||
width: width,
|
||||
wrap: wrap,
|
||||
}
|
||||
end
|
||||
|
||||
@@ -16,6 +21,15 @@ defmodule Cartographer.Board do
|
||||
x >= 0 and x < width and y >= 0 and y < height
|
||||
end
|
||||
|
||||
def teleport(%__MODULE__{:height => height, :width => width}, x, y) do
|
||||
{_teleport(x, width), _teleport(y, height)}
|
||||
end
|
||||
|
||||
defp _teleport(n, range) when n >= range, do: rem(n, range)
|
||||
defp _teleport(n, range) when rem(n, range) == 0, do: 0
|
||||
defp _teleport(n, range) when n < 0, do: range + rem(n, range)
|
||||
defp _teleport(n, _range), do: n
|
||||
|
||||
def coordinate_range(center_x, center_y, range) do
|
||||
for x <- (center_x - range)..(center_x + range), y <- (center_y - range)..(center_y + range), do: {x, y}
|
||||
end
|
||||
@@ -29,12 +43,18 @@ defmodule Cartographer.Board do
|
||||
Map.get(board.tiles, {x, y})
|
||||
end
|
||||
|
||||
def get(board, center_x, center_y, range) do
|
||||
def get(board = %{wrap: false}, center_x, center_y, range) do
|
||||
coordinate_range(center_x, center_y, range)
|
||||
|> Enum.filter(fn({x, y}) -> in_bounds(board, x, y) end)
|
||||
|> Enum.reduce(%{}, &(Map.put(&2, &1, Map.get(board.tiles, &1))))
|
||||
end
|
||||
|
||||
def get(board = %{wrap: true}, center_x, center_y, range) do
|
||||
coordinate_range(center_x, center_y, range)
|
||||
|> Enum.map(fn({x, y}) -> teleport(board, x, y) end)
|
||||
|> Enum.reduce(%{}, &(Map.put(&2, &1, Map.get(board.tiles, &1))))
|
||||
end
|
||||
|
||||
def set(board, x, y, data) do
|
||||
in_bounds(board, x, y)
|
||||
|> _set(board, x, y, data)
|
||||
@@ -50,10 +70,17 @@ defmodule Cartographer.Board do
|
||||
|
||||
defp _set(_not_in_bounds, board, _x, _y, _data), do: board
|
||||
|
||||
def neighbors(board, center_x, center_y) do
|
||||
def neighbors(board = %{wrap: false}, center_x, center_y) do
|
||||
coordinate_range(center_x, center_y, 1)
|
||||
|> List.delete({center_x, center_y})
|
||||
|> Enum.filter(fn({x, y}) -> in_bounds(board, x, y) end)
|
||||
|> Enum.reduce(%{}, &(Map.put(&2, &1, Map.get(board.tiles, &1))))
|
||||
end
|
||||
|
||||
def neighbors(board = %{wrap: true}, center_x, center_y) do
|
||||
coordinate_range(center_x, center_y, 1)
|
||||
|> List.delete({center_x, center_y})
|
||||
|> Enum.map(fn({x, y}) -> teleport(board, x, y) end)
|
||||
|> Enum.reduce(%{}, &(Map.put(&2, &1, Map.get(board.tiles, &1))))
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user