rust/landgen/src/wavefront_collapse/wavefront_collapse.rs
author unC0Rr
Tue, 28 Jan 2025 15:49:45 +0100
changeset 16073 5d302b12d837
parent 16059 2acea266d297
child 16075 2c2b094e6bbe
permissions -rw-r--r--
- Update landgen to use the latest rand crate - Change Size width and height from usize to u32 for portability - Implement backtracking in wfc generator
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
     1
use integral_geometry::Size;
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
     2
use rand::distr::{weighted::WeightedIndex, Distribution};
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
     3
use rand::prelude::IndexedRandom;
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
     4
use rand::Rng;
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
     5
use std::collections::HashSet;
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents: 15912
diff changeset
     6
use vec2d::Vec2D;
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
     7
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
     8
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents: 15912
diff changeset
     9
pub enum Tile {
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    10
    Empty,
16059
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    11
    OutsideBegin,
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    12
    OutsideFill,
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    13
    OutsideEnd,
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    14
    Numbered(usize),
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    15
}
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    16
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    17
#[derive(Debug)]
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    18
pub struct CollapseRule {
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
    19
    pub weight: u32,
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    20
    pub tile: Tile,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    21
    pub right: HashSet<Tile>,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    22
    pub bottom: HashSet<Tile>,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    23
    pub left: HashSet<Tile>,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    24
    pub top: HashSet<Tile>,
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    25
}
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    26
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents: 15912
diff changeset
    27
pub struct WavefrontCollapse {
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    28
    rules: Vec<CollapseRule>,
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    29
    grid: Vec2D<Tile>,
15924
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    30
    wrap: bool,
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    31
}
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    32
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    33
impl Default for WavefrontCollapse {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    34
    fn default() -> Self {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    35
        Self {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    36
            rules: Vec::new(),
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    37
            grid: Vec2D::new(&Size::new(1, 1), Tile::Empty),
15924
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    38
            wrap: false,
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    39
        }
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    40
    }
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    41
}
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    42
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    43
impl WavefrontCollapse {
15924
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    44
    pub fn new(wrap: bool) -> Self {
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    45
        Self {
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    46
            rules: Vec::new(),
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    47
            grid: Vec2D::new(&Size::new(1, 1), Tile::Empty),
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    48
            wrap,
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    49
        }
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    50
    }
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    51
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
    52
    pub fn generate_map<F: FnOnce(&mut Vec2D<Tile>)>(
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    53
        &mut self,
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    54
        map_size: &Size,
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    55
        seed_fn: F,
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
    56
        random_numbers: &mut impl Rng,
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    57
    ) {
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
    58
        self.grid = Vec2D::new(map_size, Tile::Empty);
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    59
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    60
        seed_fn(&mut self.grid);
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    61
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    62
        let mut backtracks = 0usize;
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    63
        while let Some(b) = self.collapse_step(random_numbers) {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    64
            backtracks += b;
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    65
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    66
            if backtracks >= 1000 {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    67
                println!("[WFC] Too much backtracking, stopping generation!");
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    68
                break;
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    69
            }
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    70
        }
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    71
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    72
        if backtracks > 0 {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    73
            println!("[WFC] Had to backtrack {} times...", backtracks);
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
    74
        }
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    75
    }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
    76
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    77
    pub fn set_rules(&mut self, rules: Vec<CollapseRule>) {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    78
        self.rules = rules;
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    79
    }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    80
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    81
    fn get_tile(&self, y: usize, x: usize) -> Tile {
15924
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    82
        let x = if self.wrap {
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    83
            if x == usize::MAX {
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    84
                self.grid.width() - 1
15925
b0e8cc72bfef Allow defining compatible edges for grid, add few more templates
unC0Rr
parents: 15924
diff changeset
    85
            } else if x == self.grid.width() {
b0e8cc72bfef Allow defining compatible edges for grid, add few more templates
unC0Rr
parents: 15924
diff changeset
    86
                0
15924
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    87
            } else {
15925
b0e8cc72bfef Allow defining compatible edges for grid, add few more templates
unC0Rr
parents: 15924
diff changeset
    88
                x
15924
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    89
            }
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    90
        } else {
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    91
            x
9502611bffc1 Some bug fixes, build fixes and code formatting
unC0Rr
parents: 15923
diff changeset
    92
        };
15925
b0e8cc72bfef Allow defining compatible edges for grid, add few more templates
unC0Rr
parents: 15924
diff changeset
    93
16059
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    94
        self.grid.get(y, x).copied().unwrap_or_else(|| {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    95
            let x_out = x >= self.grid.width();
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    96
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    97
            if x_out {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    98
                let y_at_begin = y == 0;
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
    99
                let y_at_end = y.wrapping_add(1) == self.grid.height();
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   100
                if y_at_begin {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   101
                    Tile::OutsideBegin
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   102
                } else if y_at_end {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   103
                    Tile::OutsideEnd
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   104
                } else {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   105
                    Tile::OutsideFill
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   106
                }
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   107
            } else {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   108
                // if not x, then it is y
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   109
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   110
                let x_at_begin = x == 0;
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   111
                let x_at_end = x.wrapping_add(1) == self.grid.width();
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   112
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   113
                if x_at_begin {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   114
                    Tile::OutsideBegin
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   115
                } else if x_at_end {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   116
                    Tile::OutsideEnd
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   117
                } else {
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   118
                    Tile::OutsideFill
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   119
                }
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   120
            }
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   121
        })
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   122
    }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   123
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   124
    fn collapse_step(&mut self, random_numbers: &mut impl Rng) -> Option<usize> {
16059
2acea266d297 Fix generation in corners by extending outline edge definitions
unC0Rr
parents: 16058
diff changeset
   125
        let mut tiles_to_collapse = (usize::MAX, Vec::new());
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   126
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   127
        // Iterate through the tiles in the land
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   128
        for x in 0..self.grid.width() {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   129
            for y in 0..self.grid.height() {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   130
                let current_tile = self.get_tile(y, x);
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   131
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   132
                if let Tile::Empty = current_tile {
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   133
                    let neighbors = [
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   134
                        (y, x.wrapping_add(1)),
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   135
                        (y.wrapping_add(1), x),
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   136
                        (y, x.wrapping_sub(1)),
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   137
                        (y.wrapping_sub(1), x),
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   138
                    ];
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   139
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   140
                    // calc entropy
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   141
                    let [right_tile, bottom_tile, left_tile, top_tile] =
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   142
                        neighbors.map(|(y, x)| self.get_tile(y, x));
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   143
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
   144
                    let possibilities: Vec<(u32, Tile)> = self
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   145
                        .rules
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   146
                        .iter()
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   147
                        .filter_map(|rule| {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   148
                            if rule.right.contains(&right_tile)
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   149
                                && rule.bottom.contains(&bottom_tile)
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   150
                                && rule.left.contains(&left_tile)
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   151
                                && rule.top.contains(&top_tile)
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   152
                            {
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
   153
                                Some((rule.weight, rule.tile))
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   154
                            } else {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   155
                                None
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   156
                            }
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   157
                        })
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   158
                        .collect();
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   159
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   160
                    let entropy = possibilities.len();
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   161
                    if entropy > 0 {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   162
                        if entropy <= tiles_to_collapse.0 {
16058
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
   163
                            let weights = possibilities.iter().map(|(weight, _)| *weight);
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
   164
                            let distribution = WeightedIndex::new(weights).unwrap();
de01be16df95 Make slider below preview affect WFC generator by skewing tile probabilities
unC0Rr
parents: 15925
diff changeset
   165
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   166
                            let entry =
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   167
                                (y, x, possibilities[distribution.sample(random_numbers)].1);
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   168
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   169
                            if entropy < tiles_to_collapse.0 {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   170
                                tiles_to_collapse = (entropy, vec![entry])
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   171
                            } else {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   172
                                tiles_to_collapse.1.push(entry)
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   173
                            }
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   174
                        }
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   175
                    } else {
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   176
                        /*
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   177
                        println!("We're here: {}, {}", x, y);
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   178
                        println!(
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   179
                            "Neighbour tiles are: {:?} {:?} {:?} {:?}",
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   180
                            right_tile, bottom_tile, left_tile, top_tile
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   181
                        );
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   182
                        println!("Rules are: {:?}", self.rules);
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   183
                        */
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   184
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   185
                        let entries = neighbors
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   186
                            .iter()
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   187
                            .filter(|(y, x)| self.grid.get(*y, *x).is_some())
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   188
                            .map(|(y, x)| (*y, *x, Tile::Empty))
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   189
                            .collect::<Vec<_>>();
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   190
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   191
                        if entropy < tiles_to_collapse.0 {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   192
                            tiles_to_collapse = (entropy, entries);
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   193
                        } else {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   194
                            tiles_to_collapse.1.extend(entries);
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   195
                        }
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   196
15923
d46ad15c6dec Get wavefront collapse generator to work in engine
unC0Rr
parents: 15922
diff changeset
   197
                        //todo!("no collapse possible - what to do?")
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   198
                    }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   199
                }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   200
            }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   201
        }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   202
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   203
        if tiles_to_collapse.0 == 0 {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   204
            // cannot collapse, we're clearing some tiles
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   205
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   206
            for (y, x, tile) in tiles_to_collapse.1 {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   207
                *self
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   208
                    .grid
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   209
                    .get_mut(y, x)
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   210
                    .expect("correct iteration over grid") = tile;
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   211
            }
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   212
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   213
            Some(1)
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   214
        } else {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   215
            if let Some(&(y, x, tile)) = tiles_to_collapse.1.as_slice().choose(random_numbers) {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   216
                *self
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   217
                    .grid
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   218
                    .get_mut(y, x)
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   219
                    .expect("correct iteration over grid") = tile;
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   220
16073
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   221
                Some(0)
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   222
            } else {
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   223
                None
5d302b12d837 - Update landgen to use the latest rand crate
unC0Rr
parents: 16059
diff changeset
   224
            }
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   225
        }
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   226
    }
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   227
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   228
    pub fn grid(&self) -> &Vec2D<Tile> {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   229
        &self.grid
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   230
    }
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   231
}
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   232
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   233
#[cfg(test)]
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   234
mod tests {
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents: 15912
diff changeset
   235
    use super::{Tile, WavefrontCollapse};
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   236
    use integral_geometry::Size;
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents: 15912
diff changeset
   237
    use vec2d::Vec2D;
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   238
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   239
    #[test]
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   240
    fn test_wavefront_collapse() {
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   241
        let size = Size::new(4, 4);
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   242
        let mut rnd = [0u32; 64].into_iter().cycle();
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   243
        let mut wfc = WavefrontCollapse::default();
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   244
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   245
        wfc.generate_map(&size, |_| {}, &mut rnd);
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   246
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents: 15912
diff changeset
   247
        let empty_land = Vec2D::new(&size, Tile::Empty);
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   248
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   249
        assert_eq!(empty_land.as_slice(), wfc.grid().as_slice());
15912
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   250
    }
6e22f4390b7e Add basics of wavefront collapse algorithm
unC0Rr
parents:
diff changeset
   251
}