rust/landgen/src/maze.rs
author unC0Rr
Wed, 18 Sep 2024 13:42:26 +0200
branchtransitional_engine
changeset 16064 0caa3dfb3ba2
parent 16063 09beeec033ba
child 16073 5c941f5deeec
permissions -rw-r--r--
Add templates for different maze styles
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16061
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
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
     6
#[derive(Clone)]
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
     7
pub struct MazeTemplate {
16062
1860852892c0 Use rust implementation of maze generator in engine
unC0Rr
parents: 16061
diff changeset
     8
    pub width: usize,
1860852892c0 Use rust implementation of maze generator in engine
unC0Rr
parents: 16061
diff changeset
     9
    pub height: usize,
1860852892c0 Use rust implementation of maze generator in engine
unC0Rr
parents: 16061
diff changeset
    10
    pub cell_size: usize,
1860852892c0 Use rust implementation of maze generator in engine
unC0Rr
parents: 16061
diff changeset
    11
    pub inverted: bool,
1860852892c0 Use rust implementation of maze generator in engine
unC0Rr
parents: 16061
diff changeset
    12
    pub distortion_limiting_factor: u32,
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    13
    pub braidness: u32,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    14
}
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    15
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    16
struct Maze {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    17
    inverted: bool,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    18
    braidness: u32,
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
    19
    off: Point,
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    20
    num_cells: Size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    21
    num_edges: Size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    22
    seen_cells: Size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    23
    cell_size: usize,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    24
    seen_list: Vec<Vec<Option<usize>>>,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    25
    walls: Vec<Vec<Vec<bool>>>,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    26
    edge_list: Vec<Vec<Vec<bool>>>,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    27
    last_cell: Vec<Point>,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    28
    came_from: Vec<Vec<Point>>,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    29
    came_from_pos: Vec<i32>,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    30
}
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    31
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    32
fn in_line(p1: &Point, p2: &Point, p3: &Point) -> bool {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    33
    p1.x == p2.x && p2.x == p3.x || p1.y == p2.y && p2.y == p3.y
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    34
}
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    35
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    36
#[derive(Clone, Copy)]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    37
struct Direction(Point);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    38
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    39
impl Direction {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    40
    #[inline]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    41
    pub fn new(direction: usize) -> Self {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    42
        match direction % 4 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    43
            0 => Self(Point::new(0, -1)),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    44
            1 => Self(Point::new(1, 0)),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    45
            2 => Self(Point::new(0, 1)),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    46
            3 => Self(Point::new(-1, 0)),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    47
            _ => panic!("Impossible"),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    48
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    49
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    50
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    51
    #[inline]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    52
    pub fn rotate_right(self) -> Self {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    53
        Self(self.0.rotate90())
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    54
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    55
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    56
    #[inline]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    57
    pub fn rotate_left(self) -> Self {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    58
        Self(self.0.rotate270())
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    59
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    60
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    61
    #[inline]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    62
    pub fn to_edge(self) -> Self {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    63
        Self(Point::new(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    64
            if self.0.x < 0 { 0 } else { self.0.x },
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    65
            if self.0.y < 0 { 0 } else { self.0.y },
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    66
        ))
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    67
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    68
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    69
    #[inline]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    70
    pub fn orientation(&self) -> usize {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    71
        if self.0.x == 0 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    72
            0
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    73
        } else {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    74
            1
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    75
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    76
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    77
}
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    78
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    79
impl Maze {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    80
    pub fn new<I: Iterator<Item = u32>>(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    81
        size: &Size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    82
        cell_size: usize,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    83
        num_steps: usize,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    84
        inverted: bool,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    85
        braidness: u32,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    86
        random_numbers: &mut I,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    87
    ) -> Self {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    88
        let num_cells = Size::new(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    89
            prev_odd(size.width / cell_size),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    90
            prev_odd(size.height / cell_size),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    91
        );
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    92
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    93
        let num_edges = Size::new(num_cells.width - 1, num_cells.height - 1);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    94
        let seen_cells = Size::new(num_cells.width / 2, num_cells.height / 2);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    95
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    96
        let mut last_cell = vec![Point::diag(0); num_steps];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    97
        let came_from_pos = vec![0; num_steps];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    98
        let came_from = vec![vec![Point::diag(0); num_steps]; num_cells.area()];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
    99
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   100
        let seen_list = vec![vec![None as Option<usize>; seen_cells.width]; seen_cells.height];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   101
        let walls = vec![vec![vec![true; seen_cells.width]; seen_cells.height]; 2];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   102
        let edge_list = vec![vec![vec![false; num_cells.width]; num_cells.height]; 2];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   103
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   104
        for current_step in 0..num_steps {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   105
            let x = random_numbers.next().unwrap_or_default() as usize % (seen_cells.width - 1)
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   106
                / num_steps;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   107
            last_cell[current_step] = Point::new(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   108
                (x + current_step * seen_cells.width / num_steps) as i32,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   109
                random_numbers.next().unwrap_or_default() as i32 % seen_cells.height as i32,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   110
            );
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   111
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   112
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   113
        let off_x = ((size.width - num_cells.width * cell_size) / 2) as i32;
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   114
        let off_y = ((size.height - num_cells.height * cell_size) / 2) as i32;
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   115
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   116
        Self {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   117
            inverted,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   118
            braidness,
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   119
            off: Point::new(off_x, off_y),
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   120
            num_cells,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   121
            num_edges,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   122
            seen_cells,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   123
            cell_size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   124
            seen_list,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   125
            walls,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   126
            edge_list,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   127
            last_cell,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   128
            came_from,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   129
            came_from_pos,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   130
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   131
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   132
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   133
    fn see_cell<I: Iterator<Item = u32>>(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   134
        &mut self,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   135
        current_step: usize,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   136
        start_dir: Direction,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   137
        random_numbers: &mut I,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   138
    ) -> bool {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   139
        let mut dir = start_dir;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   140
        loop {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   141
            let p = self.last_cell[current_step];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   142
            self.seen_list[p.y as usize][p.x as usize] = Some(current_step);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   143
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   144
            let next_dir_clockwise = random_numbers.next().unwrap_or_default() % 2 == 0;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   145
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   146
            for _ in 0..5 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   147
                let sp = p + dir.0;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   148
                let when_seen = if sp.x < 0
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   149
                    || sp.x >= self.seen_cells.width as i32
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   150
                    || sp.y < 0
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   151
                    || sp.y >= self.seen_cells.height as i32
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   152
                {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   153
                    Some(current_step)
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   154
                } else {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   155
                    self.seen_list[sp.y as usize][sp.x as usize]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   156
                };
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   157
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   158
                match when_seen {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   159
                    Some(a) if a == current_step => {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   160
                        // try another direction
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   161
                        if !self.inverted
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   162
                            && random_numbers.next().unwrap_or_default() % self.braidness == 0
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   163
                        {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   164
                            if dir.0.x == -1 && p.x > 0 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   165
                                self.walls[dir.orientation()][p.y as usize][p.x as usize - 1] =
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   166
                                    false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   167
                            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   168
                            if dir.0.x == 1 && p.x < self.seen_cells.width as i32 - 1 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   169
                                self.walls[dir.orientation()][p.y as usize][p.x as usize] = false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   170
                            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   171
                            if dir.0.y == -1 && p.y > 0 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   172
                                self.walls[dir.orientation()][p.y as usize - 1][p.x as usize] =
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   173
                                    false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   174
                            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   175
                            if dir.0.y == 1 && p.y < self.seen_cells.height as i32 - 1 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   176
                                self.walls[dir.orientation()][p.y as usize][p.x as usize] = false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   177
                            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   178
                        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   179
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   180
                        if next_dir_clockwise {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   181
                            dir = dir.rotate_right();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   182
                        } else {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   183
                            dir = dir.rotate_left();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   184
                        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   185
                    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   186
                    None => {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   187
                        // cell was not seen yet, go there
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   188
                        let o_dir = dir.rotate_right().rotate_right();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   189
                        let op = p - o_dir.to_edge().0;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   190
                        self.walls[o_dir.orientation()][op.y as usize][op.x as usize] = false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   191
                        self.last_cell[current_step] = sp;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   192
                        self.came_from_pos[current_step] += 1;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   193
                        self.came_from[self.came_from_pos[current_step] as usize][current_step] = p;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   194
                        return false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   195
                    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   196
                    _ => {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   197
                        return true;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   198
                    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   199
                }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   200
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   201
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   202
            self.last_cell[current_step] =
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   203
                self.came_from[self.came_from_pos[current_step] as usize][current_step];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   204
            self.came_from_pos[current_step] -= 1;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   205
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   206
            if self.came_from_pos[current_step] < 0 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   207
                return true;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   208
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   209
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   210
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   211
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   212
    fn add_vertex(&mut self, p: Point, polygon: &mut Vec<Point>) {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   213
        let [x, y] = [p.x, p.y].map(|i| {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   214
            if self.inverted || i & 1 == 0 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   215
                self.cell_size
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   216
            } else {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   217
                self.cell_size * 2 / 3
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   218
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   219
        });
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   220
        let new_point = Point::new(
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   221
            (p.x - 1) * self.cell_size as i32 + x as i32 + self.off.x,
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   222
            (p.y - 1) * self.cell_size as i32 + y as i32 + self.off.y,
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   223
        );
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   224
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   225
        let nv = polygon.len();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   226
        if nv > 2 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   227
            if in_line(&polygon[nv - 2], &polygon[nv - 1], &new_point) {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   228
                polygon.pop();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   229
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   230
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   231
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   232
        polygon.push(new_point);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   233
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   234
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   235
    fn add_edge(&mut self, p: Point, mut dir: Direction, polygon: &mut Vec<Point>) {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   236
        let mut next_p = Some(p);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   237
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   238
        while let Some(p) = next_p {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   239
            next_p = None;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   240
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   241
            for _ in 0..4 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   242
                let cdir = dir.to_edge();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   243
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   244
                let np = p + cdir.0;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   245
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   246
                if np.x >= 0
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   247
                    && np.y >= 0
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   248
                    && np.x < self.num_cells.width as i32
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   249
                    && np.y < self.num_cells.height as i32
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   250
                    && self.edge_list[dir.orientation()][np.y as usize][np.x as usize]
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   251
                {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   252
                    self.edge_list[dir.orientation()][np.y as usize][np.x as usize] = false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   253
                    self.add_vertex(p + dir.0 + Point::new(1, 1), polygon);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   254
                    next_p = Some(p + dir.0);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   255
                    break;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   256
                }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   257
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   258
                dir = dir.rotate_right();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   259
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   260
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   261
    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   262
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   263
    pub fn to_islands(mut self) -> (Vec<Polygon>, Vec<Point>) {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   264
        let mut islands: Vec<Polygon> = vec![];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   265
        let mut polygon: Vec<Point> = vec![];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   266
        let mut maze = vec![vec![false; self.num_cells.width]; self.num_cells.height];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   267
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   268
        for x in 0..self.seen_cells.width {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   269
            for y in 0..self.seen_cells.height {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   270
                if self.seen_list[y][x].is_some() {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   271
                    maze[y * 2 + 1][x * 2 + 1] = true;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   272
                }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   273
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   274
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   275
            for y in 0..self.seen_cells.height - 1 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   276
                if !self.walls[0][y][x] {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   277
                    maze[y * 2 + 2][x * 2 + 1] = true;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   278
                }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   279
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   280
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   281
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   282
        for x in 0..self.seen_cells.width - 1 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   283
            for y in 0..self.seen_cells.height {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   284
                if !self.walls[1][y][x] {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   285
                    maze[y * 2 + 1][x * 2 + 2] = true;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   286
                }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   287
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   288
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   289
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   290
        for x in 0..self.num_edges.width {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   291
            for y in 0..self.num_cells.height {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   292
                self.edge_list[0][y][x] = maze[y][x] != maze[y][x + 1];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   293
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   294
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   295
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   296
        for x in 0..self.num_cells.width {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   297
            for y in 0..self.num_edges.height {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   298
                self.edge_list[1][y][x] = maze[y][x] != maze[y + 1][x];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   299
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   300
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   301
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   302
        let mut fill_points = vec![];
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   303
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   304
        for x in 0..self.num_edges.width {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   305
            for y in 0..self.num_cells.height {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   306
                if self.edge_list[0][y][x] {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   307
                    self.edge_list[0][y][x] = false;
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   308
                    self.add_vertex(Point::new(x as i32 + 1, y as i32 + 1), &mut polygon);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   309
                    self.add_vertex(Point::new(x as i32 + 1, y as i32), &mut polygon);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   310
                    self.add_edge(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   311
                        Point::new(x as i32, y as i32 - 1),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   312
                        Direction::new(0),
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   313
                        &mut polygon,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   314
                    );
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   315
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   316
                    if polygon.len() > 4 {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   317
                        if in_line(polygon.last().unwrap(), &polygon[0], &polygon[1]) {
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   318
                            polygon.pop();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   319
                        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   320
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   321
                        for p in &polygon {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   322
                            println!("{} {}", p.x, p.y);
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   323
                        }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   324
                        println!("\ne\n");
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   325
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   326
                        islands.push(Polygon::new(&polygon));
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   327
                    }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   328
                    polygon.clear();
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   329
                }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   330
            }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   331
        }
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   332
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   333
        for x in 0..self.num_cells.width {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   334
            for y in 0..self.num_cells.height {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   335
                if maze[y][x] {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   336
                    let half_cell = self.cell_size / 2;
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   337
                    let fill_point = Point::new(
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   338
                        (x * self.cell_size + half_cell) as i32 + self.off.x,
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   339
                        (y * self.cell_size + half_cell) as i32 + self.off.y,
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   340
                    );
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   341
                    islands.push(Polygon::new(&[fill_point]));
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   342
                    fill_points.push(fill_point);
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   343
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   344
                    let mut points = vec![(x, y)];
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   345
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   346
                    while let Some((x, y)) = points.pop() {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   347
                        if maze[y][x] {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   348
                            maze[y][x] = false;
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   349
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   350
                            if x > 0 {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   351
                                points.push((x - 1, y));
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   352
                            }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   353
                            if x < self.num_cells.width - 1 {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   354
                                points.push((x + 1, y));
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   355
                            }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   356
                            if y > 0 {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   357
                                points.push((x, y - 1));
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   358
                            }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   359
                            if y < self.num_cells.height - 1 {
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   360
                                points.push((x, y + 1));
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   361
                            }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   362
                        }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   363
                    }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   364
                }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   365
            }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   366
        }
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   367
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   368
        (islands, fill_points)
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   369
    }
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   370
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   371
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   372
pub struct MazeLandGenerator {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   373
    maze_template: MazeTemplate,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   374
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   375
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   376
fn prev_odd(num: usize) -> usize {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   377
    if num & 1 == 0 {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   378
        num - 1
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   379
    } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   380
        num
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   381
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   382
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   383
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   384
impl MazeLandGenerator {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   385
    pub fn new(maze_template: MazeTemplate) -> Self {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   386
        Self { maze_template }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   387
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   388
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   389
    fn generate_outline<I: Iterator<Item = u32>>(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   390
        &self,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   391
        size: &Size,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   392
        play_box: Rect,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   393
        intersections_box: Rect,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   394
        random_numbers: &mut I,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   395
    ) -> OutlinePoints {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   396
        let num_steps = if self.maze_template.inverted { 3 } else { 1 };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   397
        let mut step_done = vec![false; num_steps];
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   398
        let mut done = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   399
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   400
        let mut maze = Maze::new(
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   401
            &size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   402
            self.maze_template.cell_size,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   403
            num_steps,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   404
            self.maze_template.inverted,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   405
            self.maze_template.braidness,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   406
            random_numbers,
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   407
        );
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   408
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   409
        while !done {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   410
            done = true;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   411
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   412
            for current_step in 0..num_steps {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   413
                if !step_done[current_step] {
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   414
                    let dir = Direction::new(random_numbers.next().unwrap_or_default() as usize);
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   415
                    step_done[current_step] = maze.see_cell(current_step, dir, random_numbers);
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   416
                    done = false;
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   417
                }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   418
            }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   419
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   420
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   421
        let (islands, fill_points) = maze.to_islands();
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   422
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   423
        OutlinePoints {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   424
            islands,
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   425
            fill_points,
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   426
            size: *size,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   427
            play_box,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   428
            intersections_box,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   429
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   430
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   431
}
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   432
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   433
impl LandGenerator for MazeLandGenerator {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   434
    fn generate_land<T: Copy + PartialEq + Default, I: Iterator<Item = u32>>(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   435
        &self,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   436
        parameters: &LandGenerationParameters<T>,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   437
        random_numbers: &mut I,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   438
    ) -> Land2D<T> {
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   439
        let do_invert = self.maze_template.inverted;
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   440
        let (basic, zero) = if do_invert {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   441
            (parameters.zero, parameters.basic)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   442
        } else {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   443
            (parameters.basic, parameters.zero)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   444
        };
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   445
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   446
        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
   447
        let mut land = Land2D::new(&land_size, basic);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   448
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   449
        let mut points = self.generate_outline(
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   450
            &land.size().size(),
16063
09beeec033ba Sanitize maze mapgen code a bit
unC0Rr
parents: 16062
diff changeset
   451
            land.play_box(), //??? Rect::at_origin(land_size).with_margin(land_size.to_square().width as i32 * -2),
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   452
            land.play_box(),
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   453
            random_numbers,
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   454
        );
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   455
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   456
        if !parameters.skip_distort {
16064
0caa3dfb3ba2 Add templates for different maze styles
unC0Rr
parents: 16063
diff changeset
   457
            points.distort(parameters.distance_divisor, self.maze_template.distortion_limiting_factor, random_numbers);
16061
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   458
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   459
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   460
        if !parameters.skip_bezier {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   461
            points.bezierize(5);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   462
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   463
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   464
        points.draw(&mut land, zero);
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   465
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   466
        for p in &points.fill_points {
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   467
            land.fill(*p, zero, zero)
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   468
        }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   469
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   470
        land
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   471
    }
31cc1e450273 Add maze land generator ported from pascal engine
unC0Rr
parents:
diff changeset
   472
}