From 943295d116c7f473d20c03a3a94d140dc1cc6a75 Mon Sep 17 00:00:00 2001 From: dennyabrain Date: Wed, 14 Aug 2024 09:42:45 +0530 Subject: [PATCH] feat: add multiple simultaneous turns --- lib/viral_spiral/game/turn.ex | 28 +++++++++++++++++++--- test/viral_spiral/turn_test.exs | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 test/viral_spiral/turn_test.exs diff --git a/lib/viral_spiral/game/turn.ex b/lib/viral_spiral/game/turn.ex index 6576c10..6586a49 100644 --- a/lib/viral_spiral/game/turn.ex +++ b/lib/viral_spiral/game/turn.ex @@ -13,6 +13,17 @@ defmodule ViralSpiral.Game.Turn do defstruct current: nil, pass_to: [] + @type t :: %__MODULE__{ + current: String.t(), + pass_to: list(String.t()) + } + + @spec new() :: Turn.t() + def new() do + %Turn{} + end + + @spec new(Round.t()) :: Turn.t() def new(%Round{} = round) do current = Enum.at(round.order, round.current) @@ -25,20 +36,31 @@ defmodule ViralSpiral.Game.Turn do def new(%Round{} = _round, %Turn{} = _turn) do end - def set_current(%Turn{} = round, current), do: %{round | current: current} + def set_current(%Turn{} = turn, current), do: %{turn | current: current} - def set_pass_to(%Turn{} = round, pass_to), do: %{round | pass_to: pass_to} + def set_pass_to(%Turn{} = turn, pass_to), do: %{turn | pass_to: pass_to} @doc """ todo : add check to ensure that it only runs next if to is in the the current pass_to """ - def next(%Turn{} = from, to) do + @spec next(Turn.t(), String.t()) :: Turn.t() + def next(%Turn{} = from, to) when is_bitstring(to) do from |> set_current(to) |> set_pass_to(List.delete(from.pass_to, to)) end + @spec next(Turn.t(), list(String.t())) :: list(Turn.t()) + def next(%Turn{} = from, to) when is_list(to) do + new_pass_to = from.pass_to -- to + + Enum.map( + to, + &%Turn{current: &1, pass_to: new_pass_to} + ) + end + def change(%Turn{} = _turn) do end end diff --git a/test/viral_spiral/turn_test.exs b/test/viral_spiral/turn_test.exs new file mode 100644 index 0000000..877d653 --- /dev/null +++ b/test/viral_spiral/turn_test.exs @@ -0,0 +1,42 @@ +defmodule ViralSpiral.TurnTest do + alias ViralSpiral.Game.Turn + alias ViralSpiral.Game.Round + use ExUnit.Case + + describe "Turn Management" do + test "pass card" do + game = Fixtures.initialized_game() + player_list = game.player_list + round = Round.new(player_list) + turn = Turn.new(round) + assert length(turn.pass_to) == 3 + + current_player = Enum.at(round.order, round.current) + + pass_to = + Enum.filter(player_list, &(&1.id != current_player)) + |> Enum.shuffle() + |> Enum.take(1) + |> Enum.at(0) + + turn = Turn.next(turn, pass_to.id) + assert length(turn.pass_to) == 2 + end + + @tag timeout: :infinity + test "pass card to multiple people during viral spiral special power" do + game = Fixtures.initialized_game() + player_list = game.player_list + round = Round.new(player_list) + turn = Turn.new(round) + assert length(turn.pass_to) == 3 + + current_player = Enum.at(round.order, 0) + to_pass_players = Enum.slice(round.order, 1..2) + turn = Turn.next(turn, to_pass_players) + + assert length(turn) == 2 + assert length(Enum.at(turn, 0).pass_to) == 1 + end + end +end