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