rust/landgen/src/wavefront_collapse/generator.rs
changeset 16058 de01be16df95
parent 16029 9cbd18220eb7
child 16059 2acea266d297
equal deleted inserted replaced
16057:106674bb21b1 16058:de01be16df95
     1 use super::tile_image::{Edge, TileImage};
     1 use super::tile_image::{Edge, TileImage};
     2 use super::wavefront_collapse::{CollapseRule, Tile, WavefrontCollapse};
     2 use super::wavefront_collapse::{CollapseRule, Tile, WavefrontCollapse};
     3 use crate::{LandGenerationParameters, LandGenerator};
     3 use crate::{LandGenerationParameters, LandGenerator};
     4 use integral_geometry::Size;
     4 use integral_geometry::Size;
     5 use png::Decoder;
     5 use png::Decoder;
       
     6 use rand::Rng;
     6 use std::collections::HashSet;
     7 use std::collections::HashSet;
     7 use std::fs::File;
     8 use std::fs::File;
     8 use std::io::{BufReader, Result};
     9 use std::io::{BufReader, Result};
     9 use std::path::{Path, PathBuf};
    10 use std::path::{Path, PathBuf};
    10 
    11 
   177     }
   178     }
   178 
   179 
   179     pub fn build_rules<T: Copy + PartialEq + Default>(
   180     pub fn build_rules<T: Copy + PartialEq + Default>(
   180         &self,
   181         &self,
   181         tiles: &[TileImage<T, String>],
   182         tiles: &[TileImage<T, String>],
       
   183         probability_distribution_factor: i32,
   182     ) -> Vec<CollapseRule> {
   184     ) -> Vec<CollapseRule> {
   183         let [grid_top_edge, grid_right_edge, grid_bottom_edge, grid_left_edge]: [Option<
   185         let [grid_top_edge, grid_right_edge, grid_bottom_edge, grid_left_edge]: [Option<
   184             Edge<String>,
   186             Edge<String>,
   185         >; 4] = [
   187         >; 4] = [
   186             self.template.edges.top.as_ref(),
   188             self.template.edges.top.as_ref(),
   261                     rules[p].bottom.insert(Tile::Numbered(i));
   263                     rules[p].bottom.insert(Tile::Numbered(i));
   262                     top.insert(Tile::Numbered(p));
   264                     top.insert(Tile::Numbered(p));
   263                 }
   265                 }
   264             }
   266             }
   265 
   267 
       
   268             let weight = (probability_distribution_factor * 2 * i as i32 / (tiles.len() - 1) as i32
       
   269                 + 100
       
   270                 - probability_distribution_factor) as u32;
       
   271 
   266             rules.push(CollapseRule {
   272             rules.push(CollapseRule {
       
   273                 weight,
   267                 tile: Tile::Numbered(i),
   274                 tile: Tile::Numbered(i),
   268                 top,
   275                 top,
   269                 right,
   276                 right,
   270                 bottom,
   277                 bottom,
   271                 left,
   278                 left,
   275         rules
   282         rules
   276     }
   283     }
   277 }
   284 }
   278 
   285 
   279 impl LandGenerator for WavefrontCollapseLandGenerator {
   286 impl LandGenerator for WavefrontCollapseLandGenerator {
   280     fn generate_land<T: Copy + PartialEq + Default, I: Iterator<Item = u32>>(
   287     fn generate_land<T: Copy + PartialEq + Default>(
   281         &self,
   288         &self,
   282         parameters: &LandGenerationParameters<T>,
   289         parameters: &LandGenerationParameters<T>,
   283         random_numbers: &mut I,
   290         random_numbers: &mut impl Rng,
   284     ) -> land2d::Land2D<T> {
   291     ) -> land2d::Land2D<T> {
       
   292         assert!(parameters.distance_divisor >= 1);
       
   293         assert!(parameters.distance_divisor <= 25);
       
   294 
   285         let tiles = self.load_template(parameters);
   295         let tiles = self.load_template(parameters);
   286         let rules = self.build_rules(&tiles);
   296         let distribution_factor = (parameters.distance_divisor - 1) as i32 * 8 - 96;
       
   297         let rules = self.build_rules(&tiles, distribution_factor);
   287 
   298 
   288         let mut wfc = WavefrontCollapse::new(self.template.wrap);
   299         let mut wfc = WavefrontCollapse::new(self.template.wrap);
   289         wfc.set_rules(rules);
   300         wfc.set_rules(rules);
   290 
   301 
   291         let wfc_size = if let Some(first_tile) = tiles.first() {
   302         let wfc_size = if let Some(first_tile) = tiles.first() {