rust/landgen/src/maze.rs
author unC0Rr
Tue, 10 Sep 2024 13:56:51 +0200
branchtransitional_engine
changeset 16032 31cc1e450273
child 16033 1860852892c0
permissions -rw-r--r--
Add maze land generator ported from pascal engine
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16032
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     1
use crate::outline_template_based::outline::OutlinePoints;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     2
use crate::{LandGenerationParameters, LandGenerator};
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     3
use integral_geometry::{Point, Polygon, Rect, Size};
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     4
use land2d::Land2D;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     5
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     6
pub struct MazeTemplate {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     7
    width: usize,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     8
    height: usize,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     9
    cell_size: usize,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    10
    inverted: bool,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    11
    distortion_limiting_factor: u32,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    12
    braidness: usize,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    13
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    14
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    15
pub struct MazeLandGenerator {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    16
    maze_template: MazeTemplate,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    17
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    18
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    19
fn prev_odd(num: usize) -> usize {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    20
    if num & 1 == 0 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    21
        num - 1
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    22
    } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    23
        num
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    24
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    25
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    26
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    27
impl MazeLandGenerator {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    28
    pub fn new(maze_template: MazeTemplate) -> Self {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    29
        Self { maze_template }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    30
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    31
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    32
    fn generate_outline<I: Iterator<Item = u32>>(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    33
        &self,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    34
        size: &Size,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    35
        play_box: Rect,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    36
        intersections_box: Rect,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    37
        random_numbers: &mut I,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    38
    ) -> OutlinePoints {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    39
        let num_cells = Size::new(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    40
            prev_odd(size.width / self.maze_template.cell_size),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    41
            prev_odd(size.height / self.maze_template.cell_size),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    42
        );
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    43
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    44
        let num_edges = Size::new(num_cells.width - 1, num_cells.height - 1);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    45
        let seen_cells = Size::new(num_cells.width / 2, num_cells.height / 2);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    46
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    47
        let num_steps = if self.maze_template.inverted { 3 } else { 1 };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    48
        let mut step_done = vec![false; num_steps];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    49
        let mut last_cell = vec![Point::diag(0); num_steps];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    50
        let mut came_from_pos = vec![0; num_steps];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    51
        let mut came_from = vec![vec![Point::diag(0); num_cells.area()]; num_steps];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    52
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    53
        let mut done = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    54
        let mut seen_list = vec![vec![None as Option<usize>; seen_cells.width]; seen_cells.height];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    55
        let mut x_walls = vec![vec![true; seen_cells.width]; seen_cells.height - 1];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    56
        let mut y_walls = vec![vec![true; seen_cells.width - 1]; seen_cells.height];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    57
        let mut x_edge_list = vec![vec![false; num_edges.width]; num_cells.height];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    58
        let mut y_edge_list = vec![vec![false; num_cells.width]; num_edges.height];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    59
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    60
        let mut maze = vec![vec![false; num_cells.width]; num_cells.height];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    61
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    62
        let off_y = 0;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    63
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    64
        for current_step in 0..num_steps {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    65
            let x = random_numbers.next().unwrap_or_default() as usize % (seen_cells.width - 1)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    66
                / num_steps;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    67
            last_cell[current_step] = Point::new(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    68
                (x + current_step * seen_cells.width / num_steps) as i32,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    69
                random_numbers.next().unwrap_or_default() as i32 / num_steps as i32,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    70
            );
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    71
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    72
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    73
        let see_cell = |current_step: usize, start_dir: Point, seen_list: &mut Vec<Vec<Option<usize>>>, x_walls: &mut Vec<Vec<bool>>, y_walls: &mut Vec<Vec<bool>>,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    74
                        last_cell: &mut Vec<Point>, came_from: &mut Vec<Vec<Point>>, came_from_pos: &mut Vec<i32>| {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    75
            loop {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    76
                let p = last_cell[current_step];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    77
                seen_list[p.y as usize][p.x as usize] = Some(current_step);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    78
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    79
                let mut dir = start_dir;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    80
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    81
                let next_dir_clockwise = true;//random_numbers.next().unwrap_or_default() % 2 == 0;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    82
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    83
                for _ in 0..5 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    84
                    let sp = p + dir;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    85
                    let when_seen =
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    86
                        if sp.x < 0
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    87
                            || sp.x >= seen_cells.width as i32
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    88
                            || sp.y < 0
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    89
                            || sp.y >= seen_cells.height as i32
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    90
                        {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    91
                            None
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    92
                        } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    93
                            Some(seen_list[sp.y as usize][sp.x as usize])
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    94
                        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    95
                    ;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    96
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    97
                    match when_seen {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    98
                        None => {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
    99
                            // try another direction
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   100
                            if dir.x == -1 && p.x > 0 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   101
                                y_walls[p.y as usize][p.x as usize - 1] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   102
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   103
                            if dir.x == 1 && p.x < seen_cells.width as i32 - 1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   104
                                y_walls[p.y as usize][p.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   105
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   106
                            if dir.y == -1 && p.y > 0 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   107
                                x_walls[p.y as usize][p.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   108
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   109
                            if dir.y == 1 && p.y < seen_cells.height as i32 - 1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   110
                                x_walls[p.y as usize][p.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   111
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   112
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   113
                            if next_dir_clockwise {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   114
                                dir = dir.rotate90();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   115
                            } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   116
                                dir = dir.rotate270();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   117
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   118
                        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   119
                        Some(None) => {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   120
                            // cell was not seen yet, go there
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   121
                            if dir.y == -1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   122
                                x_walls[p.y as usize - 1][p.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   123
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   124
                            if dir.y == 1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   125
                                x_walls[p.y as usize][p.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   126
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   127
                            if dir.x == -1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   128
                                y_walls[p.y as usize][p.x as usize - 1] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   129
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   130
                            if dir.x == 1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   131
                                y_walls[p.y as usize][p.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   132
                            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   133
                            last_cell[current_step] = p + dir;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   134
                            came_from_pos[current_step] += 1;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   135
                            came_from[came_from_pos[current_step] as usize][current_step] = p;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   136
                        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   137
                        _ => {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   138
                            return true;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   139
                        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   140
                    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   141
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   142
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   143
                last_cell[current_step] = came_from[came_from_pos[current_step] as usize][current_step];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   144
                came_from_pos[current_step] -= 1;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   145
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   146
                return came_from_pos[current_step] < 0;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   147
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   148
        };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   149
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   150
        let mut islands: Vec<Polygon> = vec![];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   151
        let mut polygon: Vec<Point> = vec![];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   152
        let add_vertex = |p: Point, polygon: &mut Vec<Point>| {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   153
            let cell_size = self.maze_template.cell_size as i32;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   154
            let [x, y] = [p.x, p.y].map(|i| {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   155
                if self.maze_template.inverted || i & 1 == 0 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   156
                    cell_size
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   157
                } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   158
                    cell_size * 2 / 3
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   159
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   160
            });
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   161
            let new_point =
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   162
                Point::new((p.x - 1) * cell_size + x, (p.y - 1) * cell_size + y + off_y);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   163
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   164
            let nv = polygon.len();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   165
            if nv > 2 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   166
                if polygon[nv - 2].x == polygon[nv - 1].x && polygon[nv - 1].x == new_point.x
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   167
                    || polygon[nv - 2].y == polygon[nv - 1].y && polygon[nv - 1].y == new_point.y
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   168
                {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   169
                    polygon.pop();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   170
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   171
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   172
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   173
            polygon.push(new_point);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   174
        };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   175
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   176
        let add_edge = |p: Point, dir: Point, polygon: &mut Vec<Point>, x_edge_list: &mut Vec<Vec<bool>>, y_edge_list: &mut Vec<Vec<bool>>| {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   177
            let mut dir = dir.rotate270();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   178
            let mut next_p = Some(p);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   179
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   180
            while let Some(p) = next_p {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   181
                next_p = None;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   182
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   183
                for _ in 0..4 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   184
                    dir = dir.rotate90();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   185
                    let cdir = Point::new(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   186
                        if dir.x < 0 { 0 } else { dir.x },
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   187
                        if dir.y < 0 { 0 } else { dir.y },
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   188
                    );
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   189
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   190
                    let np = p + cdir;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   191
                    let edge_list = if dir.x == 0 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   192
                        &mut *x_edge_list
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   193
                    } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   194
                        &mut *y_edge_list
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   195
                    };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   196
                    if np.x >= 0
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   197
                        && np.y > 0
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   198
                        && np.x < num_cells.width as i32
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   199
                        && np.y < num_cells.height as i32
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   200
                        && edge_list[np.y as usize][np.x as usize]
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   201
                    {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   202
                        (*edge_list)[np.y as usize][np.x as usize] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   203
                        add_vertex(p + dir + Point::new(1, 1), polygon);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   204
                        next_p = Some(p + dir);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   205
                        break;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   206
                    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   207
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   208
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   209
        };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   210
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   211
        while !done {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   212
            done = true;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   213
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   214
            for current_step in 0..num_steps {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   215
                if !step_done[current_step] {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   216
                    let dir = match random_numbers.next().unwrap_or_default() % 4 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   217
                        0 => Point::new(0, -1),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   218
                        1 => Point::new(1, 0),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   219
                        2 => Point::new(0, 1),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   220
                        3 => Point::new(-1, 0),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   221
                        _ => panic!(),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   222
                    };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   223
                    step_done[current_step] =
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   224
                        see_cell(current_step, dir, &mut seen_list, &mut x_walls, &mut y_walls, &mut last_cell, &mut came_from, &mut came_from_pos);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   225
                    done = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   226
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   227
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   228
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   229
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   230
        for x in 0..seen_cells.width {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   231
            for y in 0..seen_cells.height {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   232
                if seen_list[y][x].is_some() {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   233
                    maze[y * 2 + 1][x * 2 + 1] = true;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   234
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   235
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   236
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   237
            for y in 0..seen_cells.height - 1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   238
                if !x_walls[y][x] {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   239
                    maze[y * 2 + 2][x * 2 + 1] = true;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   240
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   241
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   242
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   243
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   244
        for x in 0..seen_cells.width - 1 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   245
            for y in 0..seen_cells.height {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   246
                if !y_walls[y][x] {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   247
                    maze[y * 2 + 1][x * 2 + 2] = true;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   248
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   249
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   250
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   251
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   252
        for x in 0..num_edges.width {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   253
            for y in 0..num_cells.height {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   254
                x_edge_list[y][x] = maze[y][x] != maze[y][x + 1];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   255
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   256
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   257
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   258
        for x in 0..num_cells.width {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   259
            for y in 0..num_edges.height {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   260
                y_edge_list[y][x] = maze[y][x] != maze[y + 1][x];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   261
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   262
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   263
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   264
        for x in 0..num_edges.width {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   265
            for y in 0..num_cells.height {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   266
                if x_edge_list[y][x] {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   267
                    x_edge_list[y][x] = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   268
                    add_vertex(Point::new(x as i32 + 1, y as i32 + 1), &mut polygon);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   269
                    add_vertex(Point::new(x as i32 + 1, y as i32), &mut polygon);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   270
                    add_edge(Point::new(x as i32, y as i32 - 1), Point::new(0, -1), &mut polygon, &mut x_edge_list, &mut y_edge_list);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   271
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   272
                    islands.push(Polygon::new(&polygon));
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   273
                    polygon.clear();
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   274
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   275
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   276
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   277
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   278
        OutlinePoints {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   279
            islands,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   280
            fill_points: vec![],
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   281
            size: *size,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   282
            play_box,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   283
            intersections_box,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   284
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   285
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   286
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   287
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   288
impl LandGenerator for MazeLandGenerator {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   289
    fn generate_land<T: Copy + PartialEq + Default, I: Iterator<Item = u32>>(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   290
        &self,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   291
        parameters: &LandGenerationParameters<T>,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   292
        random_numbers: &mut I,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   293
    ) -> Land2D<T> {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   294
        let do_invert = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   295
        let (basic, zero) = if do_invert {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   296
            (parameters.zero, parameters.basic)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   297
        } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   298
            (parameters.basic, parameters.zero)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   299
        };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   300
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   301
        let land_size = Size::new(self.maze_template.width, self.maze_template.height);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   302
        let mut land = Land2D::new(&land_size, basic);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   303
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   304
        let mut points = self.generate_outline(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   305
            &land.size().size(),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   306
            Rect::at_origin(land_size).with_margin(land_size.to_square().width as i32 * -2),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   307
            land.play_box(),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   308
            random_numbers,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   309
        );
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   310
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   311
        if !parameters.skip_distort {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   312
            points.distort(parameters.distance_divisor, random_numbers);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   313
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   314
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   315
        if !parameters.skip_bezier {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   316
            points.bezierize(5);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   317
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   318
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   319
        points.draw(&mut land, zero);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   320
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   321
        for p in &points.fill_points {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   322
            land.fill(*p, zero, zero)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   323
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   324
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   325
        points.draw(&mut land, basic);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   326
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   327
        land
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   328
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   329
}