103 lines
2.1 KiB
Rust
103 lines
2.1 KiB
Rust
use kajam_10_game::{
|
|
Response,
|
|
State,
|
|
};
|
|
|
|
/// 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> {
|
|
{
|
|
use std::io::Write;
|
|
let mut stdout = std::io::stdout ();
|
|
stdout.write_all (b"> ")?;
|
|
stdout.flush ()?;
|
|
}
|
|
|
|
let mut buffer = String::new ();
|
|
std::io::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)
|
|
}
|
|
|
|
fn game (args: &[String]) -> Result <()> {
|
|
let mut state = State::default ();
|
|
|
|
if args.get (1) == Some (&"cheat".to_string ()) {
|
|
state.cheat ();
|
|
}
|
|
let responses = state.step ("");
|
|
|
|
for response in responses.into_iter () {
|
|
match response {
|
|
Response::Print (line) => print (&line),
|
|
Response::PrintMany (lines) => {
|
|
for line in lines {
|
|
print (line);
|
|
}
|
|
},
|
|
Response::Sleep (x) => std::thread::sleep (std::time::Duration::from_millis (x.into ())),
|
|
_ => (),
|
|
}
|
|
}
|
|
|
|
'main_loop: loop {
|
|
let input = read_input ()?;
|
|
let responses = state.step (&input);
|
|
|
|
for response in responses.into_iter () {
|
|
match response {
|
|
Response::Print (line) => print (&line),
|
|
Response::PrintMany (lines) => {
|
|
for line in lines {
|
|
print (line);
|
|
}
|
|
},
|
|
Response::Sleep (x) => std::thread::sleep (std::time::Duration::from_millis (x.into ())),
|
|
Response::Quit => break 'main_loop,
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok (())
|
|
}
|
|
|
|
fn main () -> Result <()> {
|
|
let args: Vec <_> = std::env::args ().collect ();
|
|
game (&args [..])?;
|
|
|
|
Ok (())
|
|
}
|