|
|
|
@ -0,0 +1,98 @@
|
|
|
|
|
use std::io::{
|
|
|
|
|
Write,
|
|
|
|
|
stdin,
|
|
|
|
|
stdout,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// As a dare to myself, I won't use any error-handling crates.
|
|
|
|
|
|
|
|
|
|
#[derive (Debug)]
|
|
|
|
|
enum GameError {
|
|
|
|
|
IoError,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From <std::io::Error> for GameError {
|
|
|
|
|
fn from (_: std::io::Error) -> Self {
|
|
|
|
|
Self::IoError
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Result <T> = std::result::Result <T, GameError>;
|
|
|
|
|
|
|
|
|
|
/// Prints a string, naively wrapping at 80-character boundaries
|
|
|
|
|
/// This means a period might be wrapped separate from the sentence it ends
|
|
|
|
|
/// , and frankly I think that's part of the charm.
|
|
|
|
|
|
|
|
|
|
fn print (mut s: &str) {
|
|
|
|
|
const COLS: usize = 80;
|
|
|
|
|
|
|
|
|
|
while s.len () > COLS {
|
|
|
|
|
println! ("{}", &s [0..80]);
|
|
|
|
|
s = &s [80..];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
println! ("{}", s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn read_input () -> Result <String> {
|
|
|
|
|
{
|
|
|
|
|
let mut stdout = stdout ();
|
|
|
|
|
stdout.write_all (b"> ")?;
|
|
|
|
|
stdout.flush ()?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut buffer = String::new ();
|
|
|
|
|
stdin ().read_line (&mut buffer)?;
|
|
|
|
|
|
|
|
|
|
// I don't know why I need the type annotation here, but I do.
|
|
|
|
|
let x: &[_] = &['\r', '\n'];
|
|
|
|
|
let buffer = buffer.trim_end_matches (x).to_string ();
|
|
|
|
|
|
|
|
|
|
Ok (buffer)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive (Debug, PartialEq)]
|
|
|
|
|
enum PlayerAction {
|
|
|
|
|
Nonsense,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn parse_input (_s: &str) -> PlayerAction {
|
|
|
|
|
PlayerAction::Nonsense
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main () -> Result <()> {
|
|
|
|
|
print ("Welcome to SEROTONIN DEPOSITORY, the only adventure game ever made.");
|
|
|
|
|
print ("");
|
|
|
|
|
print ("You have been consensually kidnapped by a diabolical ADVENTURE GAME ENTHUSIAST and encouraged to solve PUZZLES for their sick PLEASURE. The only winning move is to solve all the PUZZLES.");
|
|
|
|
|
print ("");
|
|
|
|
|
print ("Press ENTER if you dare to begin.");
|
|
|
|
|
|
|
|
|
|
let input = read_input ()?;
|
|
|
|
|
|
|
|
|
|
if ! input.is_empty () {
|
|
|
|
|
print ("That was more than just ENTER but OKAY, overachiever.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
print ("");
|
|
|
|
|
print ("You are in a small room. In one corner is a TABLE. The door behind you is locked. Obvious exits are a DOOR locked by a KEYPAD, and an EMERGENCY EXIT.");
|
|
|
|
|
|
|
|
|
|
let input = read_input ()?;
|
|
|
|
|
let _action = parse_input (&input);
|
|
|
|
|
|
|
|
|
|
Ok (())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg (test)]
|
|
|
|
|
mod test {
|
|
|
|
|
#[test]
|
|
|
|
|
fn parse_input () {
|
|
|
|
|
use super::PlayerAction::*;
|
|
|
|
|
|
|
|
|
|
for (input, expected) in [
|
|
|
|
|
("", Nonsense),
|
|
|
|
|
].into_iter () {
|
|
|
|
|
let actual = super::parse_input (input);
|
|
|
|
|
assert_eq! (actual, expected);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|