|
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 } |