adventure-sim/src/main.rs

113 lines
4.2 KiB
Rust

use std::{collections::HashMap, io::BufReader, path::PathBuf, time::Duration};
use definitions::parser::DefinitionParser;
use sim::{Creature, Site, SiteArea, World};
pub mod definitions;
pub mod sim;
const SAVE_FILE: &str = "world.bin";
fn main() {
let mut parse_error_files = vec![];
let mut site_definitions = HashMap::new();
let mut creature_definitions = HashMap::new();
for entry in std::fs::read_dir(resources_path()).unwrap().flatten() {
if entry.file_name().to_string_lossy().ends_with(".def") {
let source = BufReader::new(std::fs::File::open(entry.path()).unwrap());
match DefinitionParser::parse(source) {
Ok(defs) => {
for def in defs.0 {
if let Some(prev) = site_definitions.insert(def.id.clone(), def) {
eprintln!("Duplicate site definition '{}'", prev.id);
}
}
for def in defs.1 {
if let Some(prev) = creature_definitions.insert(def.id.clone(), def) {
eprintln!("Duplicate site definition '{}'", prev.id);
}
}
}
Err(err) => {
parse_error_files.push((err, entry.path()));
}
}
}
}
for (err, path) in parse_error_files.iter() {
eprintln!("Error\t{path:?}\n\t{err:?}")
}
if !parse_error_files.is_empty() {
eprintln!("{} file(s) had parsing errors!", parse_error_files.len())
}
let site_def = site_definitions.get("CAVE").unwrap();
let mut world = match std::fs::read(SAVE_FILE) {
Ok(data) => bincode::deserialize(&data).expect("Loading world data from file"),
Err(_) => {
let mut world = World::default();
let mut site = Site::generate_from_def(site_def);
site.populate_randomly(&creature_definitions.values().collect::<Vec<_>>());
let bandit_def = creature_definitions.get("BANDIT").unwrap();
let spider_def = creature_definitions.get("SPIDER").unwrap();
let site = Site::new(
site_def.clone(),
"Gorbo's cave",
vec![
SiteArea::from_creatures(&vec![
Creature::generate_from_def(
creature_definitions.get("DRAGON").unwrap().clone(),
),
Creature::generate_from_def(
creature_definitions.get("INDESTRUCTIBLE").unwrap().clone(),
),
]),
SiteArea::from_creatures(&vec![
Creature::generate_from_def(bandit_def.clone()),
Creature::generate_from_def(spider_def.clone()),
]),
SiteArea::from_creatures(&vec![
Creature::generate_from_def(bandit_def.clone()),
Creature::generate_from_def(bandit_def.clone()),
Creature::generate_from_def(bandit_def.clone()),
]),
SiteArea::from_creatures(&vec![
Creature::generate_from_def(spider_def.clone()),
Creature::generate_from_def(spider_def.clone()),
]),
],
);
world.sites.push(site);
std::fs::write("world.bin", bincode::serialize(&world).unwrap()).unwrap();
world
}
};
for site in world.sites.iter() {
println!("{site}")
}
let mut input = String::new();
loop {
std::io::stdin().read_line(&mut input).unwrap();
if ["q", "quit", "exit"]
.iter()
.any(|quit_cmd| input.trim() == *quit_cmd)
{
break;
}
let start = std::time::Instant::now();
world.advance_time(Duration::from_secs(3600));
let end = std::time::Instant::now();
println!("World tick: {}us", (end - start).as_micros());
}
}
fn resources_path() -> PathBuf {
PathBuf::from(".").join("defs")
}