rust/landgen/src/wavefront_collapse/generator.rs
author unC0Rr
Fri, 03 Feb 2023 15:59:18 +0100
branchtransitional_engine
changeset 15917 60b5639cc3a5
parent 15916 e82de0410da5
child 15918 9bd828451d77
permissions -rw-r--r--
Add WIP for generation of rules
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
     1
use super::tile_image::{Edge, TileImage};
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
     2
use super::wavefront_collapse::{CollapseRule, Tile, WavefrontCollapse};
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
     3
use crate::{LandGenerationParameters, LandGenerator};
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     4
use integral_geometry::Size;
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     5
use png::Decoder;
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
     6
use std::collections::HashSet;
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     7
use std::fs::File;
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
     8
use std::io::BufReader;
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
     9
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    10
pub struct WavefrontCollapseLandGenerator {}
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    11
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    12
impl WavefrontCollapseLandGenerator {
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    13
    pub fn new() -> Self {
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    14
        Self {}
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    15
    }
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    16
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    17
    pub fn load_template<T: Copy + PartialEq + Default>(
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    18
        &self,
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    19
        parameters: &LandGenerationParameters<T>,
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    20
    ) -> Vec<TileImage<T, String>> {
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    21
        let mut result = Vec::new();
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    22
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    23
        let file = File::open("sample.png").expect("file exists");
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    24
        let decoder = Decoder::new(BufReader::new(file));
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    25
        let mut reader = decoder.read_info().unwrap();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    26
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    27
        let info = reader.info();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    28
        let mut tiles_image = vec2d::Vec2D::new(
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    29
            &Size::new(info.width as usize, info.height as usize),
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    30
            parameters.zero,
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    31
        );
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    32
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    33
        let mut buf = vec![0; reader.output_buffer_size()];
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    34
        let info = reader.next_frame(&mut buf).unwrap();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    35
        let bytes = &buf[..info.buffer_size()];
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    36
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    37
        let mut tiles_image_pixels = tiles_image.as_mut_slice().into_iter();
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    38
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    39
        for line in bytes.chunks_exact(info.line_size) {
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    40
            for value in line.chunks_exact(info.color_type.samples()) {
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    41
                *tiles_image_pixels
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    42
                    .next()
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    43
                    .expect("vec2d size matching image dimensions") =
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    44
                    if value.into_iter().all(|p| *p == 0) {
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    45
                        parameters.zero
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    46
                    } else {
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    47
                        parameters.basic
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    48
                    };
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    49
            }
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    50
        }
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    51
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    52
        let top_edge = Edge::new("edge".to_owned(), false);
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    53
        let right_edge = Edge::new("edge".to_owned(), false);
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    54
        let bottom_edge = Edge::new("edge".to_owned(), false);
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    55
        let left_edge = Edge::new("edge".to_owned(), false);
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    56
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    57
        let tile =
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    58
            TileImage::<T, String>::new(tiles_image, top_edge, right_edge, bottom_edge, left_edge);
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    59
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    60
        result.push(tile.clone());
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    61
        result.push(tile.mirrored());
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    62
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
    63
        result
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    64
    }
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    65
}
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    66
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    67
impl LandGenerator for WavefrontCollapseLandGenerator {
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    68
    fn generate_land<T: Copy + PartialEq + Default, I: Iterator<Item = u32>>(
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    69
        &self,
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    70
        parameters: &LandGenerationParameters<T>,
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    71
        random_numbers: &mut I,
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
    72
    ) -> land2d::Land2D<T> {
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    73
        let tiles = self.load_template(parameters);
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
    74
15917
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    75
        let mut rules = Vec::<CollapseRule>::new();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    76
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    77
        let default_connection = HashSet::from_iter(vec![Tile::Outside, Tile::Empty].into_iter());
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    78
        for (i, tile) in tiles.iter().enumerate() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    79
            let mut right = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    80
            let mut bottom = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    81
            let mut left = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    82
            let mut top = default_connection.clone();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    83
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    84
            for p in 0..i {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    85
                if tiles[p].left_edge() == tile.right_edge() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    86
                    rules[p].left.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    87
                    right.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    88
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    89
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    90
                if tiles[p].right_edge() == tile.left_edge() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    91
                    rules[p].right.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    92
                    left.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    93
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    94
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    95
                if tiles[p].top_edge() == tile.bottom_edge() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    96
                    rules[p].top.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    97
                    bottom.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    98
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
    99
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   100
                if tiles[p].bottom_edge() == tile.top_edge() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   101
                    rules[p].bottom.insert(Tile::Numbered(i));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   102
                    top.insert(Tile::Numbered(p));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   103
                }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   104
            }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   105
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   106
            rules.push(CollapseRule {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   107
                tile: Tile::Numbered(i),
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   108
                top,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   109
                right,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   110
                bottom,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   111
                left,
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   112
            });
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   113
        }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   114
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   115
        let mut wfc = WavefrontCollapse::default();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   116
        wfc.set_rules(rules);
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   117
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   118
        wfc.generate_map(&Size::new(40, 20), |_| {}, random_numbers);
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   119
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   120
        let grid = wfc.grid();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   121
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   122
        for r in 0..grid.height() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   123
            for c in 0..grid.width() {
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   124
                print!("{:?}", grid.get(r, c));
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   125
            }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   126
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   127
            println!();
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   128
        }
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   129
60b5639cc3a5 Add WIP for generation of rules
unC0Rr
parents: 15916
diff changeset
   130
        todo!("build result")
15913
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   131
    }
c5684cc62de8 Switch to Vec2D in wavefront algorithm
unC0Rr
parents:
diff changeset
   132
}
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   133
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   134
#[cfg(test)]
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   135
mod tests {
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   136
    use super::WavefrontCollapseLandGenerator;
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   137
    use crate::{LandGenerationParameters, LandGenerator};
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   138
    use integral_geometry::Size;
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   139
    use vec2d::Vec2D;
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   140
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   141
    #[test]
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   142
    fn test_generation() {
15916
e82de0410da5 Rework how rules are defined, add transformations for tiles
unC0Rr
parents: 15915
diff changeset
   143
        let wfc_gen = WavefrontCollapseLandGenerator::new();
15915
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   144
        let landgen_params = LandGenerationParameters::new(0u8, 255u8, 0, true, true);
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   145
        wfc_gen.generate_land(&landgen_params, &mut std::iter::repeat(1u32));
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   146
    }
8f093b1b18bc Add loading of tiles from png
unC0Rr
parents: 15913
diff changeset
   147
}