use rand::Rng; #[derive(PartialEq, Clone, Copy, Debug)] pub enum TileType { Wall, Floor, } impl TileType { pub fn glyph(&self) -> carpet::CP437 { match self { TileType::Wall => carpet::CP437::from_char('#'), TileType::Floor => carpet::CP437::from_u8(0), } } } pub struct Map { pub tiles: carpet::Board, pub rooms: Vec, } impl Map { pub fn new() -> Map { let mut rng = rand::thread_rng(); let mut map = Map { tiles: carpet::Board::new_with_default(80, 50, TileType::Wall), rooms: Vec::new(), }; const MAX_ROOMS: usize = 30; const MIN_SIZE: usize = 6; const MAX_SIZE: usize = 10; for _ in 0..MAX_ROOMS { let w = rng.gen_range(MIN_SIZE, MAX_SIZE); let h = rng.gen_range(MIN_SIZE, MAX_SIZE); let x = rng.gen_range(1, 80 - w); let y = rng.gen_range(1, 50 - h); let room = carpet::Rect::new([x, y], [w, h]); if map.rooms.iter().any(|r| r.overlaps(room)) { continue; } map.carve(room); if let Some(prev) = map.rooms.first() { let c1 = room.center(); let c2 = prev.center(); let join = if rng.gen() { carpet::Coord { x: c1.x, y: c2.y } } else { carpet::Coord { x: c2.x, y: c1.y } }; map.carve(carpet::Rect::from_points(c1, join)); map.carve(carpet::Rect::from_points(join, c2)); } map.rooms.push(room); } map } fn carve(&mut self, rect: carpet::Rect) { let iter = self .tiles .window_iter_mut(rect) .expect(&format!("Rect {:?} of map bounds", rect)); for (_, _, t) in iter { *t = TileType::Floor; } } pub fn passable(&self, (x, y): (usize, usize)) -> bool { Some(&TileType::Floor) == self.tiles.get(x, y) } }