//! The `map` module contains structures of the dungeon game map //! including the current `Floor`, map `Tile`, and `Entity`. use crate::pos::{Direction, Pos}; /// `MAP_SIZE` is the size of the size of the dungeon grid. pub const MAP_SIZE: u16 = 100; /// `MAP_SIZE` as a usize pub const MAP_SIZE_USIZE: usize = MAP_SIZE as usize; /// The number of tiles in the dungeon grid pub const TILE_COUNT: usize = MAP_SIZE_USIZE * MAP_SIZE_USIZE; /// The `EntityKind` represents what kind of entity this is. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum EntityKind { Player, } /// The `Entity` kind represents the main player, or any other /// ai autonomous character that can move freely across the /// dungeon. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Entity { pos: Pos, dir: Direction, kind: EntityKind, } impl Entity { /// Creates a new `Entity` at a given `Pos`, `Direction`, and `EntityKind`. /// /// # Examples /// /// ``` /// use dungeon::{Pos, Direction, Entity, EntityKind}; /// /// let pos = Pos::new(0, 0).unwrap(); /// let dir = Direction::North; /// let kind = EntityKind::Player; /// let entity = Entity::new(pos, dir, kind); /// ``` #[must_use] pub const fn new(pos: Pos, dir: Direction, kind: EntityKind) -> Self { Self { pos, dir, kind } } /// Creates the Player version of the `Entity` /// /// # Examples /// /// ``` /// use dungeon::{Pos, Entity}; /// /// let pos = Pos::new(0, 0).unwrap(); /// let player = Entity::player(pos); /// ``` #[must_use] pub const fn player(pos: Pos) -> Self { let dir = Direction::East; let kind = EntityKind::Player; Self::new(pos, dir, kind) } /// Returns the `Pos` of the entity #[must_use] pub const fn pos(&self) -> Pos { self.pos } /// Returns a mutable referense to the `Pos` of the entity #[must_use] pub const fn pos_mut(&mut self) -> &mut Pos { &mut self.pos } /// Returns the `Direction` of the entity #[must_use] pub const fn dir(&self) -> Direction { self.dir } /// Returns a mutable referense to the `Direction` of the entity #[must_use] pub const fn dir_mut(&mut self) -> &mut Direction { &mut self.dir } /// Returns the `EntityKind` of this entity #[must_use] pub const fn kind(&self) -> EntityKind { self.kind } } /// The `Tile` enum represents what is (or is not) at /// any given spot in the dungeon grid. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum Tile { /// `Wall` represents an impassible wall Wall, /// `Air` represents empty walkable space Air, } /// The `Floor` type represents the current playing /// grid of the dungeon. It contains the tiles of the /// grid, and the starting position of the player. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Floor { /// The dungeon grid tiles: Box<[Tile; TILE_COUNT]>, /// The position the player starts at player_start: Pos, /// The seed used when generating the dungeon grid seed: u64, } impl Floor { /// Generates a dungeon `Floor` using wave function collapse. /// /// # Examples /// /// ```no_run /// use dungeon::Floor; /// /// let floor = Floor::generate(); /// ``` #[must_use] pub fn generate() -> Self { let seed = rand::random(); Self::generate_seeded(seed) } /// Genreates a dungeon `Floor` using wave function collapse provided with a seed. /// /// The provided seed is used for randomness in the wave function /// collapse algorithm. /// /// # Examples /// /// ```no_run /// use dungeon::Floor; /// /// /// here is our very seedy seed /// let seed = 2893249402u64; /// let floor = Floor::generate_seeded(seed); /// ``` #[must_use] pub fn generate_seeded(_seed: u64) -> Self { unimplemented!() } /// Returns the start position of the player #[must_use] pub const fn player_start(&self) -> Pos { self.player_start } /// Returns the seed used to generate the map #[must_use] pub const fn seed(&self) -> u64 { self.seed } /// Returns a `Tile` on the dungeon grid at `Pos`. #[must_use] pub const fn get(&self, pos: Pos) -> Tile { let idx = pos.idx(); self.tiles[idx] } /// Returns a multable reference to a `Tile` on the dungeon grid at `Pos`. #[must_use] pub const fn get_mut(&mut self, pos: Pos) -> &mut Tile { let idx = pos.idx(); &mut self.tiles[idx] } /// Returns a reference to all tiles in the `Floor`. /// The size of this lise will always be `TILE_COUNT` long. #[must_use] pub const fn tiles(&self) -> &[Tile] { &*self.tiles } /// Returns a mutable reference to all tiles in the `Floor`. /// The size of this lise will always be `TILE_COUNT` long. #[must_use] pub const fn tiles_mut(&mut self) -> &mut [Tile] { &mut *self.tiles } } impl Default for Floor { /// Returns a floor with a single set of walls on the map border fn default() -> Self { const PLAYER_START: Pos = Pos::new_const::<1, 1>(); let mut tiles = Box::new([Tile::Air; TILE_COUNT]); let seed = 0u64; for pos in Pos::values() { if pos.is_border() { tiles[pos.idx()] = Tile::Wall; } } Self { tiles, player_start: PLAYER_START, seed, } } }