Tracks
/
Gleam
Gleam
/
Exercises
/
Role Playing Game
Role Playing Game

Role Playing Game

Learning Exercise

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:

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.

import gleam/option.{type Option, None, Some}

pub fn say_hello(person: Option(String)) -> String {
  case person {
    Some(name) -> "Hello, " <> name <> "!"
    None -> "Hello, Friend!"
  }
}
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.

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.

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.

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.

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).

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
Edit via GitHub The link opens in a new window or tab
Gleam Exercism

Ready to start Role Playing Game?

Sign up to Exercism to learn and master Gleam with 33 concepts, 122 exercises, and real human mentoring, all for free.