rust/landgen/src/template_based.rs
changeset 14072 8a0d69c16cad
parent 14047 3b3d97ed2286
child 14073 9c817b2eedae
equal deleted inserted replaced
14071:4b40bdd214df 14072:8a0d69c16cad
       
     1 use itertools::Itertools;
       
     2 
     1 use integral_geometry::Point;
     3 use integral_geometry::Point;
       
     4 use integral_geometry::Rect;
     2 use land2d::Land2D;
     5 use land2d::Land2D;
     3 use LandGenerationParameters;
     6 use LandGenerationParameters;
     4 use LandGenerator;
     7 use LandGenerator;
     5 
     8 
       
     9 struct OutlinePoints {
       
    10     islands: Vec<Vec<Point>>,
       
    11     fill_points: Vec<Point>,
       
    12     width: usize,
       
    13     height: usize,
       
    14 }
       
    15 
       
    16 impl OutlinePoints {
       
    17     fn from_outline_template<I: Iterator<Item = u32>>(
       
    18         outline_template: &OutlineTemplate,
       
    19         random_numbers: &mut I,
       
    20     ) -> Self {
       
    21         Self {
       
    22             islands: outline_template
       
    23                 .islands
       
    24                 .iter()
       
    25                 .map(|i| {
       
    26                     i.iter()
       
    27                         .zip(random_numbers.tuples())
       
    28                         .map(|(rect, (rnd_a, rnd_b))| {
       
    29                             Point::new(
       
    30                                 rect.x + (rnd_a % rect.width) as i32,
       
    31                                 rect.y + (rnd_b % rect.height) as i32,
       
    32                             )
       
    33                         }).collect()
       
    34                 }).collect(),
       
    35             fill_points: outline_template.fill_points.clone(),
       
    36             width: outline_template.width,
       
    37             height: outline_template.height,
       
    38         }
       
    39     }
       
    40 
       
    41     fn for_each<F: Fn(&mut Point)>(&mut self, f: F) {
       
    42         self.islands
       
    43             .iter_mut()
       
    44             .flat_map(|i| i.iter_mut())
       
    45             .chain(self.fill_points.iter_mut())
       
    46             .into_iter()
       
    47             .for_each(f);
       
    48     }
       
    49 
       
    50     fn distort<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
       
    51         unimplemented!()
       
    52     }
       
    53 }
       
    54 
     6 struct OutlineTemplate {
    55 struct OutlineTemplate {
     7     islands: Vec<Vec<Point>>,
    56     islands: Vec<Vec<Rect>>,
     8     fill_points: Vec<Point>,
    57     fill_points: Vec<Point>,
     9     width: usize,
    58     width: usize,
    10     height: usize,
    59     height: usize,
    11     can_flip: bool,
    60     can_flip: bool,
    12     can_invert: bool,
    61     can_invert: bool,
    16 
    65 
    17 struct TemplatedLandGenerator {
    66 struct TemplatedLandGenerator {
    18     outline_template: OutlineTemplate,
    67     outline_template: OutlineTemplate,
    19 }
    68 }
    20 
    69 
    21 impl OutlineTemplate {}
       
    22 
       
    23 impl TemplatedLandGenerator {
    70 impl TemplatedLandGenerator {
    24     fn new(outline_template: OutlineTemplate) -> Self {
    71     pub fn new(outline_template: OutlineTemplate) -> Self {
    25         Self { outline_template }
    72         Self { outline_template }
    26     }
    73     }
    27 }
    74 }
    28 
    75 
    29 impl LandGenerator for TemplatedLandGenerator {
    76 impl LandGenerator for TemplatedLandGenerator {
    30     fn generate_land<T: Copy + PartialEq, I: Iterator<Item = u32>>(
    77     fn generate_land<T: Copy + PartialEq, I: Iterator<Item = u32>>(
    31         &self,
    78         &self,
    32         parameters: LandGenerationParameters<T>,
    79         parameters: LandGenerationParameters<T>,
    33         random_numbers: &mut I,
    80         random_numbers: &mut I,
    34     ) -> Land2D<T> {
    81     ) -> Land2D<T> {
    35         let mut pa = Vec::new();
    82         let mut points =
       
    83             OutlinePoints::from_outline_template(&self.outline_template, random_numbers);
    36 
    84 
    37         for island in &self.outline_template.islands {
    85         let mut land = Land2D::new(points.width, points.height, parameters.basic);
    38             let mut island_points = Vec::new();
       
    39 
    86 
    40             for p in island {
    87         let top_left = Point::new(
    41                 island_points.push(p);
    88             (land.width() - land.play_width() / 2) as i32,
       
    89             (land.height() - land.play_height()) as i32,
       
    90         );
       
    91 
       
    92         points.width = land.width();
       
    93         points.height = land.height();
       
    94 
       
    95         points.for_each(|p| *p += top_left);
       
    96 
       
    97         // mirror
       
    98         if self.outline_template.can_mirror {
       
    99             if let Some(b) = random_numbers.next() {
       
   100                 if b & 1 != 0 {
       
   101                     points.for_each(|p| p.x = land.width() as i32 - 1 - p.x);
       
   102                 }
    42             }
   103             }
    43 
       
    44             pa.push(island_points);
       
    45         }
   104         }
    46 
   105 
    47         let mut land = Land2D::new(
   106         // flip
    48             self.outline_template.width,
   107         if self.outline_template.can_flip {
    49             self.outline_template.height,
   108             if let Some(b) = random_numbers.next() {
    50             parameters.basic,
   109                 if b & 1 != 0 {
    51         );
   110                     points.for_each(|p| p.y = land.height() as i32 - 1 - p.y);
       
   111                 }
       
   112             }
       
   113         }
       
   114 
       
   115         points.distort(random_numbers);
       
   116 
       
   117         // draw_edge(points, land, parameters.zero)
       
   118 
       
   119         for p in points.fill_points {
       
   120             land.fill(p, parameters.zero, parameters.zero)
       
   121         }
       
   122 
       
   123         // draw_edge(points, land, parameters.basic)
    52 
   124 
    53         land
   125         land
    54     }
   126     }
    55 }
   127 }
       
   128 
       
   129 #[test()]
       
   130 fn points_test() {
       
   131     let mut points = OutlinePoints {
       
   132         islands: vec![vec![]],
       
   133         fill_points: vec![Point::new(1, 1)],
       
   134         width: 100,
       
   135         height: 100,
       
   136     };
       
   137 
       
   138     points.for_each(|p| p.x = 2);
       
   139     assert_eq!(points.fill_points[0].x, 2);
       
   140 }