Skip to content

Commit

Permalink
feat: add entity and tests for cancel player
Browse files Browse the repository at this point in the history
  • Loading branch information
dennyabrain committed Jan 28, 2025
1 parent 1dee895 commit 4308ccb
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 36 deletions.
54 changes: 54 additions & 0 deletions lib/viral_spiral/entity/power_cancel_player.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
defmodule ViralSpiral.Entity.PowerCancelPlayer do
@moduledoc """
The Cancel Super Power.
When a Player meets certain criteria, they are allowed to cancel another Player. This takes the following form :
A player initiates cancellation by choosing which player they want to cancel and which of their affinity they want to use for it. The affinity they choose determines who can vote to cancel this player. If the majority votes to cancel the targetted Player, that player will skip a turn.
"""
alias ViralSpiral.Entity.PowerCancelPlayer
alias ViralSpiral.Affinity
import ViralSpiral.Room.EngineConfig.Guards

defstruct state: :idle,
target: nil,
affinity: nil,
votes: [],
result: nil

@type states :: :idle | :waiting | :done

@typedoc "A player's vote for/against the target"
@type vote :: %{id: String.t(), vote: boolean()}

@type t :: %__MODULE__{
state: states(),
target: String.t(),
affinity: Affinity.t(),
votes: list(vote()),
result: boolean()
}

@spec start_vote(t(), String.t(), Affinity.target()) :: t()
def start_vote(%PowerCancelPlayer{} = power, target, affinity) when is_affinity(affinity) do
%{power | target: target, affinity: affinity, state: :waiting}
end

@spec vote(t(), String.t(), boolean()) :: t()
def vote(%PowerCancelPlayer{} = power, player, vote, opts \\ []) do
done = Keyword.get(opts, :done, false)
state = if done, do: :done, else: power.state
%{power | votes: power.votes ++ [%{id: player, vote: vote}], state: state}
end

@spec put_result(t()) :: t()
def put_result(%PowerCancelPlayer{} = power) do
total_votes = length(power.votes)
true_votes = power.votes |> Enum.filter(& &1.vote) |> length()
result = if true_votes / total_votes > 0.5, do: true, else: false
%{power | result: result, state: :done}
end

def reset(%PowerCancelPlayer{} = _power) do
%PowerCancelPlayer{}
end
end
36 changes: 36 additions & 0 deletions test/viral_spiral/entity/power_cancel_player_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule ViralSpiral.Entity.PowerCancelPlayerTest do
alias ViralSpiral.Entity.PowerCancelPlayer
import ViralSpiral.Entity.PowerCancelPlayer
use ExUnit.Case

describe "entity" do
test "happy path" do
power = %PowerCancelPlayer{}
assert power.state == :idle

power = power |> start_vote("player_abc", :cat)
assert power.state == :waiting

power =
power
|> vote("player_def", true)
|> vote("player_jkl", true)

assert power.votes |> length() == 2

power = power |> vote("player_lmn", false, done: true)
assert power.votes |> length() == 3
assert power.state == :done

power = power |> put_result()
assert power.result == true

power = power |> reset()
assert power.state == :idle
assert length(power.votes) == 0
end
end

describe "changes" do
end
end
59 changes: 23 additions & 36 deletions test/viral_spiral/room/reducer_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule ViralSpiral.Room.ReducerTest do
alias ViralSpiral.Entity.Room
use ExUnit.Case

describe "" do
describe "draw card" do
setup do
:rand.seed(:exsss, {123, 135, 254})

Expand All @@ -40,21 +40,6 @@ defmodule ViralSpiral.Room.ReducerTest do
current_player = State.current_round_player(new_state)
assert length(current_player.active_cards) == 1
end

test "keep_card" do
end

test "discard_card" do
end

test "check_source" do
end

test "turn_to_fake" do
end

test "cancel_player" do
end
end

describe "viral spiral" do
Expand Down Expand Up @@ -137,7 +122,6 @@ defmodule ViralSpiral.Room.ReducerTest do
end
end

@tag timeout: :infinity
describe "view source" do
setup do
:rand.seed(:exsss, {12356, 123_534, 345_345})
Expand Down Expand Up @@ -170,25 +154,6 @@ defmodule ViralSpiral.Room.ReducerTest do
end
end

# @tag timeout: :infinity
# test "temp" do
# :rand.seed(:exsss, {12356, 123_534, 345_345})
# store = StateFixtures.new_state()
# store = StateFixtures.set_chaos(store, 4)

# %{adhiraj: adhiraj, aman: aman, farah: farah, krys: krys} =
# StateFixtures.player_by_names(store)

# # draw card of a certain type(?)

# Change.apply_change(store.players[aman.id], Options.change_clout(2))

# # IO.inspect(store.round)
# # IO.inspect(store.turn)
# # IO.inspect(store.players)
# # IO.inspect(store.room)
# end

describe "mark as fake" do
setup do
state = %State{
Expand Down Expand Up @@ -322,4 +287,26 @@ defmodule ViralSpiral.Room.ReducerTest do
# todo assert headline too
end
end

describe "cancel someone" do
setup do
state = StateFixtures.new_game()
state = %{state | deck: Factory.new_deck(state.room)}

%{state: state}
end

@tag timeout: :infinity
test "get one player to vote", %{state: state} do
IO.inspect(state)
require IEx
IEx.pry()
# apply initiate_cancel action to state
# apply cancel_vote action to state
# compare final state
end

test "get more than one player to vote" do
end
end
end

0 comments on commit 4308ccb

Please sign in to comment.