♻️ refactor
parent
1ddb5ffe18
commit
576cf0b4e5
209
src/main.rs
209
src/main.rs
|
@ -72,8 +72,13 @@ fn just <T> (t: T) -> Vec <T> {
|
|||
enum PlayerAction {
|
||||
Quit,
|
||||
Help,
|
||||
Hint,
|
||||
Nonsense,
|
||||
RoomSpecific (PlayerActionRoomSpecific),
|
||||
}
|
||||
|
||||
#[derive (Debug, PartialEq)]
|
||||
enum PlayerActionRoomSpecific {
|
||||
Hint,
|
||||
Wait,
|
||||
Look (ItemName),
|
||||
LookAround,
|
||||
|
@ -104,79 +109,96 @@ fn _item_name_display (x: ItemName) -> &'static str {
|
|||
}
|
||||
|
||||
fn parse_input (s: &str) -> PlayerAction {
|
||||
use PlayerAction::*;
|
||||
use PlayerActionRoomSpecific::*;
|
||||
|
||||
let s = s.to_lowercase ();
|
||||
|
||||
if s == "quit" || s == "quit game" {
|
||||
return PlayerAction::Quit;
|
||||
Quit
|
||||
}
|
||||
|
||||
if s == "look" || s == "look around" {
|
||||
return PlayerAction::LookAround;
|
||||
else if s == "help" || s == "help me" {
|
||||
Help
|
||||
}
|
||||
|
||||
if let Some (rest) = s.strip_prefix ("look at the ") {
|
||||
return PlayerAction::Look (parse_item_name (rest));
|
||||
else if s == "look" || s == "look around" {
|
||||
RoomSpecific (LookAround)
|
||||
}
|
||||
|
||||
if let Some (rest) = s.strip_prefix ("look at ") {
|
||||
return PlayerAction::Look (parse_item_name (rest));
|
||||
else if let Some (rest) = s.strip_prefix ("look at the ") {
|
||||
RoomSpecific (Look (parse_item_name (rest)))
|
||||
}
|
||||
|
||||
if let Some (rest) = s.strip_prefix ("look ") {
|
||||
return PlayerAction::Look (parse_item_name (rest));
|
||||
else if let Some (rest) = s.strip_prefix ("look at ") {
|
||||
RoomSpecific (Look (parse_item_name (rest)))
|
||||
}
|
||||
|
||||
if let Some (rest) = s.strip_prefix ("examine ") {
|
||||
return PlayerAction::Look (parse_item_name (rest));
|
||||
else if let Some (rest) = s.strip_prefix ("look ") {
|
||||
RoomSpecific (Look (parse_item_name (rest)))
|
||||
}
|
||||
|
||||
if let Some (rest) = s.strip_prefix ("use the ") {
|
||||
return PlayerAction::Use (parse_item_name (rest));
|
||||
else if let Some (rest) = s.strip_prefix ("examine ") {
|
||||
RoomSpecific (Look (parse_item_name (rest)))
|
||||
}
|
||||
|
||||
if let Some (rest) = s.strip_prefix ("use ") {
|
||||
return PlayerAction::Use (parse_item_name (rest));
|
||||
else if let Some (rest) = s.strip_prefix ("use the ") {
|
||||
RoomSpecific (Use (parse_item_name (rest)))
|
||||
}
|
||||
|
||||
if s == "do nothing" {
|
||||
return PlayerAction::Wait;
|
||||
else if let Some (rest) = s.strip_prefix ("use ") {
|
||||
RoomSpecific (Use (parse_item_name (rest)))
|
||||
}
|
||||
if s == "wait" {
|
||||
return PlayerAction::Wait;
|
||||
else if
|
||||
s == "do nothing" ||
|
||||
s == "wait"
|
||||
{
|
||||
RoomSpecific (Wait)
|
||||
}
|
||||
|
||||
if s == "help" {
|
||||
return PlayerAction::Help;
|
||||
else if s == "hint" {
|
||||
RoomSpecific (Hint)
|
||||
}
|
||||
if s == "hint" {
|
||||
return PlayerAction::Hint;
|
||||
else {
|
||||
Nonsense
|
||||
}
|
||||
|
||||
PlayerAction::Nonsense
|
||||
}
|
||||
|
||||
fn parse_item_name (s: &str) -> ItemName {
|
||||
if s == "door" {
|
||||
return ItemName::Door;
|
||||
ItemName::Door
|
||||
}
|
||||
|
||||
if s == "emergency exit" {
|
||||
return ItemName::EmergencyExit;
|
||||
else if s == "emergency exit" {
|
||||
ItemName::EmergencyExit
|
||||
}
|
||||
|
||||
if s == "keypad" {
|
||||
return ItemName::Keypad;
|
||||
else if s == "keypad" {
|
||||
ItemName::Keypad
|
||||
}
|
||||
|
||||
if s == "note" {
|
||||
return ItemName::Note;
|
||||
else if s == "note" {
|
||||
ItemName::Note
|
||||
}
|
||||
|
||||
if s == "table" {
|
||||
return ItemName::Table;
|
||||
else if s == "table" {
|
||||
ItemName::Table
|
||||
}
|
||||
|
||||
else {
|
||||
ItemName::Nonsense
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! require_detection {
|
||||
($condition:expr $(,)?) => {
|
||||
if ! $condition {
|
||||
return vec! [
|
||||
Response::FailedDetectionCheck,
|
||||
undetected_item (),
|
||||
];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive (Clone)]
|
||||
enum RoomName {
|
||||
/// Starting room with the dead-simple note and keypad puzzle.
|
||||
Room1,
|
||||
/// Duplicate of starting room so I can change things around a little.
|
||||
Room2,
|
||||
}
|
||||
|
||||
impl Default for RoomName {
|
||||
fn default () -> Self {
|
||||
Self::Room1
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Clone, Default)]
|
||||
|
@ -199,55 +221,41 @@ enum Response {
|
|||
FailedDetectionCheck,
|
||||
}
|
||||
|
||||
macro_rules! require_detection {
|
||||
($condition:expr $(,)?) => {
|
||||
if ! $condition {
|
||||
return vec! [
|
||||
Response::FailedDetectionCheck,
|
||||
undetected_item (),
|
||||
];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive (Clone, Default)]
|
||||
struct State {
|
||||
current_room: RoomName,
|
||||
room_1: StateRoom1,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn step (&mut self, input: &str) -> Vec <Response> {
|
||||
self.room_1 (input)
|
||||
}
|
||||
|
||||
fn room_1 (&mut self, input: &str) -> Vec <Response> {
|
||||
use Response::*;
|
||||
|
||||
let action = parse_input (input);
|
||||
|
||||
match action {
|
||||
PlayerAction::Quit => {
|
||||
vec! [
|
||||
PlayerAction::Quit => vec! [
|
||||
line_response ("Bye."),
|
||||
Quit,
|
||||
]
|
||||
}
|
||||
PlayerAction::Help => {
|
||||
just (print_help ())
|
||||
},
|
||||
PlayerAction::Hint => {
|
||||
just (line_response ("Hint for this room: Try using the `help` command."))
|
||||
},
|
||||
PlayerAction::Nonsense => {
|
||||
vec! [
|
||||
Response::Quit,
|
||||
],
|
||||
PlayerAction::Help => just (print_help ()),
|
||||
PlayerAction::Nonsense => vec! [
|
||||
line_response ("I couldn't understand that. Try `help` or `hint`."),
|
||||
line_response ("`hint` may contain spoilers. `help` will not."),
|
||||
]
|
||||
],
|
||||
PlayerAction::RoomSpecific (x) => self.room_1 (x),
|
||||
}
|
||||
}
|
||||
|
||||
fn room_1 (&mut self, action: PlayerActionRoomSpecific) -> Vec <Response> {
|
||||
use PlayerActionRoomSpecific::*;
|
||||
|
||||
match action {
|
||||
Hint => {
|
||||
just (line_response ("Hint for this room: Try using the `help` command."))
|
||||
},
|
||||
PlayerAction::Wait => {
|
||||
Wait => {
|
||||
just (line_response ("You wait around a bit. You can hear humming from the electrical lights, and the distant rumble of the building's HVAC system. The room smells faintly of fresh paint. Nothing has changed."))
|
||||
},
|
||||
PlayerAction::LookAround => {
|
||||
LookAround => {
|
||||
let mut output = vec! [
|
||||
line_response ("You are in a small room. In one corner is a TABLE. Obvious exits are a DOOR, and an EMERGENCY EXIT."),
|
||||
];
|
||||
|
@ -261,7 +269,7 @@ impl State {
|
|||
|
||||
output
|
||||
}
|
||||
PlayerAction::Look (item_name) => {
|
||||
Look (item_name) => {
|
||||
match item_name {
|
||||
ItemName::Door => {
|
||||
self.room_1.detected_keypad = true;
|
||||
|
@ -299,18 +307,14 @@ impl State {
|
|||
},
|
||||
ItemName::Table => {
|
||||
self.room_1.detected_note = true;
|
||||
vec! [
|
||||
Response::Print ("You look at the TABLE. Your instincts tell you that it is period-accurate. Upon the TABLE sits a NOTE.".into ()),
|
||||
]
|
||||
just (line_response ("You look at the TABLE. Your instincts tell you that it is period-accurate. Upon the TABLE sits a NOTE."))
|
||||
},
|
||||
_ => {
|
||||
vec! [
|
||||
undetected_item (),
|
||||
]
|
||||
just (undetected_item ())
|
||||
},
|
||||
}
|
||||
},
|
||||
PlayerAction::Use (item_name) => {
|
||||
Use (item_name) => {
|
||||
match item_name {
|
||||
ItemName::Door => {
|
||||
let mut output = vec! [
|
||||
|
@ -319,18 +323,18 @@ impl State {
|
|||
|
||||
if ! self.room_1.detected_keypad {
|
||||
self.room_1.detected_keypad = true;
|
||||
output.push (Response::Print ("You notice an electronic KEYPAD on the DOOR.".into ()));
|
||||
output.push (line_response ("You notice an electronic KEYPAD on the DOOR."));
|
||||
}
|
||||
|
||||
output
|
||||
},
|
||||
ItemName::EmergencyExit => {
|
||||
vec! [
|
||||
Response::Print ("You push on the emergency exit. An alarm starts sounding. Your ADVENTURE GAME ENTHUSIAST friend is going to be very mad at you.".into ()),
|
||||
line_response ("You push on the emergency exit. An alarm starts sounding. Your ADVENTURE GAME ENTHUSIAST friend is going to be very mad at you."),
|
||||
Response::Sleep (5000),
|
||||
Response::Print ("The alarm is still sounding. You are getting embarrassed, but you have committed to this path of action.".into ()),
|
||||
line_response ("The alarm is still sounding. You are getting embarrassed, but you have committed to this path of action."),
|
||||
Response::Sleep (5000),
|
||||
Response::Print ("The emergency exit unlocks, and you walk out of the game. Bye.".into ()),
|
||||
line_response ("The emergency exit unlocks, and you walk out of the game. Bye."),
|
||||
Response::JokeEnding,
|
||||
Response::Quit,
|
||||
]
|
||||
|
@ -353,9 +357,7 @@ impl State {
|
|||
just (line_response ("You can't think of any way to USE the TABLE that would be better than LOOKing at it."))
|
||||
},
|
||||
_ => {
|
||||
vec! [
|
||||
undetected_item (),
|
||||
]
|
||||
just (undetected_item ())
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -426,17 +428,18 @@ mod test {
|
|||
use super::{
|
||||
ItemName,
|
||||
PlayerAction::*,
|
||||
PlayerActionRoomSpecific::*,
|
||||
};
|
||||
|
||||
for (input, expected) in [
|
||||
("", Nonsense),
|
||||
("look at the table", Look (ItemName::Table)),
|
||||
("look at table", Look (ItemName::Table)),
|
||||
("look table", Look (ItemName::Table)),
|
||||
("LOOK TABLE", Look (ItemName::Table)),
|
||||
("wait", Wait),
|
||||
("help", Help),
|
||||
("hint", Hint),
|
||||
("look at the table", RoomSpecific (Look (ItemName::Table))),
|
||||
("look at table", RoomSpecific (Look (ItemName::Table))),
|
||||
("look table", RoomSpecific (Look (ItemName::Table))),
|
||||
("LOOK TABLE", RoomSpecific (Look (ItemName::Table))),
|
||||
("wait", RoomSpecific (Wait)),
|
||||
("hint", RoomSpecific (Hint)),
|
||||
].into_iter () {
|
||||
let actual = super::parse_input (input);
|
||||
assert_eq! (actual, expected);
|
||||
|
|
Loading…
Reference in New Issue