rooms/
rooms.rs

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}