# HG changeset patch # User unC0Rr # Date 1676287890 -3600 # Node ID da6b67f13c12879dd4de0d1c7474bf4fa6c6dc0b # Parent 5f00829c55ec601f547aca92e9f9b3fd295cd024 Refactor mapgen to allow for easy switching between generators diff -r 5f00829c55ec -r da6b67f13c12 rust/landgen/src/outline_template_based/mod.rs --- a/rust/landgen/src/outline_template_based/mod.rs Mon Feb 13 11:00:12 2023 +0100 +++ b/rust/landgen/src/outline_template_based/mod.rs Mon Feb 13 12:31:30 2023 +0100 @@ -1,3 +1,3 @@ mod outline; pub mod outline_template; -pub mod template_based; \ No newline at end of file +pub mod template_based; diff -r 5f00829c55ec -r da6b67f13c12 rust/landgen/src/outline_template_based/template_based.rs --- a/rust/landgen/src/outline_template_based/template_based.rs Mon Feb 13 11:00:12 2023 +0100 +++ b/rust/landgen/src/outline_template_based/template_based.rs Mon Feb 13 12:31:30 2023 +0100 @@ -1,8 +1,5 @@ -use super::{ - outline::OutlinePoints, outline_template::OutlineTemplate}; -use crate::{LandGenerationParameters, - LandGenerator, -}; +use super::{outline::OutlinePoints, outline_template::OutlineTemplate}; +use crate::{LandGenerationParameters, LandGenerator}; use land2d::Land2D; pub struct TemplatedLandGenerator { diff -r 5f00829c55ec -r da6b67f13c12 rust/landgen/src/wavefront_collapse/generator.rs --- a/rust/landgen/src/wavefront_collapse/generator.rs Mon Feb 13 11:00:12 2023 +0100 +++ b/rust/landgen/src/wavefront_collapse/generator.rs Mon Feb 13 12:31:30 2023 +0100 @@ -8,13 +8,44 @@ use std::io::{BufReader, Result}; use std::path::Path; +#[derive(Clone)] +pub struct EdgeDescription { + pub name: String, + pub reversed: Option, + pub symmetrical: Option, +} + +#[derive(Clone)] +pub struct EdgesDescription { + pub top: EdgeDescription, + pub right: EdgeDescription, + pub bottom: EdgeDescription, + pub left: EdgeDescription, +} + +#[derive(Clone)] +pub struct TileDescription { + pub name: String, + pub edges: EdgesDescription, + pub can_flip: bool, + pub can_mirror: bool, + pub can_rotate90: bool, + pub can_rotate180: bool, + pub can_rotate270: bool, +} + +pub struct TemplateDescription { + pub size: Size, + pub tiles: Vec, +} + pub struct WavefrontCollapseLandGenerator { - pub size: Size, + pub template: TemplateDescription, } impl WavefrontCollapseLandGenerator { - pub fn new(size: &Size) -> Self { - Self { size: *size } + pub fn new(template: TemplateDescription) -> Self { + Self { template } } fn load_image_tiles( @@ -140,8 +171,8 @@ let tile_size = first_tile.size(); Size::new( - self.size.width / tile_size.width, - self.size.height / tile_size.height, + self.template.size.width / tile_size.width, + self.template.size.height / tile_size.height, ) } else { Size::new(1, 1) @@ -149,17 +180,7 @@ wfc.generate_map(&wfc_size, |_| {}, random_numbers); - let grid = wfc.grid(); - - for r in 0..grid.height() { - for c in 0..grid.width() { - print!("{:?} ", grid.get(r, c)); - } - - println!(); - } - - let mut result = land2d::Land2D::new(&self.size, parameters.zero); + let mut result = land2d::Land2D::new(&self.template.size, parameters.zero); for row in 0..wfc_size.height { for column in 0..wfc_size.width { @@ -194,7 +215,6 @@ use std::fs::File; use std::io::BufWriter; use std::path::Path; - use vec2d::Vec2D; #[test] fn test_generation() { diff -r 5f00829c55ec -r da6b67f13c12 rust/landgen/src/wavefront_collapse/wavefront_collapse.rs --- a/rust/landgen/src/wavefront_collapse/wavefront_collapse.rs Mon Feb 13 11:00:12 2023 +0100 +++ b/rust/landgen/src/wavefront_collapse/wavefront_collapse.rs Mon Feb 13 12:31:30 2023 +0100 @@ -9,35 +9,6 @@ Numbered(usize), } -impl Tile { - fn is(&self, i: usize) -> bool { - *self == Tile::Numbered(i) - } - - fn is_empty(&self) -> bool { - match self { - Tile::Empty => true, - Tile::Outside => true, - _ => false, - } - } - - fn is_empty_or(&self, i: usize) -> bool { - match self { - Tile::Numbered(n) => *n == i, - Tile::Empty => true, - _ => false, - } - } - - fn is_void_or(&self, i: usize) -> bool { - match self { - Tile::Numbered(n) => *n == i, - _ => true, - } - } -} - impl Default for Tile { fn default() -> Self { Tile::Outside diff -r 5f00829c55ec -r da6b67f13c12 rust/lib-hwengine-future/src/lib.rs --- a/rust/lib-hwengine-future/src/lib.rs Mon Feb 13 11:00:12 2023 +0100 +++ b/rust/lib-hwengine-future/src/lib.rs Mon Feb 13 12:31:30 2023 +0100 @@ -1,6 +1,11 @@ use integral_geometry::{Point, Size}; use land2d; -use landgen::{outline_template_based::template_based::TemplatedLandGenerator, LandGenerationParameters, LandGenerator}; +use landgen::{ + outline_template_based::{ + outline_template::OutlineTemplate, template_based::TemplatedLandGenerator, + }, + LandGenerationParameters, LandGenerator, +}; use lfprng::LaggedFibonacciPRNG; use mapgen::{theme::Theme, MapGenerator}; use std::fs; @@ -59,7 +64,7 @@ let yaml_templates = fs::read_to_string(data_path.join(Path::new("map_templates.yaml")).as_path()) .expect("Error reading map templates file"); - let mut map_gen = MapGenerator::new(); + let mut map_gen = MapGenerator::::new(); map_gen.import_yaml_templates(&yaml_templates); let distance_divisor = feature_size.pow(2) / 8 + 10; @@ -91,7 +96,7 @@ let data_path = Path::new(&data_path); let theme_name: &str = unsafe { CStr::from_ptr(theme_name) }.to_str().unwrap(); - let map_gen = MapGenerator::new(); + let map_gen = MapGenerator::<()>::new(); let theme = Theme::load( data_path diff -r 5f00829c55ec -r da6b67f13c12 rust/mapgen/src/lib.rs --- a/rust/mapgen/src/lib.rs Mon Feb 13 11:00:12 2023 +0100 +++ b/rust/mapgen/src/lib.rs Mon Feb 13 12:31:30 2023 +0100 @@ -1,79 +1,25 @@ +mod template; pub mod theme; use self::theme::Theme; +use crate::template::outline::TemplateCollectionDesc as OutlineTemplateCollectionDesc; +use crate::template::wavefront_collapse::TemplateCollectionDesc as WfcTemplateCollectionDesc; use integral_geometry::{Point, Rect, Size}; use land2d::Land2D; -use landgen::{outline_template_based::outline_template::OutlineTemplate, LandGenerationParameters}; +use landgen::{ + outline_template_based::{ + outline_template::OutlineTemplate, template_based::TemplatedLandGenerator, + }, + wavefront_collapse::generator::{ + TemplateDescription as WfcTemplate, WavefrontCollapseLandGenerator, + }, + LandGenerationParameters, LandGenerator, +}; +use rand::{seq::SliceRandom, Rng}; use serde_derive::Deserialize; use serde_yaml; use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace}; use vec2d::Vec2D; -use rand::{Rng, seq::SliceRandom}; - -#[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::from_size( - Point::new(r.x as i32, r.y as i32), - Size::new(r.w as usize, r.h as usize), - ) - }) - .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); @@ -85,33 +31,18 @@ } #[derive(Debug)] -pub struct MapGenerator { - pub(crate) templates: HashMap>, +pub struct MapGenerator { + pub(crate) templates: HashMap>, } -impl MapGenerator { +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, rng: &mut R) -> Option<&OutlineTemplate> { + pub fn get_template(&self, template_type: &str, rng: &mut R) -> Option<&T> { self.templates .get(template_type) .and_then(|t| t.as_slice().choose(rng)) @@ -190,6 +121,48 @@ } } +impl MapGenerator { + pub fn import_yaml_templates(&mut self, text: &str) { + let mut desc: OutlineTemplateCollectionDesc = 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 build_generator(&self, template: OutlineTemplate) -> impl LandGenerator { + TemplatedLandGenerator::new(template) + } +} + +impl MapGenerator { + pub fn import_yaml_templates(&mut self, text: &str) { + let mut desc: WfcTemplateCollectionDesc = 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 build_generator(&self, template: WfcTemplate) -> impl LandGenerator { + WavefrontCollapseLandGenerator::new(template) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct Color(u32); diff -r 5f00829c55ec -r da6b67f13c12 rust/mapgen/src/template/mod.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/mapgen/src/template/mod.rs Mon Feb 13 12:31:30 2023 +0100 @@ -0,0 +1,2 @@ +pub mod outline; +pub mod wavefront_collapse; diff -r 5f00829c55ec -r da6b67f13c12 rust/mapgen/src/template/outline.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/mapgen/src/template/outline.rs Mon Feb 13 12:31:30 2023 +0100 @@ -0,0 +1,73 @@ +use integral_geometry::{Point, Rect, Size}; +use land2d::Land2D; +use landgen::{ + outline_template_based::outline_template::OutlineTemplate, LandGenerationParameters, +}; +use serde_derive::Deserialize; +use serde_yaml; +use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace}; + +#[derive(Deserialize)] +pub struct PointDesc { + x: u32, + y: u32, +} + +#[derive(Deserialize)] +pub struct RectDesc { + x: u32, + y: u32, + w: u32, + h: u32, +} + +#[derive(Deserialize)] +pub 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)] +pub struct TemplateCollectionDesc { + pub templates: Vec, + pub 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::from_size( + Point::new(r.x as i32, r.y as i32), + Size::new(r.w as usize, r.h as usize), + ) + }) + .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, + } + } +} diff -r 5f00829c55ec -r da6b67f13c12 rust/mapgen/src/template/wavefront_collapse.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/mapgen/src/template/wavefront_collapse.rs Mon Feb 13 12:31:30 2023 +0100 @@ -0,0 +1,73 @@ +use integral_geometry::{Point, Rect, Size}; +use land2d::Land2D; +use landgen::{wavefront_collapse::generator::*, LandGenerationParameters}; +use serde_derive::Deserialize; +use serde_yaml; +use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace}; + +#[derive(Deserialize)] +#[serde(remote = "EdgeDescription")] +pub struct EdgeDesc { + pub name: String, + pub reversed: Option, + pub symmetrical: Option, +} + +#[derive(Deserialize)] +#[serde(remote = "EdgesDescription")] +pub struct EdgesDesc { + #[serde(with = "EdgeDesc")] + pub top: EdgeDescription, + #[serde(with = "EdgeDesc")] + pub right: EdgeDescription, + #[serde(with = "EdgeDesc")] + pub bottom: EdgeDescription, + #[serde(with = "EdgeDesc")] + pub left: EdgeDescription, +} + +#[derive(Deserialize)] +#[serde(remote = "TileDescription")] +pub struct TileDesc { + pub name: String, + #[serde(with = "EdgesDesc")] + pub edges: EdgesDescription, + pub can_flip: bool, + pub can_mirror: bool, + pub can_rotate90: bool, + pub can_rotate180: bool, + pub can_rotate270: bool, +} + +#[derive(Deserialize)] +pub struct TileDescriptionHelper(#[serde(with = "TileDesc")] TileDescription); + +#[derive(Deserialize)] +pub struct TemplateDesc { + pub width: usize, + pub height: usize, + pub can_flip: bool, + pub is_negative: bool, + pub put_girders: bool, + pub max_hedgehogs: u8, + pub tiles: Vec, +} + +#[derive(Deserialize)] +pub struct TemplateCollectionDesc { + pub templates: Vec, + pub template_types: HashMap>, +} + +impl From<&TemplateDesc> for TemplateDescription { + fn from(desc: &TemplateDesc) -> Self { + Self { + size: Size::new(desc.width, desc.height), + tiles: desc + .tiles + .iter() + .map(|TileDescriptionHelper(t)| t.clone()) + .collect(), + } + } +}