Skip to content

Instantly share code, notes, and snippets.

@HalCanary
Created February 27, 2018 15:22
Show Gist options
  • Save HalCanary/edbe7346d9403ee013f42ce9a376ca2d to your computer and use it in GitHub Desktop.
Save HalCanary/edbe7346d9403ee013f42ce9a376ca2d to your computer and use it in GitHub Desktop.
// Implementation of /Choose Your Own Adventure/
//
// Hal Canary, 2018.
//
// See https://github.com/jcdyer/rust101.git
//
// Data: https://raw.githubusercontent.com/jcdyer/rust101/master/data/adventure.json
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
////////////////////////////////////////////////////////////////////////////////
#[derive(Deserialize, Debug)]
struct Action {
text: String,
label: String,
target: usize,
}
#[derive(Deserialize, Debug)]
struct Location {
id: usize,
text: String,
#[serde(default)]
date: String,
#[serde(default)]
actions: Vec<Action>,
}
#[derive(Deserialize, Debug)]
struct Cyoa {
title: String,
author: String,
locations: Vec<Location>,
}
////////////////////////////////////////////////////////////////////////////////
use std::io::Write;
fn main() {
let path: &str = "adventure.json";
let file = match std::fs::File::open(path) {
Ok(f) => f,
Err(e) => {
println!("Error opening '{}': {:?}", path, e);
std::process::exit(1);
}
};
let adventure: Cyoa = match serde_json::from_reader(file) {
Ok(f) => f,
Err(e) => {
println!("Error parsing file '{}': {:?}", path, e);
std::process::exit(1);
}
};
println!("{}\n{}", adventure.title, adventure.author);
let locations: &Vec<Location> = &adventure.locations;
let mut loc_idx: usize = 0;
loop {
let loc: &Location = match locations.get(loc_idx) {
Some(f) => f,
None => {
println!("Bad index {}. should be < {}", loc_idx, locations.len());
std::process::exit(3);
}
};
println!("\n{}\n", loc.text);
if loc.actions.len() == 0 {
break;
}
for (i, action) in loc.actions.iter().enumerate() {
println!(" {}. {}", i + 1, action.text);
}
let mut choice = String::new();
print!("\n? ");
std::io::stdout().flush().expect("");
std::io::stdin().read_line(&mut choice).expect(
"Failed to read line",
);
let choice_idx = match choice.trim().parse::<usize>() {
Ok(f) => f,
Err(_) => {
if choice == "" {
std::process::exit(2);
}
println!("Try Again!");
continue;
}
};
if choice_idx < 1 {
println!("Try Again!\n");
continue;
}
match loc.actions.get(choice_idx - 1) {
Some(f) => loc_idx = f.target,
None => {
println!("Try Again!\n");
continue;
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment