Created
February 27, 2018 15:22
-
-
Save HalCanary/edbe7346d9403ee013f42ce9a376ca2d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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