Sergidev's picture
v1.0a
8752997
raw
history blame
2.14 kB
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