exercism/elixir/bread-and-potions/README.md

82 lines
2.7 KiB
Markdown

# Bread And Potions
Welcome to Bread And Potions on Exercism's Elixir Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
## Protocols
Protocols are a mechanism to achieve polymorphism in Elixir when you want behavior to vary depending on the data type.
Protocols are defined using `defprotocol` and contain one or more function headers.
```elixir
defprotocol Reversible do
def reverse(term)
end
```
Protocols can be implemented using `defimpl`.
```elixir
defimpl Reversible, for: List do
def reverse(term) do
Enum.reverse(term)
end
end
```
A protocol can be implemented for any existing Elixir data type or for a struct.
When a protocol function is invoked, the appropriate implementation gets automatically chosen based on the type of the first argument.
## Instructions
You're developing your own role-playing video game. In your game, there are _characters_ and _items_. One of the many actions that you can do with an item is to make a character eat it.
Not all items are edible, and not all edible items have the same effects on the character. Some items, when eaten, turn into a different item (e.g. if you eat an apple, you are left with an apple core).
To allow for all that flexibility, you decided to create an `Edible` protocol that some of the items can implement.
## 1. Define edibility
Create the `RPG.Edible` protocol. The protocol has one function - `eat`. The `eat` function accepts an item and a character and returns a by-product and a character.
## 2. Make loaves of bread edible
Implement the `RPG.Edible` protocol for the `RPG.LoafOfBread` item. When eaten, a loaf of bread gives the character 5 health points and has no by-product.
```elixir
RPG.Edible.eat(%RPG.LoafOfBread{}, %RPG.Character{health: 31})
# => {nil, %RPG.Character{health: 36, mana: 0}}
```
## 3. Make mana potions edible
Implement the `RPG.Edible` protocol for the `RPG.ManaPotion` item. When eaten, a mana potion gives the character as many mana points as the potion's strength, and produces an empty bottle.
```elixir
RPG.Edible.eat(%RPG.ManaPotion{strength: 13}, %RPG.Character{mana: 50})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 100, mana: 63}}
```
## 4. Make poisons edible
Implement the `RPG.Edible` protocol for the `RPG.Poison` item. When eaten, a poison takes away all the health points from the character, and produces an empty bottle.
```elixir
RPG.Edible.eat(%RPG.Poison{}, %RPG.Character{health: 3000})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 0, mana: 0}}
```
## Source
### Created by
- @angelikatyborska
### Contributed to by
- @neenjaw