diff -r 32383b888309 -r 0c5b9cfda9ab rust/mapgen/src/lib.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/mapgen/src/lib.rs Sun Nov 04 04:43:30 2018 +0300 @@ -0,0 +1,150 @@ +use std::{ + collections::hash_map::HashMap, + borrow::Borrow, + mem::replace +}; +use serde::{Deserialize}; +use serde_derive::{Deserialize}; +use serde_yaml; +use integral_geometry::{Point, Size, Rect}; +use landgen::{ + outline_template::OutlineTemplate +}; +use rand::{thread_rng, Rng}; + +#[derive(Deserialize)] +struct PointDesc { + x: u32, + y: u32 +} + +#[derive(Deserialize)] +struct RectDesc { + x: u32, + y: u32, + w: u32, + h: u32 +} + +#[derive(Deserialize)] +struct TemplateDesc { + width: usize, + height: usize, + can_flip: bool, + can_invert: bool, + can_mirror: bool, + is_negative: bool, + put_girders: bool, + max_hedgehogs: u8, + outline_points: Vec>, + fill_points: Vec +} + +#[derive(Deserialize)] +struct TemplateCollectionDesc { + templates: Vec, + template_types: HashMap> +} + +impl From<&TemplateDesc> for OutlineTemplate { + fn from(desc: &TemplateDesc) -> Self { + OutlineTemplate { + islands: desc.outline_points.iter() + .map(|v| v.iter() + .map(|r| Rect::new(r.x as i32, r.y as i32, r.w, r.h)) + .collect()) + .collect(), + fill_points: desc.fill_points.iter() + .map(|p| Point::new(p.x as i32, p.y as i32)) + .collect(), + size: Size::new(desc.width, desc.height), + can_flip: desc.can_flip, + can_invert: desc.can_invert, + can_mirror: desc.can_mirror, + is_negative: desc.is_negative + } + } +} + +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +struct TemplateType(String); + +impl Borrow for TemplateType { + fn borrow(&self) -> &str { + self.0.as_str() + } +} + +#[derive(Debug)] +pub struct MapGenerator { + pub(crate) templates: HashMap> +} + +impl MapGenerator { + pub fn new() -> Self { + Self { templates: HashMap::new() } + } + + pub fn import_yaml_templates(&mut self, text: &str) { + let mut desc: TemplateCollectionDesc = serde_yaml::from_str(text).unwrap(); + let templates = replace(&mut desc.templates, vec![]); + self.templates = desc.template_types.into_iter() + .map(|(size, indices)| + (TemplateType(size), indices.iter() + .map(|i| (&templates[*i]).into()) + .collect())) + .collect(); + } + + pub fn get_template(&self, template_type: &str) -> Option<&OutlineTemplate> { + self.templates.get(template_type).and_then(|t| thread_rng().choose(t)) + } +} + +#[cfg(test)] +mod tests { + use crate::{ + MapGenerator, + TemplateType + }; + + #[test] + fn simple_load() { + let text = r#" +templates: + - + width: 3072 + height: 1424 + can_flip: false + can_invert: false + can_mirror: true + is_negative: false + put_girders: true + max_hedgehogs: 18 + outline_points: + - + - {x: 748, y: 1424, w: 1, h: 1} + - {x: 636, y: 1252, w: 208, h: 72} + - {x: 898, y: 1110, w: 308, h: 60} + - {x: 1128, y: 1252, w: 434, h: 40} + - {x: 1574, y: 1112, w: 332, h: 40} + - {x: 1802, y: 1238, w: 226, h: 36} + - {x: 1930, y: 1424, w: 1, h: 1} + fill_points: + - {x: 1023, y: 0} + +template_types: + test: [0] + +"#; + + let mut generator = MapGenerator::new(); + generator.import_yaml_templates(&text); + + assert!(generator.templates.contains_key(&TemplateType("test".to_string()))); + + let template = generator.get_template("test").unwrap(); + + assert_eq!(template.islands[0].len(), 7); + } +}