122 lines
3.6 KiB
Markdown
122 lines
3.6 KiB
Markdown
# Role Playing Game
|
|
|
|
Welcome to Role Playing Game on Exercism's Gleam 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
|
|
|
|
## Options
|
|
|
|
The `Option` type is used to represent values that can either be absent or present.
|
|
|
|
It is defined in the `gleam/option` module as follows:
|
|
|
|
```gleam
|
|
type Option(a) {
|
|
Some(a)
|
|
None
|
|
}
|
|
```
|
|
|
|
The `Some` constructor is used to wrap a value when it's present, and the `None` constructor is used to represent the absence of a value.
|
|
|
|
Accessing the content of a `Option` is often done via pattern matching.
|
|
|
|
```gleam
|
|
import gleam/option.{type Option, None, Some}
|
|
|
|
pub fn say_hello(person: Option(String)) -> String {
|
|
case person {
|
|
Some(name) -> "Hello, " <> name <> "!"
|
|
None -> "Hello, Friend!"
|
|
}
|
|
}
|
|
```
|
|
|
|
```gleam
|
|
say_hello(Some("Matthieu"))
|
|
// -> "Hello, Matthieu!"
|
|
|
|
say_hello(None)
|
|
// -> "Hello, Friend!"
|
|
```
|
|
|
|
The `gleam/option` module also defines a number of useful function for working with `Option` types, such as `unwrap`, which returns the content of an `Option` or a default value if it is `None`.
|
|
|
|
```gleam
|
|
import gleam/option.{type Option}
|
|
|
|
pub fn say_hello_again(person: Option(String)) -> String {
|
|
let name = option.unwrap(person, "Friend")
|
|
"Hello, " <> name <> "!"
|
|
}
|
|
```
|
|
|
|
## Instructions
|
|
|
|
Josh is working on a new role-playing game and needs your help implementing some of the mechanics.
|
|
|
|
## 1. Introduce yourself
|
|
|
|
Implement the `introduce` function.
|
|
|
|
Stealthy players may be hiding their name and will be introduced as `"Mighty Magician"`.
|
|
Otherwise, just use the player's name to introduce them.
|
|
|
|
```gleam
|
|
introduce(Player(name: None, level: 2, health: 8, mana: None))
|
|
// -> "Mighty Magician"
|
|
|
|
introduce(Player(name: Some("Merlin"), level: 2, health: 8, mana: None))
|
|
// -> "Merlin"
|
|
```
|
|
|
|
## 2. Implement the revive mechanic
|
|
|
|
The `revive` function should check that the player's character is indeed dead (their health has reached 0).
|
|
If they are, it should return a new `Player` instance with 100 health.
|
|
Otherwise, if the player's character isn't dead, the `revive` function returns `None`.
|
|
|
|
If the player's level is 10 or above, they should also be revived with 100 mana.
|
|
If the player's level is below 10, their mana should be untouched.
|
|
The `revive` function should preserve the player's level.
|
|
|
|
```gleam
|
|
let dead_player = Player(name: None, level: 2, health: 0, mana: None)
|
|
|
|
revive(dead_player)
|
|
// -> Some(Player(name: None, level: 2, health: 100, mana: None))
|
|
```
|
|
|
|
If the `revive` method is called on a player whose health is 1 or above, then the function should return `None`.
|
|
|
|
```gleam
|
|
let alive_player = Player(name: None, level: 2, health: 42, mana: None)
|
|
|
|
revive(alive_player)
|
|
// -> None
|
|
```
|
|
|
|
## 3. Implement the spell casting mechanic
|
|
|
|
The `cast_spell` function takes as arguments an `Int` indicating how much mana the spell costs as well as a `Player`.
|
|
It returns the updated player, as well as the amount of damage that the cast spell performs.
|
|
A successful spell cast does damage equal to two times the mana cost of the spell.
|
|
However, if the player has insufficient mana, nothing happens, the player is unchanged and no damage is done.
|
|
If the player does not even have a mana pool, attempting to cast the spell must decrease their health by the mana cost of the spell and does no damage.
|
|
Be aware that the players health cannot be below zero (0).
|
|
|
|
```gleam
|
|
let wizard = Player(name: None, level: 18, health: 123, mana: Some(30))
|
|
let #(wizard, damage) = cast_spell(wizard, 14)
|
|
|
|
wizard.mana // -> Some 16
|
|
damage // -> 28
|
|
```
|
|
|
|
## Source
|
|
|
|
### Created by
|
|
|
|
- @lpil |