defmodule RPG do defmodule Character do defstruct health: 100, mana: 0 end defmodule LoafOfBread do defstruct [] end defmodule ManaPotion do defstruct strength: 10 end defmodule Poison do defstruct [] end defmodule EmptyBottle do defstruct [] end # Add code to define the protocol and its implementations below here... defprotocol Edible do @moduledoc """ Protocol definition for interaction between Characters and Items """ @type item() :: LoafOfBread.t() | ManaPotion.t() | Poison.t() | EmptyBottle.t() @spec eat(item(), Character.t()) :: {nil | item(), Character.t()} def eat(item, character) end defimpl Edible, for: LoafOfBread do @moduledoc """ Edible implimentation for LoafOfBread """ @spec eat(LoafOfBread.t(), Character.t()) :: {nil, Character.t()} def eat(%LoafOfBread{}, %Character{health: health} = character), do: {nil, %{character | health: health + 5}} end defimpl Edible, for: ManaPotion do @moduledoc """ Edible implimentation for ManaPotion """ @spec eat(ManaPotion.t(), Character.t()) :: {EmptyBottle.t(), Character.t()} def eat(%ManaPotion{strength: strength}, %Character{mana: mana} = character), do: {%EmptyBottle{}, %{character | mana: mana + strength}} end defimpl Edible, for: Poison do @moduledoc """ Edible implimentation for Poison """ @spec eat(Poison.t(), Character.t()) :: {EmptyBottle.t(), Character.t()} def eat(%Poison{}, %Character{} = character), do: {%EmptyBottle{}, %{character | health: 0}} end end