diff options
| author | Audrey L Fuller <alf9310@g.rit.edu> | 2025-11-10 05:43:24 +0000 |
|---|---|---|
| committer | Audrey L Fuller <alf9310@g.rit.edu> | 2025-11-10 05:43:24 +0000 |
| commit | b897e95c3ae9f423280e65c456ad4371f15ebebe (patch) | |
| tree | 9cb3c4305b1a714552c37ef6cdd9d3a585840422 /dungeon/src/map.rs | |
| parent | Added many auto-gen test cases for maze connectivity (diff) | |
| parent | oops (diff) | |
| download | DungeonCrawl-b897e95c3ae9f423280e65c456ad4371f15ebebe.tar.gz DungeonCrawl-b897e95c3ae9f423280e65c456ad4371f15ebebe.tar.bz2 DungeonCrawl-b897e95c3ae9f423280e65c456ad4371f15ebebe.zip | |
Merge branch 'main' into 'dungeon_generation'
# Conflicts:
# dungeon/src/map.rs
Diffstat (limited to 'dungeon/src/map.rs')
| -rw-r--r-- | dungeon/src/map.rs | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/dungeon/src/map.rs b/dungeon/src/map.rs index 5004dd7..7d79f7f 100644 --- a/dungeon/src/map.rs +++ b/dungeon/src/map.rs @@ -7,6 +7,7 @@ use strum_macros::EnumIter; use std::{ cell::RefCell, + fmt::{Display, Write}, hash::{DefaultHasher, Hash, Hasher}, }; @@ -42,8 +43,15 @@ impl Tile { } /// Returns if the tile is a wall - pub fn is_wall(self) -> bool { - self == Self::Wall + #[must_use] + pub const fn is_wall(self) -> bool { + matches!(self, Self::Wall) + } + + /// Returns if the tile is walkable + #[must_use] + pub const fn is_walkable(self) -> bool { + matches!(self, Self::Air) } // Index by u16 @@ -53,6 +61,16 @@ impl Default for Tile { Self::Wall } } +impl Display for Tile { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let char = match self { + Self::Wall => '#', + Self::Air => '.', + Self::Stairs => '>', + }; + f.write_char(char) + } +} /// The `Floor` type represents the current playing /// grid of the dungeon. It contains the tiles of the @@ -169,8 +187,7 @@ impl Floor { /// Returns the neighbors of a tile inside the floor, checking /// that the neighbor positions are the same tile type as in `pos`. pub fn neighbors(&self, pos: &Pos) -> impl Iterator<Item = Pos> { - let tile = self.get(*pos); - pos.neighbors().filter(move |p| self.get(*p) == tile) + pos.neighbors().filter(|p| self.get(*p).is_walkable()) } /// Computes the hash of the tile map @@ -231,19 +248,19 @@ impl Floor { /// Returns a random open (no wall) position pub fn random_pos(&mut self) -> Pos { loop { - let x = self.rng.random_range(0..MAP_SIZE); - let y = self.rng.random_range(0..MAP_SIZE); - let Some(pos) = Pos::new(x, y) else { - continue; - }; - if self.get(pos) == Tile::Wall { + let pos = self.rand().random(); + if !self.get(pos).is_walkable() { continue; } break pos; } } -} + /// Returns the random number gen for the `Floor` + pub fn rand(&mut self) -> &mut impl Rng { + &mut self.rng + } +} impl Default for Floor { /// Returns a floor with a single set of walls on the map border fn default() -> Self { @@ -260,6 +277,34 @@ impl Default for Floor { Self::new(tiles, player_start, seed) } } +impl Display for Floor { + /// Display the floor as a string for debugging + /// + /// # Examples + /// ```no_run + /// use dungeon::Floor; + /// let floor = Floor::generate(); + /// println!("{floor}"); + /// ``` + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for pos in Pos::values() { + // If it's the player start, show 'P' + if self.player_start == pos { + f.write_char('P')?; + continue; + } + // Otherwise, show the tile character + let tile = self.get(pos); + write!(f, "{tile}")?; + // Newline at the end of each row + if pos.xy().0 == MAP_SIZE - 1 { + writeln!(f)?; + } + } + + Ok(()) + } +} /// Tests #[cfg(test)] @@ -270,8 +315,7 @@ mod tests { #[test] fn test_floor_display() { let floor = Floor::generate(); - let display = floor.display(); // Print the display for visual inspection - println!("{display}"); + println!("{floor}"); } } |