Packages

Perudex is a library implementing the game Perudo, also known as Dudo or Liar's Dice (which you may have heard of in the Pirates of the Caribbean movie).

Current section

Files

Jump to
perudex lib game_server.ex
Raw

lib/game_server.ex

defmodule Perudex.GameServer do
@moduledoc """
This module is a GenServer implementation to control the Perudo game state.
"""
use GenServer, restart: :transient
alias Perudex.{Game, NotifierServer}
@type id :: any
@type player :: %{id: any, callback_mod: module, callback_arg: any}
@type callback_arg :: any
@impl true
def init({id, players_ids}),
do: {:ok, players_ids |> Game.start(5) |> handle_move_result(%{id: id, game: nil})}
def start_link({id, players}),
do: GenServer.start_link(__MODULE__, {id, Enum.map(players, & &1.id)}, name: service_name(id))
@spec move(id, Game.player_id(), Game.move()) :: any
def move(game_id, player_id, move),
do: GenServer.call(service_name(game_id), {:move, player_id, move})
@impl true
def handle_call({:move, player_id, move}, _from, state),
do:
{:reply, :ok,
state.game
|> Game.play_move(player_id, move)
|> handle_move_result(state)}
defp handle_move_result({instructions, game}, state),
do: Enum.reduce(instructions, %{state | game: game}, &handle_instruction(&2, &1))
defp handle_instruction(state, {:notify_player, player_id, instruction_payload}) do
NotifierServer.publish(state.id, player_id, instruction_payload)
state
end
defp service_name(game_id), do: Perudex.service_name({__MODULE__, game_id})
end