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