Packages
islands_engine
0.1.7
0.2.65
0.2.64
0.2.63
0.2.62
0.2.61
0.2.60
0.2.59
0.2.58
0.2.56
0.2.55
0.2.54
0.2.53
0.2.52
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.43
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.34
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.27
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.13
0.2.12
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.81
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.73
0.1.72
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.0
Models the Game of Islands.
Current section
Files
Jump to
Current section
Files
lib/islands/engine/grid.ex
defmodule Islands.Engine.Grid do
@moduledoc """
Converts a player's board/guesses to a grid (map of maps).
Also converts a grid to a list of maps.
"""
use PersistConfig
alias IO.ANSI.Plus, as: ANSI
alias Islands.Engine.{Board, Coord, Format, Guesses, Island}
@type t :: %{Coord.row() => %{Coord.col() => atom}}
@board_range Application.get_env(@app, :board_range)
@doc """
Returns an "empty" grid.
## Examples
iex> alias Islands.Engine.Grid
iex> %{1 => row_1} = Grid.new()
iex> row_1
%{
1 => nil, 2 => nil, 3 => nil, 4 => nil, 5 => nil,
6 => nil, 7 => nil, 8 => nil, 9 => nil, 10 => nil
}
"""
@spec new() :: t
def new() do
for row <- @board_range, into: %{} do
{row, for(col <- @board_range, into: %{}, do: {col, nil})}
end
end
@doc """
Converts a board map or a guesses struct to a grid.
## Examples
iex> {:ok, atoll_coord} = Coord.new(1, 1)
iex> {:ok, atoll_hit} = Coord.new(1, 2)
iex> {:ok, atoll} = Island.new(:atoll, atoll_coord)
iex>
iex> {:hit, :none, :no_win, board} =
iex> Board.new()
iex> |> Board.position_island(atoll)
iex> |> Board.guess(atoll_hit)
iex>
iex> %{1 => row_1} = Grid.new(board)
iex> row_1
%{
1 => :atoll, 2 => :atoll_hit, 3 => nil, 4 => nil, 5 => nil,
6 => nil , 7 => nil , 8 => nil, 9 => nil, 10 => nil
}
iex> {:ok, atoll_coord} = Coord.new(1, 1)
iex> {:ok, atoll_hit} = Coord.new(1, 2)
iex>
iex> guesses =
iex> Guesses.new()
iex> |> Guesses.add(:miss, atoll_coord)
iex> |> Guesses.add(:hit, atoll_hit)
iex>
iex> %{1 => row_1} = Grid.new(guesses)
iex> row_1
%{
1 => :miss, 2 => :hit, 3 => nil, 4 => nil, 5 => nil,
6 => nil , 7 => nil , 8 => nil, 9 => nil, 10 => nil
}
"""
@spec new(Board.t() | Guesses.t()) :: t
def new(board_or_guesses)
def new(%Board{islands: islands, misses: misses}) do
islands
|> Map.values()
|> Enum.reduce(new(), fn island, grid ->
%Island{type: type, coords: coords, hits: hits} = island
grid
|> update(coords, type)
|> update(hits, :"#{type}_hit")
|> update(misses, :board_miss)
end)
end
def new(%Guesses{hits: hits, misses: misses}) do
new() |> update(hits, :hit) |> update(misses, :miss)
end
@doc """
Converts a grid to a list of maps.
## Examples
iex> {:ok, atoll_coord} = Coord.new(1, 1)
iex> {:ok, atoll_hit} = Coord.new(1, 2)
iex> {:ok, atoll} = Island.new(:atoll, atoll_coord)
iex>
iex> {:hit, :none, :no_win, board} =
iex> Board.new()
iex> |> Board.position_island(atoll)
iex> |> Board.guess(atoll_hit)
iex>
iex> [row_1 | _other_rows] = board |> Grid.new() |> Grid.to_maps(& &1)
iex> row_1
%{"row" => 1,
1 => :atoll, 2 => :atoll_hit, 3 => nil, 4 => nil, 5 => nil,
6 => nil , 7 => nil , 8 => nil, 9 => nil, 10 => nil
}
"""
@spec to_maps(t, (atom -> ANSI.ansidata())) :: [map]
def to_maps(grid, fun \\ &Format.for/1) when is_function(fun, 1) do
for {row_num, row_map} <- grid do
[
{"row", row_num}
| for {col_num, cell_val} <- row_map do
{col_num, fun.(cell_val)}
end
]
|> Map.new()
end
end
## Private functions
@spec update(t, Island.coords(), atom) :: t
defp update(grid, coords, value) do
coords
|> MapSet.to_list()
|> Enum.reduce(grid, fn %Coord{row: row, col: col}, grid ->
put_in(grid, [row, col], value)
end)
end
end