From 2e7682c503b8abe2a2fcce11b28d6ac79944837f Mon Sep 17 00:00:00 2001 From: Liru Date: Fri, 20 Apr 2018 22:09:15 -0400 Subject: [PATCH] Finished step two: equipment --- lib/zombie_survivor/survivor.ex | 34 +++++++++++++++++-- test/survivor_test.exs | 58 +++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/lib/zombie_survivor/survivor.ex b/lib/zombie_survivor/survivor.ex index 8d6e31d..999274c 100644 --- a/lib/zombie_survivor/survivor.ex +++ b/lib/zombie_survivor/survivor.ex @@ -3,10 +3,11 @@ defmodule ZombieSurvivor.Survivor do @type t :: %__MODULE__{ name: String.t(), - wounds: non_neg_integer + wounds: non_neg_integer, + equipment: [String.t()] } - defstruct name: "", wounds: 0 + defstruct name: "", wounds: 0, equipment: [] @spec new([{atom, any}]) :: Survivor.t() def new(opts \\ []), do: struct(__MODULE__, opts) @@ -18,4 +19,33 @@ defmodule ZombieSurvivor.Survivor do def max_actions(_survivor) do 3 end + + @spec wound(Survivor.t(), non_neg_integer) :: Survivor.t() + def wound(survivor, num \\ 1) do + %{survivor | wounds: survivor.wounds + num} + |> discard_equipment() + end + + @spec max_equipment(Survivor.t()) :: non_neg_integer + def max_equipment(%Survivor{} = survivor) do + 5 - survivor.wounds + end + + @spec add_equipment(Survivor.t(), String.t() | [String.t()]) :: Survivor.t() + def add_equipment(%Survivor{equipment: equipment} = survivor, new_items) + when is_list(new_items) do + %{survivor | equipment: Enum.concat(new_items, equipment)} + |> discard_equipment() + end + + def add_equipment(%Survivor{equipment: equipment} = survivor, new_item) do + %{survivor | equipment: [new_item | equipment]} + |> discard_equipment() + end + + @spec discard_equipment(Survivor.t()) :: Survivor.t() + def discard_equipment(%Survivor{equipment: equipment} = survivor) do + max = max_equipment(survivor) + %{survivor | equipment: Enum.take(equipment, max)} + end end diff --git a/test/survivor_test.exs b/test/survivor_test.exs index e2d5373..4bf445c 100644 --- a/test/survivor_test.exs +++ b/test/survivor_test.exs @@ -4,6 +4,8 @@ defmodule SurvivorTest do import Survivor + @items ["Baseball bat", "Frying pan", "Katana", "Pistol", "Bottled Water", "Molotov"] + describe "new" do test "gives a survivor with a name" do assert %Survivor{name: _} = Survivor.new() @@ -39,4 +41,60 @@ defmodule SurvivorTest do assert Survivor.max_actions(s) == 3 end end + + describe "max_equipment/1" do + test "returns 5 for a new survivor" do + assert 5 == max_equipment(Survivor.new()) + end + + test "returns fewer items with more wounds" do + s = + Survivor.new() + |> Survivor.wound() + + assert max_equipment(s) == 4 + end + end + + describe "wound/1" do + # TODO: Property testing with increments + test "adds wounds to survivors (duh)" do + s = + Survivor.new() + |> wound() + + assert %{wounds: 1} = s + end + + test "drops survivor equipment if they are carrying too much" do + # TODO: Property testing + # kinda funky if max_equipment rules change, will fix later + s = + Survivor.new() + |> add_equipment(@items) + + max = max_equipment(s) + assert max == length(s.equipment) + + s = + s + |> wound + + assert max - 1 == length(s.equipment) + end + + test "doesn't drop survivor equipment if they aren't carrying too much" do + s = + Survivor.new() + |> add_equipment("Corncob") + + assert 1 == length(s.equipment) + + s = + s + |> wound + + assert 1 == length(s.equipment) + end + end end