Snakes and Ladder - Elixir Game server
defmodule GameServer do | |
use GenServer | |
def start do | |
initial_state = {:players, [], :positions, Map.new, :snakes_and_ladders, [ | |
{:ladder, 5, 15}, {:ladder, 10, 22}, {:ladder, 25, 45}, {:snake, 35, 15}, {:snake, 65, 55}]} | |
GenServer.start_link(__MODULE__, initial_state, name: __MODULE__) | |
end | |
def join(player), do: GenServer.cast(__MODULE__, {:join, player}) | |
def play, do: GenServer.call(__MODULE__, {:play}) | |
def display, do: GenServer.call(__MODULE__, {:display}) | |
def shutdown, do: GenServer.cast(__MODULE__, {:bye}) | |
def handle_cast({:join, player}, state) do | |
{:players, players, :positions, positions, :snakes_and_ladders, snakes_and_ladders} = state | |
{:noreply, {:players, [player | players], :positions, Map.put(positions, player, 1), :snakes_and_ladders, snakes_and_ladders}} | |
end | |
def handle_call({:play}, _from, state) do | |
{:players, players, :positions, positions, :snakes_and_ladders, snakes_and_ladders} = state | |
[current_player | others] = players | |
dice_value = :random.uniform(6) | |
new_position = next_position(positions[current_player] + dice_value, snakes_and_ladders) | |
if new_position < 100 do | |
new_positions = Map.put(positions, current_player, new_position) | |
new_players = others ++ [current_player] | |
{:reply, {current_player, new_position}, {:players, new_players, :positions, new_positions, :snakes_and_ladders, snakes_and_ladders}} | |
else | |
{:reply, {current_player, :winner}, state} | |
end | |
end | |
def handle_call({:display}, _from, state) do | |
{:players, _, :positions, positions, :snakes_and_ladders, _} = state | |
{:reply, positions, state} | |
end | |
def handle_cast({:bye}, state), do: {:stop, :shutdown, state} | |
defp next_position(pos, snakes_and_ladders) do | |
handle_elem(Enum.filter(snakes_and_ladders, fn({_type, from, _to}) -> from == pos end), pos) | |
end | |
defp handle_elem([], pos), do: pos | |
defp handle_elem([{:snake, _, to}], _), do: to | |
defp handle_elem([{:ladder, _, to}], _), do: to | |
end |
This comment has been minimized.
This comment has been minimized.
@sathish316 Any particular reason you are using a tuple for the initial state and not a map?
|
This comment has been minimized.
This comment has been minimized.
@avinasha: No specific reason. I was following the convention of using {:ok , foo} tuples in elixir. Destructuring code could become a lot simpler if i use map. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
For playing game from iex: