Chapter 6: Patterns all the way down
Role playing game
- partial record patterns
- as
- Option
This one shows off Bea's record patterns. Player(name: None |
_) matches any player whose name is None and ignores
the other fields. The | _ means "and the rest".
as p keeps the whole value while you take it apart, so
Player(p | health: 100) can rebuild it with one field changed.
Guards still apply: revive treats high-level players
differently.
pub type Player {
Player(
name: Option(String),
level: Int,
health: Int,
mana: Option(Int)
)
}
pub def introduce(Player(name: None | _)) {
"Mighty Magician"
}
pub def introduce(Player(name: Some(v) | _)) {
v
}
pub def revive(Player(health: 0, level: l | _) as p) if l >= 10 {
Some(Player(p | health: 100, mana: Some(100)))
}
pub def revive(Player(health: 0 | _) as p) {
Some(Player(p | health: 100))
}
pub def revive(_) {
None
}
pub def cast_spell(Player(mana: None, health: h | _) as p, cost) {
updated_health = if h - cost < 0 {
0
} else {
h - cost
}
(Player(p | health: updated_health), 0)
}
pub def cast_spell(Player(mana: Some(m) | _) as p, cost) if m < cost {
(p, 0)
}
pub def cast_spell(Player(mana: Some(m) | _) as p, cost) {
(Player(p | mana: Some(m - cost)), 2 * cost)
}
pub def main() {
echo introduce(Player(name: None, level: 2, health: 8, mana: None))
dead_player = Player(name: None, level: 2, health: 0, mana: None)
echo revive(dead_player)
alive_player = Player(name: None, level: 2, health: 42, mana: None)
echo revive(alive_player)
wizard = Player(name: None, level: 18, health: 123, mana: Some(30))
echo cast_spell(wizard, 14)
}import gleam/option.{type Option, None, Some}
pub type Player {
Player(name: Option(String), level: Int, health: Int, mana: Option(Int))
}
pub fn introduce(arg_0) {
case arg_0 {
Player(name: None, ..) -> "Mighty Magician"
Player(name: Some(v), ..) -> v
}
}
pub fn revive(arg_0) {
case arg_0 {
Player(health: 0, level: l, ..) as p if l >= 10 ->
Some(Player(..p, health: 100, mana: Some(100)))
Player(health: 0, ..) as p -> Some(Player(..p, health: 100))
_ -> None
}
}
pub fn cast_spell(arg_0, cost) {
case arg_0 {
Player(mana: None, health: h, ..) as p -> {
let updated_health = case h - cost < 0 {
True -> 0
False -> h - cost
}
#(Player(..p, health: updated_health), 0)
}
Player(mana: Some(m), ..) as p if m < cost -> #(p, 0)
Player(mana: Some(m), ..) as p ->
#(Player(..p, mana: Some(m - cost)), 2 * cost)
}
}
pub fn main() {
echo introduce(Player(name: None, level: 2, health: 8, mana: None))
let dead_player = Player(name: None, level: 2, health: 0, mana: None)
echo revive(dead_player)
let alive_player = Player(name: None, level: 2, health: 42, mana: None)
echo revive(alive_player)
let wizard = Player(name: None, level: 18, health: 123, mana: Some(30))
echo cast_spell(wizard, 14)
}src/e21_role_playing.bea:49
"Mighty Magician"
src/e21_role_playing.bea:51
Some(Player(None, 2, 100, None))
src/e21_role_playing.bea:53
None
src/e21_role_playing.bea:55
#(Player(None, 18, 123, Some(16)), 28)An exercism exercise from the Gleam track, solved in Bea: beacode/src/e21_role_playing.bea