rust/landgen/src/template_based.rs
changeset 14072 8a0d69c16cad
parent 14047 3b3d97ed2286
child 14073 9c817b2eedae
--- a/rust/landgen/src/template_based.rs	Mon Oct 29 23:06:18 2018 +0100
+++ b/rust/landgen/src/template_based.rs	Wed Oct 31 23:36:05 2018 +0100
@@ -1,10 +1,59 @@
+use itertools::Itertools;
+
 use integral_geometry::Point;
+use integral_geometry::Rect;
 use land2d::Land2D;
 use LandGenerationParameters;
 use LandGenerator;
 
+struct OutlinePoints {
+    islands: Vec<Vec<Point>>,
+    fill_points: Vec<Point>,
+    width: usize,
+    height: usize,
+}
+
+impl OutlinePoints {
+    fn from_outline_template<I: Iterator<Item = u32>>(
+        outline_template: &OutlineTemplate,
+        random_numbers: &mut I,
+    ) -> Self {
+        Self {
+            islands: outline_template
+                .islands
+                .iter()
+                .map(|i| {
+                    i.iter()
+                        .zip(random_numbers.tuples())
+                        .map(|(rect, (rnd_a, rnd_b))| {
+                            Point::new(
+                                rect.x + (rnd_a % rect.width) as i32,
+                                rect.y + (rnd_b % rect.height) as i32,
+                            )
+                        }).collect()
+                }).collect(),
+            fill_points: outline_template.fill_points.clone(),
+            width: outline_template.width,
+            height: outline_template.height,
+        }
+    }
+
+    fn for_each<F: Fn(&mut Point)>(&mut self, f: F) {
+        self.islands
+            .iter_mut()
+            .flat_map(|i| i.iter_mut())
+            .chain(self.fill_points.iter_mut())
+            .into_iter()
+            .for_each(f);
+    }
+
+    fn distort<I: Iterator<Item = u32>>(&mut self, random_numbers: &mut I) {
+        unimplemented!()
+    }
+}
+
 struct OutlineTemplate {
-    islands: Vec<Vec<Point>>,
+    islands: Vec<Vec<Rect>>,
     fill_points: Vec<Point>,
     width: usize,
     height: usize,
@@ -18,10 +67,8 @@
     outline_template: OutlineTemplate,
 }
 
-impl OutlineTemplate {}
-
 impl TemplatedLandGenerator {
-    fn new(outline_template: OutlineTemplate) -> Self {
+    pub fn new(outline_template: OutlineTemplate) -> Self {
         Self { outline_template }
     }
 }
@@ -32,24 +79,62 @@
         parameters: LandGenerationParameters<T>,
         random_numbers: &mut I,
     ) -> Land2D<T> {
-        let mut pa = Vec::new();
+        let mut points =
+            OutlinePoints::from_outline_template(&self.outline_template, random_numbers);
+
+        let mut land = Land2D::new(points.width, points.height, parameters.basic);
 
-        for island in &self.outline_template.islands {
-            let mut island_points = Vec::new();
+        let top_left = Point::new(
+            (land.width() - land.play_width() / 2) as i32,
+            (land.height() - land.play_height()) as i32,
+        );
 
-            for p in island {
-                island_points.push(p);
+        points.width = land.width();
+        points.height = land.height();
+
+        points.for_each(|p| *p += top_left);
+
+        // mirror
+        if self.outline_template.can_mirror {
+            if let Some(b) = random_numbers.next() {
+                if b & 1 != 0 {
+                    points.for_each(|p| p.x = land.width() as i32 - 1 - p.x);
+                }
             }
-
-            pa.push(island_points);
         }
 
-        let mut land = Land2D::new(
-            self.outline_template.width,
-            self.outline_template.height,
-            parameters.basic,
-        );
+        // flip
+        if self.outline_template.can_flip {
+            if let Some(b) = random_numbers.next() {
+                if b & 1 != 0 {
+                    points.for_each(|p| p.y = land.height() as i32 - 1 - p.y);
+                }
+            }
+        }
+
+        points.distort(random_numbers);
+
+        // draw_edge(points, land, parameters.zero)
+
+        for p in points.fill_points {
+            land.fill(p, parameters.zero, parameters.zero)
+        }
+
+        // draw_edge(points, land, parameters.basic)
 
         land
     }
 }
+
+#[test()]
+fn points_test() {
+    let mut points = OutlinePoints {
+        islands: vec![vec![]],
+        fill_points: vec![Point::new(1, 1)],
+        width: 100,
+        height: 100,
+    };
+
+    points.for_each(|p| p.x = 2);
+    assert_eq!(points.fill_points[0].x, 2);
+}