From 2e2d4525ec0a3f271b51b72ba68d12f993e287e1 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Wed, 6 Nov 2024 11:16:53 +0200 Subject: [PATCH] refactor(maze): move files to src dir --- src/lib.rs | 13 +++++- src/maze.rs | 95 +++++++++++++++++++++++++++++++++++++++++ src/maze/maze.rs | 38 ----------------- src/maze/mod.rs | 7 --- src/{maze => }/tile.rs | 11 ++++- src/{maze => }/walls.rs | 41 ++++++++++++++---- 6 files changed, 148 insertions(+), 57 deletions(-) create mode 100644 src/maze.rs delete mode 100644 src/maze/maze.rs delete mode 100644 src/maze/mod.rs rename src/{maze => }/tile.rs (56%) rename src/{maze => }/walls.rs (53%) diff --git a/src/lib.rs b/src/lib.rs index e80a3ad..e320cbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,12 @@ -pub mod maze; +mod maze; +mod tile; +mod walls; -pub use maze::*; +pub use maze::HexMaze; +pub use tile::HexTile; +pub use walls::Walls; + +pub mod prelude { + pub use super::{HexMaze, HexTile, Walls}; + pub use hexx::{EdgeDirection, Hex, HexLayout}; +} diff --git a/src/maze.rs b/src/maze.rs new file mode 100644 index 0000000..59e5667 --- /dev/null +++ b/src/maze.rs @@ -0,0 +1,95 @@ +use std::collections::HashMap; + +use hexx::{EdgeDirection, Hex, HexLayout}; + +use super::{HexTile, Walls}; + +/// Represents a hexagonal maze with tiles and walls +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone)] +pub struct HexMaze { + tiles: HashMap, + layout: HexLayout, +} + +impl HexMaze { + /// Creates a new empty maze with the specified layout + #[inline] + pub fn new(layout: HexLayout) -> Self { + Self { + tiles: HashMap::new(), + layout, + } + } + + /// Adds a new tile at the specified coordinates + #[inline] + pub fn add_tile(&mut self, coords: Hex) { + let tile = HexTile::new(coords); + self.tiles.insert(coords, tile); + } + + /// Adds a wall in the specified direction at the given coordinates + #[inline] + pub fn add_wall(&mut self, coord: Hex, direction: EdgeDirection) { + if let Some(tile) = self.tiles.get_mut(&coord) { + tile.walls.add(direction) + } + } + + /// Returns a reference to the tile at the specified coordinates + #[inline] + pub fn get_tile(&self, coord: &Hex) -> Option<&HexTile> { + self.tiles.get(coord) + } + + /// Returns a reference to the walls at the specified coordinates + #[inline] + pub fn get_walls(&self, coord: &Hex) -> Option<&Walls> { + self.tiles.get(coord).map(|tile| tile.walls()) + } + + /// Returns the layout of the maze + #[inline] + pub fn layout(&self) -> &HexLayout { + &self.layout + } + + /// Returns an iterator over all tiles + #[inline] + pub fn tiles(&self) -> impl Iterator { + self.tiles.iter() + } + + /// Returns the number of tiles in the maze + #[inline] + pub fn len(&self) -> usize { + self.tiles.len() + } + + /// Returns true if the maze is empty + #[inline] + pub fn is_empty(&self) -> bool { + self.tiles.is_empty() + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn maze() { + let layout = HexLayout::default(); + let mut maze = HexMaze::new(layout); + let coord = Hex::ZERO; + + maze.add_tile(coord); + assert!(maze.get_tile(&coord).is_some()); + + maze.add_wall(coord, EdgeDirection::FLAT_TOP_LEFT); + assert!(maze + .get_walls(&coord) + .unwrap() + .has(EdgeDirection::FLAT_TOP_LEFT)); + } +} diff --git a/src/maze/maze.rs b/src/maze/maze.rs deleted file mode 100644 index fdb53cf..0000000 --- a/src/maze/maze.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::collections::HashMap; - -use hexx::{EdgeDirection, Hex, HexLayout}; - -use super::{HexTile, Walls}; - -pub struct HexMaze { - pub tiles: HashMap, - pub layout: HexLayout, -} - -impl HexMaze { - pub fn new(layout: HexLayout) -> Self { - Self { - tiles: HashMap::new(), - layout, - } - } - - pub fn add_tile(&mut self, coords: Hex) { - let tile = HexTile::new(coords); - self.tiles.insert(coords, tile); - } - - pub fn add_wall(&mut self, coord: Hex, direction: EdgeDirection) { - if let Some(tile) = self.tiles.get_mut(&coord) { - tile.walls.add(direction) - } - } - - pub fn get_tile(&self, coord: &Hex) -> Option<&HexTile> { - self.tiles.get(coord) - } - - pub fn get_walls(&self, coord: &Hex) -> Option<&Walls> { - self.tiles.get(coord).map(|tile| &tile.walls) - } -} diff --git a/src/maze/mod.rs b/src/maze/mod.rs deleted file mode 100644 index a0ca907..0000000 --- a/src/maze/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod maze; -pub mod tile; -pub mod walls; - -pub use maze::HexMaze; -pub use tile::HexTile; -pub use walls::Walls; diff --git a/src/maze/tile.rs b/src/tile.rs similarity index 56% rename from src/maze/tile.rs rename to src/tile.rs index 0bf099c..0dfaf28 100644 --- a/src/maze/tile.rs +++ b/src/tile.rs @@ -2,18 +2,27 @@ use hexx::Hex; use super::Walls; +/// Represents a single hexagonal tile in the maze #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct HexTile { - pub pos: Hex, + pos: Hex, pub walls: Walls, } impl HexTile { + /// Creates a new tile with pos and default walls + #[inline] pub fn new(pos: Hex) -> Self { Self { pos, walls: Walls::default(), } } + + /// Returns a reference to the tile's walls + #[inline] + pub fn walls(&self) -> &Walls { + &self.walls + } } diff --git a/src/maze/walls.rs b/src/walls.rs similarity index 53% rename from src/maze/walls.rs rename to src/walls.rs index f83e3e8..887b19b 100644 --- a/src/maze/walls.rs +++ b/src/walls.rs @@ -2,39 +2,46 @@ use std::ops::{Deref, DerefMut}; use hexx::EdgeDirection; +/// Represents the walls of a hexagonal tile using bit flags #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Walls(u8); impl Walls { + /// Creates a new walls configuration with all walls + #[inline] pub fn new() -> Self { Self::default() } + /// Adds a wall in the specified direction + #[inline] pub fn add(&mut self, direction: EdgeDirection) { self.0 |= Self::from(direction).0 } + /// Removes a wall in the specified direction + #[inline] pub fn remove(&mut self, direction: EdgeDirection) { self.0 &= !Self::from(direction).0 } + /// Returns true if there is a wall in the specified direction + #[inline] pub fn has(&self, direction: EdgeDirection) -> bool { self.0 & Self::from(direction).0 != 0 } + + /// Returns the raw bit representation of the walls + #[inline] + pub fn as_bits(&self) -> u8 { + self.0 + } } impl From for Walls { fn from(value: EdgeDirection) -> Self { - let bits = match value.index() { - 0 => 0b000001, - 1 => 0b000010, - 2 => 0b000011, - 3 => 0b000100, - 4 => 0b000101, - 5 => 0b000110, - _ => unreachable!(), - }; + let bits = 1 << value.index(); Self(bits) } } @@ -58,3 +65,19 @@ impl Default for Walls { Self(0b111111) } } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn walls() { + let mut walls = Walls::new(); + assert!(walls.has(EdgeDirection::FLAT_TOP)); + + walls.remove(EdgeDirection::FLAT_TOP); + assert!(!walls.has(EdgeDirection::FLAT_TOP)); + + walls.add(EdgeDirection::FLAT_TOP); + assert!(walls.has(EdgeDirection::FLAT_TOP)); + } +}