use epkard::*;
#[derive(Serialize, Deserialize)]
struct State {
has_key: bool,
}
#[derive(Clone, Serialize, Deserialize)]
enum Room {
Start,
Side,
Exit,
}
impl Node for Room {
type State = State;
fn next<F>(self, rt: &mut Runtime<Self, F>) -> Control<Self>
where
F: Frontend,
{
rt.clear();
match self {
Room::Start => {
rt.println("You are in a room.");
rt.wait()?;
let next_room = rt.multiple_choice_named(
"Where do you want to go?",
vec![
("The door with light behind it", Room::Exit),
("The door with no light behind it", Room::Side),
],
)?;
next(next_room)
}
Room::Side => {
rt.println(if rt.has_key {
"There is nothing here."
} else {
"There is a key on the floor."
});
rt.wait()?;
let pick_up_key = rt.multiple_choice_named(
"What do you want to do?",
Some(("Pick up the key", true))
.filter(|_| !rt.has_key)
.into_iter()
.chain(Some(("Go back through the door", false))),
)?;
if pick_up_key {
rt.has_key = true;
next(Room::Side)
} else {
next(Room::Start)
}
}
Room::Exit => {
rt.println("There is another door with a bright light behind it.");
rt.wait()?;
let try_to_leave = rt.multiple_choice_named(
"Where do you want to go?",
vec![
("Through the door ahead", true),
("Back through the door you came in", false),
],
)?;
if try_to_leave {
if rt.has_key {
rt.println("The door is locked. You unlock the door with your key.");
rt.wait()?;
rt.println("You escaped! You win!");
rt.wait()?;
exit()
} else {
rt.println("The door is locked.");
rt.wait()?;
next(Room::Exit)
}
} else {
next(Room::Start)
}
}
}
}
}
#[derive(Clone)]
struct Inventory;
impl Node for Inventory {
type State = State;
fn next<F>(self, rt: &mut Runtime<Self, F>) -> Control<Self>
where
F: Frontend,
{
if rt.has_key {
rt.println("You have a key");
} else {
rt.println("You have nothing");
}
exit()
}
}
fn main() {
run(
Room::Start,
&mut State { has_key: false },
&mut CliFrontend::new(),
)
.command("save", |rt| {
match rt.save("rooms.yaml") {
Ok(_) => rt.println("Save complete"),
Err(e) => rt.println(format!("Error: {}", e)),
}
Continue
})
.command("load", |rt| {
match rt.load("rooms.yaml") {
Ok(_) => rt.println("Load complete"),
Err(e) => rt.println(format!("Error: {}", e)),
}
Skip
})
.command("inv, inventory", |rt| rt.push_node(Inventory));
}