1 use crate::outline_template_based::outline::OutlinePoints; |
1 use crate::outline_template_based::outline::OutlinePoints; |
2 use crate::{LandGenerationParameters, LandGenerator}; |
2 use crate::{LandGenerationParameters, LandGenerator}; |
3 use integral_geometry::{Point, Polygon, Rect, Size}; |
3 use integral_geometry::{Point, Polygon, Rect, Size}; |
4 use land2d::Land2D; |
4 use land2d::Land2D; |
5 use rand::Rng; |
5 use rand::Rng; |
|
6 use vec2d::Vec2D; |
6 |
7 |
7 #[derive(Clone)] |
8 #[derive(Clone)] |
8 pub struct MazeTemplate { |
9 pub struct MazeTemplate { |
9 pub width: usize, |
10 pub width: u32, |
10 pub height: usize, |
11 pub height: u32, |
11 pub cell_size: usize, |
12 pub cell_size: u32, |
12 pub inverted: bool, |
13 pub inverted: bool, |
13 pub distortion_limiting_factor: u32, |
14 pub distortion_limiting_factor: u32, |
14 pub braidness: u32, |
15 pub braidness: u32, |
15 } |
16 } |
16 |
17 |
19 braidness: u32, |
20 braidness: u32, |
20 off: Point, |
21 off: Point, |
21 num_cells: Size, |
22 num_cells: Size, |
22 num_edges: Size, |
23 num_edges: Size, |
23 seen_cells: Size, |
24 seen_cells: Size, |
24 cell_size: usize, |
25 cell_size: u32, |
25 seen_list: Vec<Vec<Option<usize>>>, |
26 seen_list: Vec2D<Option<usize>>, |
26 walls: Vec<Vec<Vec<bool>>>, |
27 walls: Vec<Vec2D<bool>>, |
27 edge_list: Vec<Vec<Vec<bool>>>, |
28 edge_list: Vec<Vec2D<bool>>, |
28 last_cell: Vec<Point>, |
29 last_cell: Vec<Point>, |
29 came_from: Vec<Vec<Point>>, |
30 came_from: Vec<Vec<Point>>, |
30 came_from_pos: Vec<i32>, |
31 came_from_pos: Vec<i32>, |
31 } |
32 } |
32 |
33 |
94 let num_edges = Size::new(num_cells.width - 1, num_cells.height - 1); |
95 let num_edges = Size::new(num_cells.width - 1, num_cells.height - 1); |
95 let seen_cells = Size::new(num_cells.width / 2, num_cells.height / 2); |
96 let seen_cells = Size::new(num_cells.width / 2, num_cells.height / 2); |
96 |
97 |
97 let mut last_cell = vec![Point::diag(0); num_steps]; |
98 let mut last_cell = vec![Point::diag(0); num_steps]; |
98 let came_from_pos = vec![0; num_steps]; |
99 let came_from_pos = vec![0; num_steps]; |
99 let came_from = vec![vec![Point::diag(0); num_steps]; num_cells.area()]; |
100 let came_from = vec![vec![Point::diag(0); num_steps]; num_cells.area() as usize]; |
100 |
101 |
101 let seen_list = vec![vec![None as Option<usize>; seen_cells.width]; seen_cells.height]; |
102 let seen_list = Vec2D::new(&seen_cells, None); |
102 let walls = vec![vec![vec![true; seen_cells.width]; seen_cells.height]; 2]; |
103 let walls = vec![Vec2D::new(&seen_cells, true); 2]; |
103 let edge_list = vec![vec![vec![false; num_cells.width]; num_cells.height]; 2]; |
104 let edge_list = vec![Vec2D::new(&num_cells, false); 2]; |
104 |
105 |
105 for current_step in 0..num_steps { |
106 for current_step in 0..num_steps { |
106 let x = random_numbers.gen_range(0..seen_cells.width - 1) / num_steps; |
107 let x = random_numbers.random_range(0..seen_cells.width as i32 - 1) / num_steps as i32; |
107 last_cell[current_step] = Point::new( |
108 last_cell[current_step] = Point::new( |
108 (x + current_step * seen_cells.width / num_steps) as i32, |
109 x + current_step as i32 * seen_cells.width as i32 / num_steps as i32, |
109 random_numbers.gen_range(0..seen_cells.height) as i32, |
110 random_numbers.random_range(..seen_cells.height) as i32, |
110 ); |
111 ); |
111 } |
112 } |
112 |
113 |
113 let off_x = ((size.width - num_cells.width * cell_size) / 2) as i32; |
114 let off_x = ((size.width - num_cells.width * cell_size) / 2) as i32; |
114 let off_y = ((size.height - num_cells.height * cell_size) / 2) as i32; |
115 let off_y = ((size.height - num_cells.height * cell_size) / 2) as i32; |
156 }; |
157 }; |
157 |
158 |
158 match when_seen { |
159 match when_seen { |
159 Some(a) if a == current_step => { |
160 Some(a) if a == current_step => { |
160 // try another direction |
161 // try another direction |
161 if !self.inverted && random_numbers.gen_range(0..self.braidness) == 0 { |
162 if !self.inverted && random_numbers.random_range(..self.braidness) == 0 { |
162 if dir.0.x == -1 && p.x > 0 { |
163 if dir.0.x == -1 && p.x > 0 { |
163 self.walls[dir.orientation()][p.y as usize][p.x as usize - 1] = |
164 self.walls[dir.orientation()][p.y as usize][p.x as usize - 1] = |
164 false; |
165 false; |
165 } |
166 } |
166 if dir.0.x == 1 && p.x < self.seen_cells.width as i32 - 1 { |
167 if dir.0.x == 1 && p.x < self.seen_cells.width as i32 - 1 { |
259 } |
260 } |
260 |
261 |
261 pub fn to_islands(mut self) -> (Vec<Polygon>, Vec<Point>) { |
262 pub fn to_islands(mut self) -> (Vec<Polygon>, Vec<Point>) { |
262 let mut islands: Vec<Polygon> = vec![]; |
263 let mut islands: Vec<Polygon> = vec![]; |
263 let mut polygon: Vec<Point> = vec![]; |
264 let mut polygon: Vec<Point> = vec![]; |
264 let mut maze = vec![vec![false; self.num_cells.width]; self.num_cells.height]; |
265 let mut maze = Vec2D::new(&self.num_cells, false); |
265 |
266 |
266 for x in 0..self.seen_cells.width { |
267 for x in 0..self.seen_cells.width as usize { |
267 for y in 0..self.seen_cells.height { |
268 for y in 0..self.seen_cells.height as usize { |
268 if self.seen_list[y][x].is_some() { |
269 if self.seen_list[y][x].is_some() { |
269 maze[y * 2 + 1][x * 2 + 1] = true; |
270 maze[y * 2 + 1][x * 2 + 1] = true; |
270 } |
271 } |
271 } |
272 } |
272 |
273 |
273 for y in 0..self.seen_cells.height - 1 { |
274 for y in 0..self.seen_cells.height as usize - 1 { |
274 if !self.walls[0][y][x] { |
275 if !self.walls[0][y][x] { |
275 maze[y * 2 + 2][x * 2 + 1] = true; |
276 maze[y * 2 + 2][x * 2 + 1] = true; |
276 } |
277 } |
277 } |
278 } |
278 } |
279 } |
279 |
280 |
280 for x in 0..self.seen_cells.width - 1 { |
281 for x in 0..self.seen_cells.width as usize - 1 { |
281 for y in 0..self.seen_cells.height { |
282 for y in 0..self.seen_cells.height as usize { |
282 if !self.walls[1][y][x] { |
283 if !self.walls[1][y][x] { |
283 maze[y * 2 + 1][x * 2 + 2] = true; |
284 maze[y * 2 + 1][x * 2 + 2] = true; |
284 } |
285 } |
285 } |
286 } |
286 } |
287 } |
287 |
288 |
288 for x in 0..self.num_edges.width { |
289 for x in 0..self.num_edges.width as usize { |
289 for y in 0..self.num_cells.height { |
290 for y in 0..self.num_cells.height as usize { |
290 self.edge_list[0][y][x] = maze[y][x] != maze[y][x + 1]; |
291 self.edge_list[0][y][x] = maze[y][x] != maze[y][x + 1]; |
291 } |
292 } |
292 } |
293 } |
293 |
294 |
294 for x in 0..self.num_cells.width { |
295 for x in 0..self.num_cells.width as usize { |
295 for y in 0..self.num_edges.height { |
296 for y in 0..self.num_edges.height as usize { |
296 self.edge_list[1][y][x] = maze[y][x] != maze[y + 1][x]; |
297 self.edge_list[1][y][x] = maze[y][x] != maze[y + 1][x]; |
297 } |
298 } |
298 } |
299 } |
299 |
300 |
300 let mut fill_points = vec![]; |
301 let mut fill_points = vec![]; |
301 |
302 |
302 for x in 0..self.num_edges.width { |
303 for x in 0..self.num_edges.width as usize { |
303 for y in 0..self.num_cells.height { |
304 for y in 0..self.num_cells.height as usize { |
304 if self.edge_list[0][y][x] { |
305 if self.edge_list[0][y][x] { |
305 self.edge_list[0][y][x] = false; |
306 self.edge_list[0][y][x] = false; |
306 self.add_vertex(Point::new(x as i32 + 1, y as i32 + 1), &mut polygon); |
307 self.add_vertex(Point::new(x as i32 + 1, y as i32 + 1), &mut polygon); |
307 self.add_vertex(Point::new(x as i32 + 1, y as i32), &mut polygon); |
308 self.add_vertex(Point::new(x as i32 + 1, y as i32), &mut polygon); |
308 self.add_edge( |
309 self.add_edge( |
326 polygon.clear(); |
327 polygon.clear(); |
327 } |
328 } |
328 } |
329 } |
329 } |
330 } |
330 |
331 |
331 for x in 0..self.num_cells.width { |
332 for x in 0..self.num_cells.width as usize { |
332 for y in 0..self.num_cells.height { |
333 for y in 0..self.num_cells.height as usize { |
333 if maze[y][x] { |
334 if maze[y][x] { |
334 let half_cell = self.cell_size / 2; |
335 let half_cell = self.cell_size / 2; |
335 let fill_point = Point::new( |
336 let fill_point = Point::new( |
336 (x * self.cell_size + half_cell) as i32 + self.off.x, |
337 (x as u32 * self.cell_size + half_cell) as i32 + self.off.x, |
337 (y * self.cell_size + half_cell) as i32 + self.off.y, |
338 (y as u32 * self.cell_size + half_cell) as i32 + self.off.y, |
338 ); |
339 ); |
339 islands.push(Polygon::new(&[fill_point])); |
340 islands.push(Polygon::new(&[fill_point])); |
340 fill_points.push(fill_point); |
341 fill_points.push(fill_point); |
341 |
342 |
342 let mut points = vec![(x, y)]; |
343 let mut points = vec![(x, y)]; |
346 maze[y][x] = false; |
347 maze[y][x] = false; |
347 |
348 |
348 if x > 0 { |
349 if x > 0 { |
349 points.push((x - 1, y)); |
350 points.push((x - 1, y)); |
350 } |
351 } |
351 if x < self.num_cells.width - 1 { |
352 if x < self.num_cells.width as usize - 1 { |
352 points.push((x + 1, y)); |
353 points.push((x + 1, y)); |
353 } |
354 } |
354 if y > 0 { |
355 if y > 0 { |
355 points.push((x, y - 1)); |
356 points.push((x, y - 1)); |
356 } |
357 } |
357 if y < self.num_cells.height - 1 { |
358 if y < self.num_cells.height as usize - 1 { |
358 points.push((x, y + 1)); |
359 points.push((x, y + 1)); |
359 } |
360 } |
360 } |
361 } |
361 } |
362 } |
362 } |
363 } |