59 lines
1.6 KiB
Elixir
59 lines
1.6 KiB
Elixir
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
|