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 web_sys;
use rand::prelude::*;
use mapgen::{Map, MapBuilder, TileType, geometry::Point};
use mapgen::{Map, MapBuilder, geometry::Point};
use mapgen::filter::*;
use mapgen::metric;
@ -34,7 +34,7 @@ impl World {
fn new(width: u32, height: u32, map: Map) -> World {
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();
World { width, height, tiles, map }
}

View File

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

View File

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

View File

@ -23,7 +23,7 @@
use rand::prelude::*;
use crate::MapFilter;
use crate::{Map, TileType};
use crate::{Map, Tile};
/// Map filter
@ -65,14 +65,14 @@ fn apply_iteration(map: &Map) -> Map {
(x-1, y), (x+1, y),
(x-1, y+1), (x, y+1), (x+1, y+1)];
let neighbors = idxs.iter()
.filter(|(x, y)| map.at(*x, *y) == TileType::Wall)
.filter(|(x, y)| map.at(*x, *y).is_blocked())
.count();
if neighbors > 4 || neighbors == 0 {
new_map.set_tile(x, y, TileType::Wall)
new_map.set_tile(x, y, Tile::wall())
}
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() {
let map = Map::new(3, 3);
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);
for i in 0..3 {
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);
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 crate::MapFilter;
use crate::{Map, TileType};
use crate::{Map, Tile};
use crate::dijkstra::DijkstraMap;
@ -30,11 +30,11 @@ impl CullUnreachable {
let dijkstra_map = DijkstraMap::new(map);
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];
// We can't get to this tile - so we'll make it a wall
if distance_to_start == std::f32::MAX {
*tile = TileType::Wall;
*tile = Tile::wall();
}
}
}

View File

@ -16,7 +16,7 @@
use rand::prelude::*;
use crate::MapFilter;
use crate::{
map::{Map, Symmetry, TileType},
map::{Map, Symmetry, Tile},
geometry::Point,
random::Rng
};
@ -79,11 +79,11 @@ impl DrunkardsWalk {
let mut new_map = map.clone();
// Set a central starting point
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 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;
while floor_tile_count < desired_floor_tiles {
let mut drunk_x;
@ -106,7 +106,7 @@ impl DrunkardsWalk {
let mut drunk_life = self.drunken_lifetime;
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);
let stagger_direction = rng.roll_dice(1, 4);
@ -121,7 +121,7 @@ impl DrunkardsWalk {
}
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

View File

@ -16,7 +16,7 @@
use rand::prelude::*;
use crate::MapFilter;
use crate::{
map::{Map, TileType},
map::{Map, Tile},
random::Rng
};
@ -201,17 +201,17 @@ impl<'a> Grid<'a> {
fn copy_to_map(&self, map: &mut 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() {
let x = (cell.column as usize + 1) * 2;
let y = (cell.row as usize + 1) * 2;
map.set_tile(x, y, TileType::Floor);
if !cell.walls[TOP] { map.set_tile(x, y-1, TileType::Floor) }
if !cell.walls[RIGHT] { map.set_tile(x+1, y, TileType::Floor) }
if !cell.walls[BOTTOM] { map.set_tile(x, y+1, TileType::Floor) }
if !cell.walls[LEFT] { map.set_tile(x-1, y, TileType::Floor) }
map.set_tile(x, y, Tile::floor());
if !cell.walls[TOP] { map.set_tile(x, y-1, Tile::floor()) }
if !cell.walls[RIGHT] { map.set_tile(x+1, y, Tile::floor()) }
if !cell.walls[BOTTOM] { map.set_tile(x, y+1, Tile::floor()) }
if !cell.walls[LEFT] { map.set_tile(x-1, y, Tile::floor()) }
}
}
}

View File

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

View File

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

View File

@ -16,7 +16,7 @@
use rand::prelude::*;
use crate::MapFilter;
use crate::{
map::{Map, TileType},
map::{Map, Tile},
random::Rng,
geometry::Point,
};
@ -71,7 +71,7 @@ impl VoronoiHive {
if voronoi_membership[new_map.xy_idx(x, y+1)] != my_seed { neighbors += 1; }
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
//! ```
//! use mapgen::{MapFilter, MapBuilder, Map, TileType};
//! use mapgen::{MapFilter, MapBuilder, Map, Tile};
//! use mapgen::filter::{
//! NoiseGenerator,
//! CellularAutomata,
@ -33,7 +33,7 @@ pub mod geometry;
pub mod map;
pub mod metric;
pub use map::{Map, Symmetry, TileType};
pub use map::{Map, Symmetry, Tile};
pub use filter::*;
pub (crate) mod dijkstra;

View File

@ -12,8 +12,8 @@ use super::geometry::{Point, Rect, usize_abs};
#[derive(PartialEq, Copy, Clone, Debug, Eq, Hash)]
pub enum TileType {
Wall, Floor
pub struct Tile {
is_blocked: bool,
}
#[derive(PartialEq, Copy, Clone)]
@ -23,7 +23,7 @@ pub enum Symmetry { None, Horizontal, Vertical, Both }
/// Map data
#[derive(Default, Clone)]
pub struct Map {
pub tiles : Vec<TileType>,
pub tiles : Vec<Tile>,
pub width : usize,
pub height : usize,
pub starting_point: Option<Point>,
@ -32,13 +32,31 @@ pub struct Map {
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 {
/// Generates an empty map, consisting entirely of solid walls
pub fn new(width: usize, height: usize) -> Map {
let map_tile_count = width*height;
Map{
tiles : vec![TileType::Wall; map_tile_count],
tiles : vec![Tile::wall(); map_tile_count],
width,
height,
starting_point: None,
@ -62,7 +80,7 @@ impl Map {
let line = lines[i].as_bytes();
for j in 0..line.len() {
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
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 {
TileType::Wall
Tile::wall()
} else {
let idx = (y as usize) * self.width + (x as usize);
self.tiles[idx]
@ -100,11 +118,11 @@ impl Map {
// Check if given tile can be accessed
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
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 {
let idx = self.xy_idx(x as usize, y as usize);
self.tiles[idx] = tile;
@ -120,7 +138,7 @@ impl Map {
pub fn add_room(&mut self, rect: Rect) {
for x in rect.x1..rect.x2 {
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);
@ -142,9 +160,9 @@ impl Map {
y -= 1;
}
if self.at(x, y) != TileType::Floor {
if self.at(x, y).is_blocked {
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) {
match brush_size {
1 => {
self.set_tile(x, y, TileType::Floor);
self.set_tile(x, y, Tile::floor());
}
_ => {
let half_brush_size = brush_size / 2;
for brush_y in y-half_brush_size .. y+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 {
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 {
for y in 0..self.height {
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();
let line = String::from_utf8(bytes).expect("Can't convert map to string");
let _ = write!(f, "{}\n", line);
@ -233,7 +251,7 @@ mod tests {
let map = Map::new(10, 10);
for i 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.height, 3);
for i in 0..10 {
assert_eq!(map.at(i, 0), TileType::Wall);
assert_eq!(map.at(i, 2), TileType::Wall);
assert!(map.at(i, 0).is_blocked);
assert!(map.at(i, 2).is_blocked);
if i == 0 || i == 9 {
assert_eq!(map.at(i, 1), TileType::Wall);
assert!(map.at(i, 1).is_blocked);
} 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 y in 0..map.height {
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 {
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.
//!
use super::map::{Map, TileType};
use super::map::Map;
use super::dijkstra::DijkstraMap;
@ -13,7 +13,7 @@ use super::dijkstra::DijkstraMap;
/// is probably to degenerated and shouldn't be used
pub fn density(map: &Map) -> f32 {
let floor_count = map.tiles.iter()
.filter(|&t| *t == TileType::Floor)
.filter(|&t| t.is_walkable())
.count();
floor_count as f32 / map.tiles.len() as f32
}