Implment MetaMapBuilder for Cellular Automata map builder

This commit is contained in:
Timothy Warren 2021-12-15 13:50:27 -05:00
parent 8249622a3e
commit ee9e96e828

View File

@ -1,6 +1,6 @@
use rltk::RandomNumberGenerator; use rltk::RandomNumberGenerator;
use crate::map_builders::{BuilderMap, InitialMapBuilder}; use crate::map_builders::{BuilderMap, InitialMapBuilder, MetaMapBuilder};
use crate::TileType; use crate::TileType;
pub struct CellularAutomataBuilder {} 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 { impl CellularAutomataBuilder {
pub fn new() -> Box<CellularAutomataBuilder> { pub fn new() -> Box<CellularAutomataBuilder> {
Box::new(CellularAutomataBuilder {}) 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) { fn build(&mut self, rng: &mut RandomNumberGenerator, build_data: &mut BuilderMap) {
// First we completely randomize the map, setting 55% of it to be floor. // First we completely randomize the map, setting 55% of it to be floor.
for y in 1..build_data.map.height - 1 { for y in 1..build_data.map.height - 1 {
@ -36,56 +92,7 @@ impl CellularAutomataBuilder {
// Now we iteratively apply cellular automata rules // Now we iteratively apply cellular automata rules
for _i in 0..15 { for _i in 0..15 {
let mut newtiles = build_data.map.tiles.clone(); self.apply_iteration(build_data);
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();
} }
} }
} }