diff --git a/src/map_builders/cellular_automata.rs b/src/map_builders/cellular_automata.rs index 0e055cf..af3b9bb 100644 --- a/src/map_builders/cellular_automata.rs +++ b/src/map_builders/cellular_automata.rs @@ -1,6 +1,6 @@ use rltk::RandomNumberGenerator; -use crate::map_builders::{BuilderMap, InitialMapBuilder}; +use crate::map_builders::{BuilderMap, InitialMapBuilder, MetaMapBuilder}; use crate::TileType; pub struct CellularAutomataBuilder {} @@ -12,11 +12,67 @@ impl InitialMapBuilder for CellularAutomataBuilder { } } +impl MetaMapBuilder for CellularAutomataBuilder { + #[allow(dead_code)] + fn build_map(&mut self, _rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) { + self.apply_iteration(build_data); + } +} + impl CellularAutomataBuilder { pub fn new() -> Box { Box::new(CellularAutomataBuilder {}) } + fn apply_iteration(&mut self, build_data: &mut BuilderMap) { + let mut newtiles = build_data.map.tiles.clone(); + + for y in 1..build_data.map.height - 1 { + for x in 1..build_data.map.width - 1 { + let idx = build_data.map.xy_idx(x, y); + let mut neighbors = 0; + + if build_data.map.tiles[idx - 1] == TileType::Wall { + neighbors += 1; + } + if build_data.map.tiles[idx + 1] == TileType::Wall { + neighbors += 1; + } + if build_data.map.tiles[idx - build_data.map.width as usize] == TileType::Wall { + neighbors += 1; + } + if build_data.map.tiles[idx + build_data.map.width as usize] == TileType::Wall { + neighbors += 1; + } + if build_data.map.tiles[idx - (build_data.map.width as usize - 1)] == TileType::Wall + { + neighbors += 1; + } + if build_data.map.tiles[idx - (build_data.map.width as usize + 1)] == TileType::Wall + { + neighbors += 1; + } + if build_data.map.tiles[idx + (build_data.map.width as usize - 1)] == TileType::Wall + { + neighbors += 1; + } + if build_data.map.tiles[idx + (build_data.map.width as usize + 1)] == TileType::Wall + { + neighbors += 1; + } + + if neighbors > 4 || neighbors == 0 { + newtiles[idx] = TileType::Wall; + } else { + newtiles[idx] = TileType::Floor; + } + } + } + + build_data.map.tiles = newtiles.clone(); + build_data.take_snapshot(); + } + fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) { // First we completely randomize the map, setting 55% of it to be floor. for y in 1..build_data.map.height - 1 { @@ -36,56 +92,7 @@ impl CellularAutomataBuilder { // Now we iteratively apply cellular automata rules for _i in 0..15 { - let mut newtiles = build_data.map.tiles.clone(); - - for y in 1..build_data.map.height - 1 { - for x in 1..build_data.map.width - 1 { - let idx = build_data.map.xy_idx(x, y); - let mut neighbors = 0; - - if build_data.map.tiles[idx - 1] == TileType::Wall { - neighbors += 1; - } - if build_data.map.tiles[idx + 1] == TileType::Wall { - neighbors += 1; - } - if build_data.map.tiles[idx - build_data.map.width as usize] == TileType::Wall { - neighbors += 1; - } - if build_data.map.tiles[idx + build_data.map.width as usize] == TileType::Wall { - neighbors += 1; - } - if build_data.map.tiles[idx - (build_data.map.width as usize - 1)] - == TileType::Wall - { - neighbors += 1; - } - if build_data.map.tiles[idx - (build_data.map.width as usize + 1)] - == TileType::Wall - { - neighbors += 1; - } - if build_data.map.tiles[idx + (build_data.map.width as usize - 1)] - == TileType::Wall - { - neighbors += 1; - } - if build_data.map.tiles[idx + (build_data.map.width as usize + 1)] - == TileType::Wall - { - neighbors += 1; - } - - if neighbors > 4 || neighbors == 0 { - newtiles[idx] = TileType::Wall; - } else { - newtiles[idx] = TileType::Floor; - } - } - } - - build_data.map.tiles = newtiles.clone(); - build_data.take_snapshot(); + self.apply_iteration(build_data); } } }