1use epkard::*;
2
3#[derive(Serialize, Deserialize)]
4struct State {
5 has_key: bool,
6}
7
8#[derive(Clone, Serialize, Deserialize)]
9enum Room {
10 Start,
11 Side,
12 Exit,
13}
14
15impl Node for Room {
16 type State = State;
17 fn next<F>(self, rt: &mut Runtime<Self, F>) -> Control<Self>
18 where
19 F: Frontend,
20 {
21 rt.clear();
22 match self {
23 Room::Start => {
24 rt.println("You are in a room.");
25 rt.wait()?;
26 let next_room = rt.multiple_choice_named(
27 "Where do you want to go?",
28 vec![
29 ("The door with light behind it", Room::Exit),
30 ("The door with no light behind it", Room::Side),
31 ],
32 )?;
33 next(next_room)
34 }
35 Room::Side => {
36 rt.println(if rt.has_key {
37 "There is nothing here."
38 } else {
39 "There is a key on the floor."
40 });
41 rt.wait()?;
42 let pick_up_key = rt.multiple_choice_named(
43 "What do you want to do?",
44 Some(("Pick up the key", true))
45 .filter(|_| !rt.has_key)
46 .into_iter()
47 .chain(Some(("Go back through the door", false))),
48 )?;
49 if pick_up_key {
50 rt.has_key = true;
51 next(Room::Side)
52 } else {
53 next(Room::Start)
54 }
55 }
56 Room::Exit => {
57 rt.println("There is another door with a bright light behind it.");
58 rt.wait()?;
59 let try_to_leave = rt.multiple_choice_named(
60 "Where do you want to go?",
61 vec![
62 ("Through the door ahead", true),
63 ("Back through the door you came in", false),
64 ],
65 )?;
66 if try_to_leave {
67 if rt.has_key {
68 rt.println("The door is locked. You unlock the door with your key.");
69 rt.wait()?;
70 rt.println("You escaped! You win!");
71 rt.wait()?;
72 exit()
73 } else {
74 rt.println("The door is locked.");
75 rt.wait()?;
76 next(Room::Exit)
77 }
78 } else {
79 next(Room::Start)
80 }
81 }
82 }
83 }
84}
85
86#[derive(Clone)]
87struct Inventory;
88
89impl Node for Inventory {
90 type State = State;
91 fn next<F>(self, rt: &mut Runtime<Self, F>) -> Control<Self>
92 where
93 F: Frontend,
94 {
95 if rt.has_key {
96 rt.println("You have a key");
97 } else {
98 rt.println("You have nothing");
99 }
100 exit()
101 }
102}
103
104fn main() {
105 run(
106 Room::Start,
107 &mut State { has_key: false },
108 &mut CliFrontend::new(),
109 )
110 .command("save", |rt| {
111 match rt.save("rooms.yaml") {
112 Ok(_) => rt.println("Save complete"),
113 Err(e) => rt.println(format!("Error: {}", e)),
114 }
115 Continue
116 })
117 .command("load", |rt| {
118 match rt.load("rooms.yaml") {
119 Ok(_) => rt.println("Load complete"),
120 Err(e) => rt.println(format!("Error: {}", e)),
121 }
122 Skip
123 })
124 .command("inv, inventory", |rt| rt.push_node(Inventory));
125}