Drop BuilderData
trait.
This commit is contained in:
parent
ffaad6cf48
commit
2202540a43
|
@ -2,7 +2,7 @@ use mapgen::{
|
|||
filter::{
|
||||
AreaStartingPosition, CellularAutomata, CullUnreachable, NoiseGenerator, XStart, YStart,
|
||||
},
|
||||
BuilderData, MapBuilder, MapFilter,
|
||||
MapBuilder, MapFilter,
|
||||
};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
@ -10,11 +10,9 @@ struct MyData {
|
|||
value: usize,
|
||||
}
|
||||
|
||||
impl BuilderData for MyData {}
|
||||
|
||||
struct IncrementData;
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for IncrementData {
|
||||
impl<D: Clone + Default> MapFilter<D> for IncrementData {
|
||||
fn modify_map(&self, rng: &mut rand::prelude::StdRng, map: &mapgen::Map<D>) -> mapgen::Map<D> {
|
||||
let map = map.clone();
|
||||
map.data.value += 1;
|
||||
|
@ -28,7 +26,7 @@ fn main() {
|
|||
.with(CellularAutomata::new())
|
||||
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
|
||||
.with(CullUnreachable::new())
|
||||
.with(Box::new(IncrementData))
|
||||
.with(Box::new(IncrementData::<MyData>))
|
||||
.build();
|
||||
|
||||
println!("{:}", &map);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
//! ---
|
||||
//!
|
||||
|
||||
use super::map::{BuilderData, Map};
|
||||
use super::map::Map;
|
||||
use std::f32::MAX;
|
||||
use std::{collections::VecDeque, marker::PhantomData};
|
||||
|
||||
|
@ -41,13 +41,13 @@ pub struct DijkstraMap<D> {
|
|||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> DijkstraMap<D> {
|
||||
impl<D: Clone + Default> DijkstraMap<D> {
|
||||
//! Construct a new Dijkstra map, ready to run.
|
||||
pub fn new(map: &Map<D>) -> DijkstraMap<D> {
|
||||
let len = map.width * map.height;
|
||||
let tiles = vec![MAX; len];
|
||||
let mut d = DijkstraMap {
|
||||
tiles: tiles,
|
||||
tiles,
|
||||
size_x: map.width,
|
||||
size_y: map.height,
|
||||
max_depth: len as f32,
|
||||
|
|
|
@ -25,21 +25,21 @@ use std::marker::PhantomData;
|
|||
use crate::geometry::{Point, Rect};
|
||||
use crate::random::Rng;
|
||||
use crate::Map;
|
||||
use crate::{BuilderData, MapFilter};
|
||||
use crate::MapFilter;
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct BspInterior<D: BuilderData> {
|
||||
pub struct BspInterior<D> {
|
||||
min_room_size: usize,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for BspInterior<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for BspInterior<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(rng, map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> BspInterior<D> {
|
||||
impl<D: Clone + Default> BspInterior<D> {
|
||||
pub fn new() -> Box<BspInterior<D>> {
|
||||
Box::new(BspInterior {
|
||||
min_room_size: 8,
|
||||
|
|
|
@ -22,23 +22,22 @@ use std::marker::PhantomData;
|
|||
|
||||
use crate::geometry::Rect;
|
||||
use crate::random::Rng;
|
||||
use crate::BuilderData;
|
||||
use crate::Map;
|
||||
use crate::MapFilter;
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct BspRooms<D: BuilderData> {
|
||||
pub struct BspRooms<D> {
|
||||
max_split: usize,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for BspRooms<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for BspRooms<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build_rooms(map, rng)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> BspRooms<D> {
|
||||
impl<D: Clone + Default> BspRooms<D> {
|
||||
pub fn new() -> Box<BspRooms<D>> {
|
||||
Box::new(BspRooms {
|
||||
max_split: 240,
|
||||
|
@ -152,10 +151,8 @@ impl<D: BuilderData> BspRooms<D> {
|
|||
if y < 1 {
|
||||
can_build = false;
|
||||
}
|
||||
if can_build {
|
||||
if map.at(x as usize, y as usize).is_walkable() {
|
||||
can_build = false;
|
||||
}
|
||||
if can_build && map.at(x as usize, y as usize).is_walkable() {
|
||||
can_build = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,24 +23,23 @@
|
|||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::BuilderData;
|
||||
use crate::MapFilter;
|
||||
use crate::{Map, Tile};
|
||||
use rand::prelude::*;
|
||||
|
||||
/// Map filter
|
||||
pub struct CellularAutomata<D: BuilderData> {
|
||||
pub struct CellularAutomata<D> {
|
||||
num_iteraction: u32,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for CellularAutomata<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for CellularAutomata<D> {
|
||||
fn modify_map(&self, _rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> CellularAutomata<D> {
|
||||
impl<D: Clone + Default> CellularAutomata<D> {
|
||||
/// Create generator which will create map with the given dimension.
|
||||
pub fn new() -> Box<CellularAutomata<D>> {
|
||||
Box::new(CellularAutomata {
|
||||
|
@ -60,7 +59,7 @@ impl<D: BuilderData> CellularAutomata<D> {
|
|||
}
|
||||
}
|
||||
|
||||
fn apply_iteration<D: BuilderData>(map: &Map<D>) -> Map<D> {
|
||||
fn apply_iteration<D: Clone + Default>(map: &Map<D>) -> Map<D> {
|
||||
let mut new_map = map.clone();
|
||||
|
||||
for y in 1..map.height - 1 {
|
||||
|
|
|
@ -8,21 +8,21 @@ use std::marker::PhantomData;
|
|||
|
||||
use crate::dijkstra::DijkstraMap;
|
||||
use crate::MapFilter;
|
||||
use crate::{BuilderData, Map, Tile};
|
||||
use crate::{Map, Tile};
|
||||
use rand::prelude::StdRng;
|
||||
|
||||
/// Remove unreachable areas from the map.
|
||||
pub struct CullUnreachable<D: BuilderData> {
|
||||
pub struct CullUnreachable<D> {
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for CullUnreachable<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for CullUnreachable<D> {
|
||||
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> CullUnreachable<D> {
|
||||
impl<D: Clone + Default> CullUnreachable<D> {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Box<CullUnreachable<D>> {
|
||||
Box::new(CullUnreachable {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
use crate::dijkstra::DijkstraMap;
|
||||
use crate::geometry::Point;
|
||||
use crate::BuilderData;
|
||||
use crate::Map;
|
||||
use crate::MapFilter;
|
||||
use rand::prelude::StdRng;
|
||||
|
@ -14,17 +13,17 @@ use std::f32;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
/// Add exist position to the map based on the distance from the start point.
|
||||
pub struct DistantExit<D: BuilderData> {
|
||||
pub struct DistantExit<D> {
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for DistantExit<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for DistantExit<D> {
|
||||
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> DistantExit<D> {
|
||||
impl<D: Clone + Default> DistantExit<D> {
|
||||
#[allow(dead_code)]
|
||||
pub fn new() -> Box<DistantExit<D>> {
|
||||
Box::new(DistantExit {
|
||||
|
|
|
@ -20,7 +20,6 @@ use crate::{
|
|||
geometry::Point,
|
||||
map::{Map, Symmetry, Tile},
|
||||
random::Rng,
|
||||
BuilderData,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
|
||||
|
@ -30,7 +29,7 @@ pub enum DrunkSpawnMode {
|
|||
Random,
|
||||
}
|
||||
|
||||
pub struct DrunkardsWalk<D: BuilderData> {
|
||||
pub struct DrunkardsWalk<D> {
|
||||
spawn_mode: DrunkSpawnMode,
|
||||
drunken_lifetime: i32,
|
||||
floor_percent: f32,
|
||||
|
@ -39,13 +38,13 @@ pub struct DrunkardsWalk<D: BuilderData> {
|
|||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for DrunkardsWalk<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for DrunkardsWalk<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(rng, map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> DrunkardsWalk<D> {
|
||||
impl<D: Clone + Default> DrunkardsWalk<D> {
|
||||
pub fn new(
|
||||
spawn_mode: DrunkSpawnMode,
|
||||
drunken_lifetime: i32,
|
||||
|
|
|
@ -17,22 +17,22 @@ use std::marker::PhantomData;
|
|||
|
||||
use crate::MapFilter;
|
||||
use crate::{
|
||||
map::{BuilderData, Map, Tile},
|
||||
map::{Map, Tile},
|
||||
random::Rng,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct MazeBuilder<D: BuilderData> {
|
||||
pub struct MazeBuilder<D> {
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for MazeBuilder<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for MazeBuilder<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(rng, map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MazeBuilder<D> {
|
||||
impl<D: Clone + Default> MazeBuilder<D> {
|
||||
pub fn new() -> Box<MazeBuilder<D>> {
|
||||
Box::new(MazeBuilder {
|
||||
phantom: PhantomData,
|
||||
|
@ -93,7 +93,7 @@ impl Cell {
|
|||
}
|
||||
}
|
||||
|
||||
struct Grid<'a, D: BuilderData> {
|
||||
struct Grid<'a, D> {
|
||||
width: i32,
|
||||
height: i32,
|
||||
cells: Vec<Cell>,
|
||||
|
@ -103,7 +103,7 @@ struct Grid<'a, D: BuilderData> {
|
|||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<'a, D: BuilderData> Grid<'a, D> {
|
||||
impl<'a, D: Clone + Default> Grid<'a, D> {
|
||||
fn new(width: i32, height: i32, rng: &mut StdRng) -> Grid<D> {
|
||||
let mut grid = Grid {
|
||||
width,
|
||||
|
|
|
@ -19,22 +19,22 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::MapFilter;
|
||||
use crate::{BuilderData, Map, Tile};
|
||||
use crate::{Map, Tile};
|
||||
use rand::prelude::*;
|
||||
|
||||
/// Map noise generator
|
||||
pub struct NoiseGenerator<D: BuilderData> {
|
||||
pub struct NoiseGenerator<D> {
|
||||
prob: f32,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for NoiseGenerator<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for NoiseGenerator<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(map, rng)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> NoiseGenerator<D> {
|
||||
impl<D: Clone + Default> NoiseGenerator<D> {
|
||||
/// Create noise with custom probability
|
||||
pub fn new(prob: f32) -> Box<NoiseGenerator<D>> {
|
||||
Box::new(NoiseGenerator {
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
//! Connect nearest rooms on the map with corridors
|
||||
//!
|
||||
use crate::BuilderData;
|
||||
use crate::Map;
|
||||
use crate::MapFilter;
|
||||
use rand::prelude::StdRng;
|
||||
use std::collections::HashSet;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct NearestCorridors<D: BuilderData> {
|
||||
pub struct NearestCorridors<D> {
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for NearestCorridors<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for NearestCorridors<D> {
|
||||
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.corridors(map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> NearestCorridors<D> {
|
||||
impl<D: Clone + Default> NearestCorridors<D> {
|
||||
pub fn new() -> Box<NearestCorridors<D>> {
|
||||
Box::new(NearestCorridors {
|
||||
phantom: PhantomData,
|
||||
|
|
|
@ -22,25 +22,24 @@ use std::marker::PhantomData;
|
|||
|
||||
use crate::geometry::Rect;
|
||||
use crate::random::Rng;
|
||||
use crate::BuilderData;
|
||||
use crate::Map;
|
||||
use crate::MapFilter;
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct SimpleRooms<D: BuilderData> {
|
||||
pub struct SimpleRooms<D> {
|
||||
max_rooms: usize,
|
||||
min_room_size: usize,
|
||||
max_room_size: usize,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for SimpleRooms<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for SimpleRooms<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build_rooms(map, rng)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> SimpleRooms<D> {
|
||||
impl<D: Clone + Default> SimpleRooms<D> {
|
||||
pub fn new() -> Box<SimpleRooms<D>> {
|
||||
Box::new(SimpleRooms {
|
||||
max_rooms: 30,
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use crate::geometry::Point;
|
||||
use crate::BuilderData;
|
||||
use crate::Map;
|
||||
use crate::MapFilter;
|
||||
use rand::prelude::StdRng;
|
||||
|
@ -43,19 +42,19 @@ pub enum YStart {
|
|||
}
|
||||
|
||||
/// Add starting position to the map
|
||||
pub struct AreaStartingPosition<D: BuilderData> {
|
||||
pub struct AreaStartingPosition<D> {
|
||||
x: XStart,
|
||||
y: YStart,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for AreaStartingPosition<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for AreaStartingPosition<D> {
|
||||
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> AreaStartingPosition<D> {
|
||||
impl<D: Clone + Default> AreaStartingPosition<D> {
|
||||
/// Create new modifier with given region
|
||||
pub fn new(x: XStart, y: YStart) -> Box<AreaStartingPosition<D>> {
|
||||
Box::new(AreaStartingPosition {
|
||||
|
|
|
@ -18,23 +18,23 @@ use std::marker::PhantomData;
|
|||
use crate::MapFilter;
|
||||
use crate::{
|
||||
geometry::Point,
|
||||
map::{BuilderData, Map, Tile},
|
||||
map::{Map, Tile},
|
||||
random::Rng,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct VoronoiHive<D: BuilderData> {
|
||||
pub struct VoronoiHive<D> {
|
||||
n_seeds: usize,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapFilter<D> for VoronoiHive<D> {
|
||||
impl<D: Clone + Default> MapFilter<D> for VoronoiHive<D> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
|
||||
self.build(rng, map)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> VoronoiHive<D> {
|
||||
impl<D: Clone + Default> VoronoiHive<D> {
|
||||
pub fn new() -> Box<VoronoiHive<D>> {
|
||||
Box::new(VoronoiHive {
|
||||
n_seeds: 64,
|
||||
|
|
|
@ -34,7 +34,7 @@ pub mod map;
|
|||
pub mod metric;
|
||||
|
||||
pub use filter::*;
|
||||
pub use map::{BuilderData, Map, NoData, Symmetry, Tile};
|
||||
pub use map::{Map, NoData, Symmetry, Tile};
|
||||
|
||||
pub(crate) mod dijkstra;
|
||||
pub(crate) mod random;
|
||||
|
@ -44,18 +44,18 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
|||
|
||||
/// Trait which should be implemented by map modifier.
|
||||
/// Modifier takes initiall map and apply changes to it.
|
||||
pub trait MapFilter<D: BuilderData> {
|
||||
pub trait MapFilter<D: Clone + Default> {
|
||||
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D>;
|
||||
}
|
||||
|
||||
/// Used to chain MapBuilder and MapModifiers to create the final map.
|
||||
pub struct MapBuilder<D> {
|
||||
pub struct MapBuilder<D: Clone + Default> {
|
||||
width: usize,
|
||||
height: usize,
|
||||
modifiers: Vec<Box<dyn MapFilter<D>>>,
|
||||
}
|
||||
|
||||
impl<D: BuilderData> MapBuilder<D> {
|
||||
impl<D: Clone + Default> MapBuilder<D> {
|
||||
/// Create Map Builder with initial map generator
|
||||
pub fn new(width: usize, height: usize) -> MapBuilder<D> {
|
||||
MapBuilder {
|
||||
|
|
11
src/map.rs
11
src/map.rs
|
@ -24,18 +24,13 @@ pub enum Symmetry {
|
|||
Both,
|
||||
}
|
||||
|
||||
/// Arbitrary data associated with each map
|
||||
pub trait BuilderData: Clone + Default {}
|
||||
|
||||
/// No build data
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct NoData;
|
||||
|
||||
impl BuilderData for NoData {}
|
||||
|
||||
/// Map data
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Map<D> {
|
||||
pub struct Map<D: Clone + Default> {
|
||||
pub tiles: Vec<Tile>,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
|
@ -72,7 +67,7 @@ impl Tile {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> Map<D> {
|
||||
impl<D: Clone + Default> Map<D> {
|
||||
/// Generates an empty map, consisting entirely of solid walls
|
||||
pub fn new(width: usize, height: usize) -> Map<D> {
|
||||
let map_tile_count = width * height;
|
||||
|
@ -274,7 +269,7 @@ impl<D: BuilderData> Map<D> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<D: BuilderData> fmt::Display for Map<D> {
|
||||
impl<D: Clone + Default> fmt::Display for Map<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for y in 0..self.height {
|
||||
let bytes: Vec<u8> = (0..self.width)
|
||||
|
|
|
@ -6,12 +6,11 @@
|
|||
|
||||
use super::dijkstra::DijkstraMap;
|
||||
use super::map::Map;
|
||||
use super::BuilderData;
|
||||
|
||||
/// This metric calculates the percentage of walkable cells (Floor).
|
||||
/// If this number is very low (like < 10%) then it means that the map
|
||||
/// is probably to degenerated and shouldn't be used
|
||||
pub fn density<D>(map: &Map<D>) -> f32 {
|
||||
pub fn density<D: Clone + Default>(map: &Map<D>) -> f32 {
|
||||
let floor_count = map.tiles.iter().filter(|&t| t.is_walkable()).count();
|
||||
floor_count as f32 / map.tiles.len() as f32
|
||||
}
|
||||
|
@ -19,7 +18,7 @@ pub fn density<D>(map: &Map<D>) -> f32 {
|
|||
/// Calculate the length of the shortes path from the starting point
|
||||
/// to the exit.
|
||||
/// If this path is very short, then the map is probably degenerated.
|
||||
pub fn path_length<D: BuilderData>(map: &Map<D>) -> f32 {
|
||||
pub fn path_length<D: Clone + Default>(map: &Map<D>) -> f32 {
|
||||
if map.starting_point.is_none() {
|
||||
return 0.0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user