From 38e8087b1ca4e7dbb864937a83b37b92187d4960 Mon Sep 17 00:00:00 2001 From: Liru Date: Fri, 20 Apr 2018 22:57:46 -0400 Subject: [PATCH] Finished step 3: Game --- lib/zombie_survivor/game.ex | 30 ++++++++++++++++ test/game_test.exs | 72 +++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 lib/zombie_survivor/game.ex create mode 100644 test/game_test.exs diff --git a/lib/zombie_survivor/game.ex b/lib/zombie_survivor/game.ex new file mode 100644 index 0000000..76c004e --- /dev/null +++ b/lib/zombie_survivor/game.ex @@ -0,0 +1,30 @@ +defmodule ZombieSurvivor.Game do + alias ZombieSurvivor.{Game, Survivor} + + @type t :: %__MODULE__{survivors: %{String.t() => Survivor.t()}} + + defstruct survivors: %{} + + @spec new() :: Game.t() + def new(), do: %Game{} + + @spec add_survivor(Game.t(), Survivor.t()) :: Game.t() + def add_survivor(game, survivor) do + name = survivor.name + + if Map.has_key?(game, name) do + game + else + %{game | survivors: Map.put(game.survivors, name, survivor)} + end + end + + @spec ended?(Game.t()) :: boolean + def ended?(%Game{survivors: survivors}) when map_size(survivors) == 0, do: false + + def ended?(game) do + Enum.all?(game.survivors, fn {_, survivor} -> + Survivor.dead?(survivor) + end) + end +end diff --git a/test/game_test.exs b/test/game_test.exs new file mode 100644 index 0000000..63aac40 --- /dev/null +++ b/test/game_test.exs @@ -0,0 +1,72 @@ +defmodule GameTest do + use ExUnit.Case + alias ZombieSurvivor.{Game, Survivor} + + doctest Game + + @new_survivor Survivor.new(name: "Zombait") + @dead_survivor Survivor.new(name: "Deadman", wounds: 2) + + describe "new/0 starts a game" do + test "that has 0 survivors" do + assert Map.size(Game.new().survivors) == 0 + end + end + + describe "add_survivor/1" do + test "adds a survivor to a game" do + g = + Game.new() + |> Game.add_survivor(@new_survivor) + + assert Map.size(g.survivors) == 1 + + g = + g + |> Game.add_survivor(%{@new_survivor | name: "Larry"}) + + assert Map.size(g.survivors) == 2 + end + + test "ensures that two survivors with the same name can't exist" do + g = + Game.new() + |> Game.add_survivor(@new_survivor) + |> Game.add_survivor(@new_survivor) + + assert Map.size(g.survivors) == 1 + end + end + + describe "ended?/1" do + test "returns true if all its survivors are dead" do + # TODO: Property test, add many dead survivors + g = + Game.new() + |> Game.add_survivor(@dead_survivor) + + assert Game.ended?(g) + + g = + g + |> Game.add_survivor(%{@dead_survivor | name: "Zambee"}) + + assert Game.ended?(g) + end + + test "returns false if at least one survivor is alive" do + g = + Game.new() + |> Game.add_survivor(@new_survivor) + |> Game.add_survivor(@dead_survivor) + + refute Game.ended?(g) + end + + test "returns false if no survivors joined" do + g = Game.new() + + refute Game.ended?(g) + end + end +end