refactoring

This commit is contained in:
klangner 2020-09-22 20:44:54 +02:00
parent 278b549094
commit f661da36ce
11 changed files with 117 additions and 96 deletions

View File

@ -21,10 +21,10 @@
//! //!
use rand::prelude::*; use rand::prelude::*;
use super::MapFilter; use crate::MapFilter;
use crate::geometry::{Point, Rect}; use crate::geometry::{Point, Rect};
use crate::random::Rng; use crate::random::Rng;
use crate::map::Map; use crate::Map;
pub struct BspInterior { pub struct BspInterior {

View File

@ -19,10 +19,10 @@
//! //!
use rand::prelude::*; use rand::prelude::*;
use super::MapFilter; use crate::MapFilter;
use crate::geometry::Rect; use crate::geometry::Rect;
use crate::random::Rng; use crate::random::Rng;
use crate::map::{Map, TileType}; use crate::{Map, TileType};
pub struct BspRooms { pub struct BspRooms {

View File

@ -22,8 +22,8 @@
//! //!
use rand::prelude::*; use rand::prelude::*;
use super::MapFilter; use crate::MapFilter;
use crate::map::{Map, TileType}; use crate::{Map, TileType};
/// Map generator and modifier /// Map generator and modifier

View File

@ -5,8 +5,8 @@
//! //!
use rand::prelude::StdRng; use rand::prelude::StdRng;
use super::MapFilter; use crate::MapFilter;
use crate::map::{Map, TileType}; use crate::{Map, TileType};
use crate::dijkstra::DijkstraMap; use crate::dijkstra::DijkstraMap;

View File

@ -7,8 +7,8 @@
use std::f32; use std::f32;
use rand::prelude::StdRng; use rand::prelude::StdRng;
use crate::geometry::Point; use crate::geometry::Point;
use super::MapFilter; use crate::MapFilter;
use crate::map::Map; use crate::Map;
use crate::dijkstra::DijkstraMap; use crate::dijkstra::DijkstraMap;

View File

@ -14,7 +14,7 @@
//! //!
use rand::prelude::*; use rand::prelude::*;
use super::MapFilter; use crate::MapFilter;
use crate::{ use crate::{
map::{Map, Symmetry, TileType}, map::{Map, Symmetry, TileType},
geometry::Point, geometry::Point,

View File

@ -44,77 +44,5 @@ pub use distant_exit::DistantExit;
pub use drunkard::DrunkardsWalk; pub use drunkard::DrunkardsWalk;
pub use simple_rooms::SimpleRooms; pub use simple_rooms::SimpleRooms;
pub use rooms_corridors_nearest::NearestCorridors; pub use rooms_corridors_nearest::NearestCorridors;
pub use starting_point::AreaStartingPosition; pub use starting_point::{AreaStartingPosition, XStart, YStart};
use std::time::{SystemTime, UNIX_EPOCH};
use rand::prelude::*;
use crate::map::Map;
/// Trait which should be implemented by map modifier.
/// Modifier takes initiall map and apply changes to it.
pub trait MapFilter {
fn modify_map(&self, rng: &mut StdRng, map: &Map) -> Map;
}
/// Used to chain MapBuilder and MapModifiers to create the final map.
pub struct MapBuilder {
modifiers: Vec<Box<dyn MapFilter>>,
}
impl MapBuilder {
/// Create Map Builder with initial map generator
pub fn new() -> MapBuilder {
MapBuilder {
modifiers: Vec::new(),
}
}
pub fn with(&mut self, modifier : Box<dyn MapFilter>) -> &mut MapBuilder {
self.modifiers.push(modifier);
self
}
/// Build map using random number seeded with system time
pub fn build_map(&mut self, width: usize, height: usize) -> Map {
let system_time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Can't access system time");
let mut rng = StdRng::seed_from_u64(system_time.as_millis() as u64);
self.build_map_with_rng(width, height, &mut rng)
}
/// Build map using provided random number generator
pub fn build_map_with_rng(&mut self, width: usize, height: usize, rng: &mut StdRng) -> Map {
let mut map = Map::new(width, height);
// Build additional layers in turn
for modifier in self.modifiers.iter() {
map = modifier.modify_map(rng, &map);
}
map
}
}
/// ------------------------------------------------------------------------------------------------
/// Module unit tests
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
use cellular_automata::CellularAutomata;
use starting_point::{AreaStartingPosition, XStart, YStart};
#[test]
fn test_ca_map() {
let map = MapBuilder::new()
.with(CellularAutomata::new())
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
.build_map(80, 50);
assert_eq!(map.width, 80);
assert_eq!(map.height, 50);
assert_eq!(map.starting_point.is_some(), true);
}
}

View File

@ -1,8 +1,8 @@
//! Connect nearest rooms on the map with corridors //! Connect nearest rooms on the map with corridors
//! //!
use rand::prelude::StdRng; use rand::prelude::StdRng;
use super::MapFilter; use crate::MapFilter;
use crate::map::Map; use crate::Map;
use std::collections::HashSet; use std::collections::HashSet;

View File

@ -19,10 +19,10 @@
//! //!
use rand::prelude::*; use rand::prelude::*;
use super::MapFilter; use crate::MapFilter;
use crate::geometry::Rect; use crate::geometry::Rect;
use crate::random::Rng; use crate::random::Rng;
use crate::map::{Map}; use crate::Map;
pub struct SimpleRooms { pub struct SimpleRooms {

View File

@ -21,9 +21,9 @@
//! //!
use rand::prelude::StdRng; use rand::prelude::StdRng;
use super::MapFilter; use crate::MapFilter;
use crate::geometry::Point; use crate::geometry::Point;
use crate::map::{Map, TileType}; use crate::{Map, TileType};
/// Initial x region position /// Initial x region position

View File

@ -1,15 +1,108 @@
//! A collection of map generators. //! Generators for dungeon type maps.
//! //!
//! The generators are implemented for the following types of maps: //! Generators can bu used directly or they can be combined with
//! * Dungeon maps //! `MapGenerator`s and `MapModifier`s
//! //!
//! * MapGenerators are use to create initial map.
//! * MapModifiers modify existing map.
//!
//! Example
//! ```
//! use mapgen::{MapFilter, MapBuilder, Map, TileType};
//! use mapgen::filter::{
//! CellularAutomata,
//! starting_point::{AreaStartingPosition, XStart, YStart}
//! };
//! use mapgen::geometry::Point;
//!
//! let map = MapBuilder::new()
//! .with(CellularAutomata::new())
//! .with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
//! .build_map(80, 50);
//!
//! assert_eq!(map.width, 80);
//! assert_eq!(map.height, 50);
//! assert_eq!(map.starting_point.is_some(), true);
//! ```
//!
pub mod filter; pub mod filter;
pub mod geometry; pub mod geometry;
pub mod map; pub mod map;
pub use map::{Map, TileType}; pub use map::{Map, Symmetry, TileType};
pub use filter::{MapFilter, MapBuilder};
pub (crate) mod dijkstra; pub (crate) mod dijkstra;
pub (crate) mod random; pub (crate) mod random;
use std::time::{SystemTime, UNIX_EPOCH};
use rand::prelude::*;
/// Trait which should be implemented by map modifier.
/// Modifier takes initiall map and apply changes to it.
pub trait MapFilter {
fn modify_map(&self, rng: &mut StdRng, map: &Map) -> Map;
}
/// Used to chain MapBuilder and MapModifiers to create the final map.
pub struct MapBuilder {
modifiers: Vec<Box<dyn MapFilter>>,
}
impl MapBuilder {
/// Create Map Builder with initial map generator
pub fn new() -> MapBuilder {
MapBuilder {
modifiers: Vec::new(),
}
}
pub fn with(&mut self, modifier : Box<dyn MapFilter>) -> &mut MapBuilder {
self.modifiers.push(modifier);
self
}
/// Build map using random number seeded with system time
pub fn build_map(&mut self, width: usize, height: usize) -> Map {
let system_time = SystemTime::now().duration_since(UNIX_EPOCH).expect("Can't access system time");
let mut rng = StdRng::seed_from_u64(system_time.as_millis() as u64);
self.build_map_with_rng(width, height, &mut rng)
}
/// Build map using provided random number generator
pub fn build_map_with_rng(&mut self, width: usize, height: usize, rng: &mut StdRng) -> Map {
let mut map = Map::new(width, height);
// Build additional layers in turn
for modifier in self.modifiers.iter() {
map = modifier.modify_map(rng, &map);
}
map
}
}
/// ------------------------------------------------------------------------------------------------
/// Module unit tests
/// ------------------------------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
use filter::CellularAutomata;
use filter::{AreaStartingPosition, XStart, YStart};
#[test]
fn test_ca_map() {
let map = MapBuilder::new()
.with(CellularAutomata::new())
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
.build_map(80, 50);
assert_eq!(map.width, 80);
assert_eq!(map.height, 50);
assert_eq!(map.starting_point.is_some(), true);
}
}