Finished step four: Experience and Levels
This commit is contained in:
parent
38e8087b1c
commit
c069557f17
|
|
@ -2,4 +2,16 @@ defmodule ZombieSurvivor do
|
|||
@moduledoc """
|
||||
Documentation for ZombieSurvivor.
|
||||
"""
|
||||
|
||||
@type level :: :blue | :yellow | :orange | :red
|
||||
|
||||
@spec level(non_neg_integer) :: level
|
||||
def level(experience) do
|
||||
case experience do
|
||||
x when x > 42 -> :red
|
||||
x when x > 18 -> :orange
|
||||
x when x > 6 -> :yellow
|
||||
_ -> :blue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27,4 +27,11 @@ defmodule ZombieSurvivor.Game do
|
|||
Survivor.dead?(survivor)
|
||||
end)
|
||||
end
|
||||
|
||||
@spec level(Game.t()) :: ZombieSurvivor.level()
|
||||
def level(game) do
|
||||
game.survivors
|
||||
|> Enum.reduce(0, fn {_, s}, acc -> max(s.experience, acc) end)
|
||||
|> ZombieSurvivor.level()
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ defmodule ZombieSurvivor.Survivor do
|
|||
@type t :: %__MODULE__{
|
||||
name: String.t(),
|
||||
wounds: non_neg_integer,
|
||||
equipment: [String.t()]
|
||||
equipment: [String.t()],
|
||||
experience: non_neg_integer
|
||||
}
|
||||
|
||||
defstruct name: "", wounds: 0, equipment: []
|
||||
defstruct name: "", wounds: 0, equipment: [], experience: 0
|
||||
|
||||
@spec new([{atom, any}]) :: Survivor.t()
|
||||
def new(opts \\ []), do: struct(__MODULE__, opts)
|
||||
|
|
@ -15,6 +16,9 @@ defmodule ZombieSurvivor.Survivor do
|
|||
@spec dead?(Survivor.t()) :: boolean
|
||||
def dead?(survivor), do: survivor.wounds >= 2
|
||||
|
||||
@spec level(Survivor.t()) :: ZombieSurvivor.level()
|
||||
def level(survivor), do: ZombieSurvivor.level(survivor.experience)
|
||||
|
||||
@spec max_actions(Survivor.t()) :: non_neg_integer
|
||||
def max_actions(_survivor) do
|
||||
3
|
||||
|
|
@ -26,6 +30,11 @@ defmodule ZombieSurvivor.Survivor do
|
|||
|> discard_equipment()
|
||||
end
|
||||
|
||||
@spec kill_zombies(Survivor.t(), non_neg_integer) :: Survivor.t()
|
||||
def kill_zombies(survivor, count \\ 1) do
|
||||
%{survivor | experience: survivor.experience + count}
|
||||
end
|
||||
|
||||
@spec max_equipment(Survivor.t()) :: non_neg_integer
|
||||
def max_equipment(%Survivor{} = survivor) do
|
||||
5 - survivor.wounds
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ defmodule GameTest do
|
|||
test "that has 0 survivors" do
|
||||
assert Map.size(Game.new().survivors) == 0
|
||||
end
|
||||
|
||||
test "that's at level blue" do
|
||||
assert Game.level(Game.new()) == :blue
|
||||
end
|
||||
end
|
||||
|
||||
describe "add_survivor/1" do
|
||||
|
|
@ -69,4 +73,32 @@ defmodule GameTest do
|
|||
refute Game.ended?(g)
|
||||
end
|
||||
end
|
||||
|
||||
describe "level/1" do
|
||||
test "returns the level of the highest levelled survivor" do
|
||||
g =
|
||||
Game.new()
|
||||
|> Game.add_survivor(@new_survivor)
|
||||
|
||||
assert Game.level(g) == :blue
|
||||
|
||||
g =
|
||||
g
|
||||
|> Game.add_survivor(Survivor.new(name: "Eric", experience: 10))
|
||||
|
||||
assert Game.level(g) == :yellow
|
||||
|
||||
g =
|
||||
g
|
||||
|> Game.add_survivor(Survivor.new(name: "Jack", experience: 20))
|
||||
|
||||
assert Game.level(g) == :orange
|
||||
|
||||
g =
|
||||
g
|
||||
|> Game.add_survivor(Survivor.new(name: "Liru", experience: 1_000_000))
|
||||
|
||||
assert Game.level(g) == :red
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,6 +14,14 @@ defmodule SurvivorTest do
|
|||
test "gives a survivor with 0 wounds" do
|
||||
assert %Survivor{wounds: 0} = Survivor.new()
|
||||
end
|
||||
|
||||
test "gives a survivor with 0 experience" do
|
||||
assert %Survivor{experience: 0} = Survivor.new()
|
||||
end
|
||||
|
||||
test "gives a survivor at level blue" do
|
||||
assert Survivor.level(Survivor.new()) == :blue
|
||||
end
|
||||
end
|
||||
|
||||
describe "dead?/1" do
|
||||
|
|
@ -35,6 +43,38 @@ defmodule SurvivorTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "kill_zombies/1" do
|
||||
# TODO: Property testing, always increments
|
||||
test "increases experience by 1" do
|
||||
s =
|
||||
Survivor.new()
|
||||
|> Survivor.kill_zombies()
|
||||
|
||||
assert s.experience == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "level/1" do
|
||||
[
|
||||
{:blue, :yellow, 6},
|
||||
{:yellow, :orange, 18},
|
||||
{:orange, :red, 42}
|
||||
]
|
||||
|> Enum.each(fn {old, new, threshold} ->
|
||||
@old old
|
||||
@new new
|
||||
@threshold threshold
|
||||
test "upgrades from #{@old} to #{@new} when exceeding #{@threshold} experience" do
|
||||
s = Survivor.new(experience: @threshold)
|
||||
assert Survivor.level(s) == @old
|
||||
|
||||
s = s |> Survivor.kill_zombies()
|
||||
|
||||
assert Survivor.level(s) == @new
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
describe "max_actions/1" do
|
||||
test "returns 3 for a new survivor" do
|
||||
s = Survivor.new()
|
||||
|
|
|
|||
Loading…
Reference in New Issue