| 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 |
|
|