changed TileType to struct

This commit is contained in:
klangner 2021-06-28 17:06:47 +02:00
parent 5c440c17ba
commit d513dcda8f
13 changed files with 88 additions and 70 deletions

View File

@ -1,7 +1,7 @@
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use web_sys; use web_sys;
use rand::prelude::*; use rand::prelude::*;
use mapgen::{Map, MapBuilder, TileType, geometry::Point}; use mapgen::{Map, MapBuilder, geometry::Point};
use mapgen::filter::*; use mapgen::filter::*;
use mapgen::metric; use mapgen::metric;
@ -34,7 +34,7 @@ impl World {
fn new(width: u32, height: u32, map: Map) -> World { fn new(width: u32, height: u32, map: Map) -> World {
let tiles = (0..map.tiles.len()) let tiles = (0..map.tiles.len())
.map(|i| if map.tiles[i] == TileType::Floor {Cell::Floor} else {Cell::Wall}) .map(|i| if map.tiles[i].is_walkable() {Cell::Floor} else {Cell::Wall})
.collect(); .collect();
World { width, height, tiles, map } World { width, height, tiles, map }
} }

View File

@ -114,7 +114,7 @@ impl BspInterior {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{TileType, Map}; use crate::{Map};
#[test] #[test]
fn no_corridors_on_borders() { fn no_corridors_on_borders() {
@ -122,12 +122,12 @@ mod tests {
let gen = BspInterior::new(); let gen = BspInterior::new();
let map = gen.modify_map(&mut rng, &Map::new(80, 50)); let map = gen.modify_map(&mut rng, &Map::new(80, 50));
for i in 0..80 { for i in 0..80 {
assert_eq!(map.at(i, 0), TileType::Wall); assert!(map.at(i, 0).is_blocked());
assert_eq!(map.at(i, 49), TileType::Wall); assert!(map.at(i, 49).is_blocked());
} }
for j in 0..50 { for j in 0..50 {
assert_eq!(map.at(0, j), TileType::Wall); assert!(map.at(0, j).is_blocked());
assert_eq!(map.at(79, j), TileType::Wall); assert!(map.at(79, j).is_blocked());
} }
} }

View File

@ -22,7 +22,7 @@ use rand::prelude::*;
use crate::MapFilter; use crate::MapFilter;
use crate::geometry::Rect; use crate::geometry::Rect;
use crate::random::Rng; use crate::random::Rng;
use crate::{Map, TileType}; use crate::Map;
pub struct BspRooms { pub struct BspRooms {
@ -122,7 +122,7 @@ impl BspRooms {
if x < 1 { can_build = false; } if x < 1 { can_build = false; }
if y < 1 { can_build = false; } if y < 1 { can_build = false; }
if can_build { if can_build {
if map.at(x as usize, y as usize) != TileType::Wall { if map.at(x as usize, y as usize).is_walkable() {
can_build = false; can_build = false;
} }
} }
@ -147,12 +147,12 @@ mod tests {
let gen = BspRooms::new(); let gen = BspRooms::new();
let map = gen.modify_map(&mut rng, &Map::new(80, 50)); let map = gen.modify_map(&mut rng, &Map::new(80, 50));
for i in 0..80 { for i in 0..80 {
assert_eq!(map.at(i, 0), TileType::Wall); assert!(map.at(i, 0).is_blocked());
assert_eq!(map.at(i, 49), TileType::Wall); assert!(map.at(i, 49).is_blocked());
} }
for j in 0..50 { for j in 0..50 {
assert_eq!(map.at(0, j), TileType::Wall); assert!(map.at(0, j).is_blocked());
assert_eq!(map.at(79, j), TileType::Wall); assert!(map.at(79, j).is_blocked());
} }
} }

View File

@ -23,7 +23,7 @@
use rand::prelude::*; use rand::prelude::*;
use crate::MapFilter; use crate::MapFilter;
use crate::{Map, TileType}; use crate::{Map, Tile};
/// Map filter /// Map filter
@ -65,14 +65,14 @@ fn apply_iteration(map: &Map) -> Map {
(x-1, y), (x+1, y), (x-1, y), (x+1, y),
(x-1, y+1), (x, y+1), (x+1, y+1)]; (x-1, y+1), (x, y+1), (x+1, y+1)];
let neighbors = idxs.iter() let neighbors = idxs.iter()
.filter(|(x, y)| map.at(*x, *y) == TileType::Wall) .filter(|(x, y)| map.at(*x, *y).is_blocked())
.count(); .count();
if neighbors > 4 || neighbors == 0 { if neighbors > 4 || neighbors == 0 {
new_map.set_tile(x, y, TileType::Wall) new_map.set_tile(x, y, Tile::wall())
} }
else { else {
new_map.set_tile(x, y, TileType::Floor); new_map.set_tile(x, y, Tile::floor());
} }
} }
} }
@ -91,7 +91,7 @@ mod tests {
fn test_iteration_wal() { fn test_iteration_wal() {
let map = Map::new(3, 3); let map = Map::new(3, 3);
let new_map = apply_iteration(&map); let new_map = apply_iteration(&map);
assert_eq!(new_map.at(1, 1), TileType::Wall); assert!(new_map.at(1, 1).is_blocked());
} }
@ -100,11 +100,11 @@ mod tests {
let mut map = Map::new(3, 3); let mut map = Map::new(3, 3);
for i in 0..3 { for i in 0..3 {
for j in 0..2 { for j in 0..2 {
map.set_tile(i, j, TileType::Floor); map.set_tile(i, j, Tile::floor());
} }
} }
let new_map = apply_iteration(&map); let new_map = apply_iteration(&map);
assert_eq!(new_map.at(1, 1), TileType::Floor); assert!(new_map.at(1, 1).is_walkable());
} }
} }

View File

@ -6,7 +6,7 @@
use rand::prelude::StdRng; use rand::prelude::StdRng;
use crate::MapFilter; use crate::MapFilter;
use crate::{Map, TileType}; use crate::{Map, Tile};
use crate::dijkstra::DijkstraMap; use crate::dijkstra::DijkstraMap;
@ -30,11 +30,11 @@ impl CullUnreachable {
let dijkstra_map = DijkstraMap::new(map); let dijkstra_map = DijkstraMap::new(map);
for (i, tile) in new_map.tiles.iter_mut().enumerate() { for (i, tile) in new_map.tiles.iter_mut().enumerate() {
if *tile == TileType::Floor { if tile.is_walkable() {
let distance_to_start = dijkstra_map.tiles[i]; let distance_to_start = dijkstra_map.tiles[i];
// We can't get to this tile - so we'll make it a wall // We can't get to this tile - so we'll make it a wall
if distance_to_start == std::f32::MAX { if distance_to_start == std::f32::MAX {
*tile = TileType::Wall; *tile = Tile::wall();
} }
} }
} }

View File

@ -16,7 +16,7 @@
use rand::prelude::*; use rand::prelude::*;
use crate::MapFilter; use crate::MapFilter;
use crate::{ use crate::{
map::{Map, Symmetry, TileType}, map::{Map, Symmetry, Tile},
geometry::Point, geometry::Point,
random::Rng random::Rng
}; };
@ -79,11 +79,11 @@ impl DrunkardsWalk {
let mut new_map = map.clone(); let mut new_map = map.clone();
// Set a central starting point // Set a central starting point
let starting_position = Point::new( new_map.width / 2, new_map.height / 2 ); let starting_position = Point::new( new_map.width / 2, new_map.height / 2 );
new_map.set_tile(starting_position.x, starting_position.y, TileType::Floor); new_map.set_tile(starting_position.x, starting_position.y, Tile::floor());
let total_tiles = new_map.width * new_map.height; let total_tiles = new_map.width * new_map.height;
let desired_floor_tiles = (self.floor_percent * total_tiles as f32) as usize; let desired_floor_tiles = (self.floor_percent * total_tiles as f32) as usize;
let mut floor_tile_count = new_map.tiles.iter().filter(|a| **a == TileType::Floor).count(); let mut floor_tile_count = new_map.tiles.iter().filter(|a| a.is_walkable()).count();
let mut digger_count = 0; let mut digger_count = 0;
while floor_tile_count < desired_floor_tiles { while floor_tile_count < desired_floor_tiles {
let mut drunk_x; let mut drunk_x;
@ -106,7 +106,7 @@ impl DrunkardsWalk {
let mut drunk_life = self.drunken_lifetime; let mut drunk_life = self.drunken_lifetime;
while drunk_life > 0 { while drunk_life > 0 {
new_map.set_tile(drunk_x, drunk_y, TileType::Wall); new_map.set_tile(drunk_x, drunk_y, Tile::wall());
new_map.paint(self.symmetry, self.brush_size, drunk_x, drunk_y); new_map.paint(self.symmetry, self.brush_size, drunk_x, drunk_y);
let stagger_direction = rng.roll_dice(1, 4); let stagger_direction = rng.roll_dice(1, 4);
@ -121,7 +121,7 @@ impl DrunkardsWalk {
} }
digger_count += 1; digger_count += 1;
floor_tile_count = new_map.tiles.iter().filter(|a| **a == TileType::Floor).count(); floor_tile_count = new_map.tiles.iter().filter(|a| a.is_walkable()).count();
} }
new_map new_map

View File

@ -16,7 +16,7 @@
use rand::prelude::*; use rand::prelude::*;
use crate::MapFilter; use crate::MapFilter;
use crate::{ use crate::{
map::{Map, TileType}, map::{Map, Tile},
random::Rng random::Rng
}; };
@ -201,17 +201,17 @@ impl<'a> Grid<'a> {
fn copy_to_map(&self, map: &mut Map) { fn copy_to_map(&self, map: &mut Map) {
// Clear the map // Clear the map
for i in map.tiles.iter_mut() { *i = TileType::Wall; } for i in map.tiles.iter_mut() { *i = Tile::wall(); }
for cell in self.cells.iter() { for cell in self.cells.iter() {
let x = (cell.column as usize + 1) * 2; let x = (cell.column as usize + 1) * 2;
let y = (cell.row as usize + 1) * 2; let y = (cell.row as usize + 1) * 2;
map.set_tile(x, y, TileType::Floor); map.set_tile(x, y, Tile::floor());
if !cell.walls[TOP] { map.set_tile(x, y-1, TileType::Floor) } if !cell.walls[TOP] { map.set_tile(x, y-1, Tile::floor()) }
if !cell.walls[RIGHT] { map.set_tile(x+1, y, TileType::Floor) } if !cell.walls[RIGHT] { map.set_tile(x+1, y, Tile::floor()) }
if !cell.walls[BOTTOM] { map.set_tile(x, y+1, TileType::Floor) } if !cell.walls[BOTTOM] { map.set_tile(x, y+1, Tile::floor()) }
if !cell.walls[LEFT] { map.set_tile(x-1, y, TileType::Floor) } if !cell.walls[LEFT] { map.set_tile(x-1, y, Tile::floor()) }
} }
} }
} }

View File

@ -18,7 +18,7 @@
use rand::prelude::*; use rand::prelude::*;
use crate::MapFilter; use crate::MapFilter;
use crate::{Map, TileType}; use crate::{Map, Tile};
/// Map noise generator /// Map noise generator
@ -54,8 +54,8 @@ impl NoiseGenerator {
for y in 1..new_map.height-1 { for y in 1..new_map.height-1 {
for x in 1..new_map.width-1 { for x in 1..new_map.width-1 {
let roll = rng.next_u32() % 100; let roll = rng.next_u32() % 100;
if roll > p { new_map.set_tile(x, y, TileType::Floor) } if roll > p { new_map.set_tile(x, y, Tile::floor()) }
else { new_map.set_tile(x, y, TileType::Wall) } else { new_map.set_tile(x, y, Tile::wall()) }
} }
} }

View File

@ -6,13 +6,13 @@
//! Example modifier usage: //! Example modifier usage:
//! ``` //! ```
//! use rand::prelude::*; //! use rand::prelude::*;
//! use mapgen::{MapFilter, Map, TileType}; //! use mapgen::{MapFilter, Map, Tile};
//! use mapgen::filter::starting_point::{AreaStartingPosition, XStart, YStart}; //! use mapgen::filter::starting_point::{AreaStartingPosition, XStart, YStart};
//! use mapgen::geometry::Point; //! use mapgen::geometry::Point;
//! //!
//! let mut rng = StdRng::seed_from_u64(100); //! let mut rng = StdRng::seed_from_u64(100);
//! let mut map = Map::new(80, 50); //! let mut map = Map::new(80, 50);
//! map.set_tile(10, 10, TileType::Floor); //! map.set_tile(10, 10, Tile::floor());
//! let modifier = AreaStartingPosition::new(XStart::LEFT, YStart::TOP); //! let modifier = AreaStartingPosition::new(XStart::LEFT, YStart::TOP);
//! let new_map = modifier.modify_map(&mut rng, &map); //! let new_map = modifier.modify_map(&mut rng, &map);
//! //!
@ -23,7 +23,7 @@
use rand::prelude::StdRng; use rand::prelude::StdRng;
use crate::MapFilter; use crate::MapFilter;
use crate::geometry::Point; use crate::geometry::Point;
use crate::{Map, TileType}; use crate::Map;
/// Initial x region position /// Initial x region position
@ -67,7 +67,7 @@ impl AreaStartingPosition {
let mut available_floors : Vec<(usize, f32)> = Vec::new(); let mut available_floors : Vec<(usize, f32)> = Vec::new();
for (idx, tiletype) in map.tiles.iter().enumerate() { for (idx, tiletype) in map.tiles.iter().enumerate() {
if *tiletype == TileType::Floor { if tiletype.is_walkable() {
available_floors.push( available_floors.push(
( (
idx, idx,

View File

@ -16,7 +16,7 @@
use rand::prelude::*; use rand::prelude::*;
use crate::MapFilter; use crate::MapFilter;
use crate::{ use crate::{
map::{Map, TileType}, map::{Map, Tile},
random::Rng, random::Rng,
geometry::Point, geometry::Point,
}; };
@ -71,7 +71,7 @@ impl VoronoiHive {
if voronoi_membership[new_map.xy_idx(x, y+1)] != my_seed { neighbors += 1; } if voronoi_membership[new_map.xy_idx(x, y+1)] != my_seed { neighbors += 1; }
if neighbors < 2 { if neighbors < 2 {
new_map.set_tile(x, y, TileType::Floor); new_map.set_tile(x, y, Tile::floor());
} }
} }
} }

View File

@ -8,7 +8,7 @@
//! //!
//! Example //! Example
//! ``` //! ```
//! use mapgen::{MapFilter, MapBuilder, Map, TileType}; //! use mapgen::{MapFilter, MapBuilder, Map, Tile};
//! use mapgen::filter::{ //! use mapgen::filter::{
//! NoiseGenerator, //! NoiseGenerator,
//! CellularAutomata, //! CellularAutomata,
@ -33,7 +33,7 @@ pub mod geometry;
pub mod map; pub mod map;
pub mod metric; pub mod metric;
pub use map::{Map, Symmetry, TileType}; pub use map::{Map, Symmetry, Tile};
pub use filter::*; pub use filter::*;
pub (crate) mod dijkstra; pub (crate) mod dijkstra;

View File

@ -12,8 +12,8 @@ use super::geometry::{Point, Rect, usize_abs};
#[derive(PartialEq, Copy, Clone, Debug, Eq, Hash)] #[derive(PartialEq, Copy, Clone, Debug, Eq, Hash)]
pub enum TileType { pub struct Tile {
Wall, Floor is_blocked: bool,
} }
#[derive(PartialEq, Copy, Clone)] #[derive(PartialEq, Copy, Clone)]
@ -23,7 +23,7 @@ pub enum Symmetry { None, Horizontal, Vertical, Both }
/// Map data /// Map data
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct Map { pub struct Map {
pub tiles : Vec<TileType>, pub tiles : Vec<Tile>,
pub width : usize, pub width : usize,
pub height : usize, pub height : usize,
pub starting_point: Option<Point>, pub starting_point: Option<Point>,
@ -32,13 +32,31 @@ pub struct Map {
pub corridors: Vec<Vec<Point>>, pub corridors: Vec<Vec<Point>>,
} }
impl Tile {
pub fn wall() -> Tile {
Tile { is_blocked: true }
}
pub fn floor() -> Tile {
Tile { is_blocked: false }
}
pub fn is_walkable(&self) -> bool {
!self.is_blocked
}
pub fn is_blocked(&self) -> bool {
self.is_blocked
}
}
impl Map { impl Map {
/// Generates an empty map, consisting entirely of solid walls /// Generates an empty map, consisting entirely of solid walls
pub fn new(width: usize, height: usize) -> Map { pub fn new(width: usize, height: usize) -> Map {
let map_tile_count = width*height; let map_tile_count = width*height;
Map{ Map{
tiles : vec![TileType::Wall; map_tile_count], tiles : vec![Tile::wall(); map_tile_count],
width, width,
height, height,
starting_point: None, starting_point: None,
@ -62,7 +80,7 @@ impl Map {
let line = lines[i].as_bytes(); let line = lines[i].as_bytes();
for j in 0..line.len() { for j in 0..line.len() {
if line[j] as char == ' ' { if line[j] as char == ' ' {
map.set_tile(j, i, TileType::Floor); map.set_tile(j, i, Tile::floor());
} }
} }
} }
@ -70,9 +88,9 @@ impl Map {
} }
/// Get TileType at the given location /// Get TileType at the given location
pub fn at(&self, x: usize, y: usize) -> TileType { pub fn at(&self, x: usize, y: usize) -> Tile {
if x >= self.width || y >= self.height { if x >= self.width || y >= self.height {
TileType::Wall Tile::wall()
} else { } else {
let idx = (y as usize) * self.width + (x as usize); let idx = (y as usize) * self.width + (x as usize);
self.tiles[idx] self.tiles[idx]
@ -100,11 +118,11 @@ impl Map {
// Check if given tile can be accessed // Check if given tile can be accessed
fn is_exit_valid(&self, x:usize, y:usize) -> bool { fn is_exit_valid(&self, x:usize, y:usize) -> bool {
self.at(x, y) == TileType::Floor self.at(x, y).is_blocked == false
} }
/// Modify tile at the given location /// Modify tile at the given location
pub fn set_tile(&mut self, x: usize, y: usize, tile: TileType) { pub fn set_tile(&mut self, x: usize, y: usize, tile: Tile) {
if x < self.width && y < self.height { if x < self.width && y < self.height {
let idx = self.xy_idx(x as usize, y as usize); let idx = self.xy_idx(x as usize, y as usize);
self.tiles[idx] = tile; self.tiles[idx] = tile;
@ -120,7 +138,7 @@ impl Map {
pub fn add_room(&mut self, rect: Rect) { pub fn add_room(&mut self, rect: Rect) {
for x in rect.x1..rect.x2 { for x in rect.x1..rect.x2 {
for y in rect.y1..rect.y2 { for y in rect.y1..rect.y2 {
self.set_tile(x as usize, y as usize, TileType::Floor); self.set_tile(x as usize, y as usize, Tile::floor());
} }
} }
self.rooms.push(rect); self.rooms.push(rect);
@ -142,9 +160,9 @@ impl Map {
y -= 1; y -= 1;
} }
if self.at(x, y) != TileType::Floor { if self.at(x, y).is_blocked {
corridor.push(Point::new(x, y)); corridor.push(Point::new(x, y));
self.set_tile(x, y, TileType::Floor); self.set_tile(x, y, Tile::floor());
} }
} }
} }
@ -192,14 +210,14 @@ impl Map {
fn apply_paint(&mut self, brush_size: usize, x: usize, y: usize) { fn apply_paint(&mut self, brush_size: usize, x: usize, y: usize) {
match brush_size { match brush_size {
1 => { 1 => {
self.set_tile(x, y, TileType::Floor); self.set_tile(x, y, Tile::floor());
} }
_ => { _ => {
let half_brush_size = brush_size / 2; let half_brush_size = brush_size / 2;
for brush_y in y-half_brush_size .. y+half_brush_size { for brush_y in y-half_brush_size .. y+half_brush_size {
for brush_x in x-half_brush_size .. x+half_brush_size { for brush_x in x-half_brush_size .. x+half_brush_size {
if brush_x > 1 && brush_x < self.width-1 && brush_y > 1 && brush_y < self.height-1 { if brush_x > 1 && brush_x < self.width-1 && brush_y > 1 && brush_y < self.height-1 {
self.set_tile(brush_x, brush_y, TileType::Floor); self.set_tile(brush_x, brush_y, Tile::floor());
} }
} }
} }
@ -212,7 +230,7 @@ impl fmt::Display for Map {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for y in 0..self.height { for y in 0..self.height {
let bytes: Vec<u8> = (0..self.width) let bytes: Vec<u8> = (0..self.width)
.map(|x| if self.at(x, y) == TileType::Wall {'#'} else {' '} as u8) .map(|x| if self.at(x, y).is_blocked {'#'} else {' '} as u8)
.collect(); .collect();
let line = String::from_utf8(bytes).expect("Can't convert map to string"); let line = String::from_utf8(bytes).expect("Can't convert map to string");
let _ = write!(f, "{}\n", line); let _ = write!(f, "{}\n", line);
@ -233,7 +251,7 @@ mod tests {
let map = Map::new(10, 10); let map = Map::new(10, 10);
for i in 0..10 { for i in 0..10 {
for j in 0..10 { for j in 0..10 {
assert_eq!(map.at(i, j), TileType::Wall); assert!(map.at(i, j).is_blocked);
} }
} }
} }
@ -250,12 +268,12 @@ mod tests {
assert_eq!(map.width, 10); assert_eq!(map.width, 10);
assert_eq!(map.height, 3); assert_eq!(map.height, 3);
for i in 0..10 { for i in 0..10 {
assert_eq!(map.at(i, 0), TileType::Wall); assert!(map.at(i, 0).is_blocked);
assert_eq!(map.at(i, 2), TileType::Wall); assert!(map.at(i, 2).is_blocked);
if i == 0 || i == 9 { if i == 0 || i == 9 {
assert_eq!(map.at(i, 1), TileType::Wall); assert!(map.at(i, 1).is_blocked);
} else { } else {
assert_eq!(map.at(i, 1), TileType::Floor); assert!(map.at(i, 1).is_blocked == false);
} }
} }
} }
@ -281,9 +299,9 @@ mod tests {
for x in 0..map.width { for x in 0..map.width {
for y in 0..map.height { for y in 0..map.height {
if x == 0 || y == 0 || x == 4 || y == 4 { if x == 0 || y == 0 || x == 4 || y == 4 {
assert_eq!(map.at(x, y), TileType::Wall); assert!(map.at(x, y).is_blocked);
} else { } else {
assert_eq!(map.at(x, y), TileType::Floor); assert!(map.at(x, y).is_blocked == false);
} }
} }
} }

View File

@ -4,7 +4,7 @@
//! and the provide generator score as an average. //! and the provide generator score as an average.
//! //!
use super::map::{Map, TileType}; use super::map::Map;
use super::dijkstra::DijkstraMap; use super::dijkstra::DijkstraMap;
@ -13,7 +13,7 @@ use super::dijkstra::DijkstraMap;
/// is probably to degenerated and shouldn't be used /// is probably to degenerated and shouldn't be used
pub fn density(map: &Map) -> f32 { pub fn density(map: &Map) -> f32 {
let floor_count = map.tiles.iter() let floor_count = map.tiles.iter()
.filter(|&t| *t == TileType::Floor) .filter(|&t| t.is_walkable())
.count(); .count();
floor_count as f32 / map.tiles.len() as f32 floor_count as f32 / map.tiles.len() as f32
} }