File size: 2,138 Bytes
8752997 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
defmodule Hexalixir.Game do
use GenServer
alias Hexalixir.Grid
# Client API
def start_link(_opts) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def click_tile(coords) do
GenServer.call(__MODULE__, {:click_tile, coords})
end
def save_color(color, slot) do
GenServer.call(__MODULE__, {:save_color, color, slot})
end
def use_saved_color(coords, slot) do
GenServer.call(__MODULE__, {:use_saved_color, coords, slot})
end
# Server Callbacks
@impl true
def init(:ok) do
{:ok, %{
grid: Grid.new(),
saved_colors: %{1 => {nil, 6}, 2 => {nil, 6}}
}}
end
@impl true
def handle_call({:click_tile, coords}, _from, state) do
if Map.get(state.grid, coords) do
{:reply, {:error, :tile_already_colored}, state}
else
new_grid = color_tiles([coords | Grid.get_adjacent_coords(coords)], state.grid)
new_state = %{state | grid: new_grid}
{:reply, {:ok, new_grid, Grid.check_win(new_grid)}, new_state}
end
end
@impl true
def handle_call({:save_color, color, slot}, _from, state) do
new_state = put_in(state.saved_colors[slot], {color, 6})
{:reply, :ok, new_state}
end
@impl true
def handle_call({:use_saved_color, coords, slot}, _from, state) do
case state.saved_colors[slot] do
{nil, _} ->
{:reply, {:error, :no_color_saved}, state}
{color, 0} ->
{:reply, {:error, :no_uses_left}, state}
{color, uses} ->
if Map.get(state.grid, coords) do
{:reply, {:error, :tile_already_colored}, state}
else
new_grid = Map.put(state.grid, coords, color)
new_state = %{state |
grid: new_grid,
saved_colors: Map.put(state.saved_colors, slot, {color, uses - 1})
}
{:reply, {:ok, new_grid, Grid.check_win(new_grid)}, new_state}
end
end
end
# Private Functions
defp color_tiles(coords, grid) do
Enum.reduce(coords, grid, fn coord, acc ->
if Map.get(acc, coord) do
acc
else
Map.put(acc, coord, Grid.random_color())
end
end)
end
end
|