|
defmodule Hexalixir.Game do |
|
use GenServer |
|
alias Hexalixir.Grid |
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
@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 |
|
|
|
|
|
|
|
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 |
|
|