88 lines
2.5 KiB
Rust
88 lines
2.5 KiB
Rust
use super::MapArchitect;
|
|
use crate::prelude::*;
|
|
|
|
const STAGGER_DISTANCE: usize = 400;
|
|
const NUM_TILES: usize = (SCREEN_WIDTH * SCREEN_HEIGHT) as usize;
|
|
const DESIRED_FLOOR: usize = NUM_TILES / 3;
|
|
|
|
pub struct DrunkardsWalkArchitect {}
|
|
|
|
impl MapArchitect for DrunkardsWalkArchitect {
|
|
fn new(&mut self, rng: &mut RandomNumberGenerator) -> MapBuilder {
|
|
let mut mb = MapBuilder {
|
|
map: Map::new(),
|
|
rooms: Vec::new(),
|
|
monster_spawns: Vec::new(),
|
|
player_start: Point::zero(),
|
|
amulet_start: Point::zero(),
|
|
theme: super::themes::DungeonTheme::new(),
|
|
};
|
|
|
|
mb.fill(TileType::Wall);
|
|
let center = Point::new(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
|
|
self.drunkard(¢er, rng, &mut mb.map);
|
|
|
|
while mb
|
|
.map
|
|
.tiles
|
|
.iter()
|
|
.filter(|t| **t == TileType::Floor)
|
|
.count()
|
|
< DESIRED_FLOOR
|
|
{
|
|
self.drunkard(
|
|
&Point::new(rng.range(0, SCREEN_WIDTH), rng.range(0, SCREEN_HEIGHT)),
|
|
rng,
|
|
&mut mb.map,
|
|
);
|
|
|
|
let dijkstra_map = DijkstraMap::new(
|
|
SCREEN_WIDTH,
|
|
SCREEN_HEIGHT,
|
|
&[mb.map.point2d_to_index(center)],
|
|
&mb.map,
|
|
1024.0,
|
|
);
|
|
dijkstra_map
|
|
.map
|
|
.iter()
|
|
.enumerate()
|
|
.filter(|(_, distance)| *distance > &2000.0)
|
|
.for_each(|(idx, _)| mb.map.tiles[idx] = TileType::Wall);
|
|
}
|
|
|
|
mb.monster_spawns = mb.spawn_monsters(¢er, rng);
|
|
mb.player_start = center;
|
|
mb.amulet_start = mb.find_most_distant(&mb.player_start);
|
|
|
|
mb
|
|
}
|
|
}
|
|
|
|
impl DrunkardsWalkArchitect {
|
|
fn drunkard(&mut self, start: &Point, rng: &mut RandomNumberGenerator, map: &mut Map) {
|
|
let mut drunkard_pos = start.clone();
|
|
let mut distance_staggered = 0;
|
|
|
|
loop {
|
|
let drunk_idx = map.point2d_to_index(drunkard_pos);
|
|
map.tiles[drunk_idx] = TileType::Floor;
|
|
|
|
match rng.range(0, 4) {
|
|
0 => drunkard_pos.x -= 1,
|
|
1 => drunkard_pos.x += 1,
|
|
2 => drunkard_pos.y -= 1,
|
|
_ => drunkard_pos.y += 1,
|
|
}
|
|
if !map.in_bounds(drunkard_pos) {
|
|
break;
|
|
}
|
|
|
|
distance_staggered += 1;
|
|
if distance_staggered > STAGGER_DISTANCE {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|