feat(walls): add more methods

This commit is contained in:
Kristofers Solo 2024-11-29 17:33:19 +02:00
parent cb52be461a
commit 7d5d0743b9
3 changed files with 593 additions and 137 deletions

4
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 4
[[package]] [[package]]
name = "ab_glyph" name = "ab_glyph"
@ -2063,7 +2063,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]] [[package]]
name = "hexlab" name = "hexlab"
version = "0.1.2" version = "0.1.3"
dependencies = [ dependencies = [
"bevy", "bevy",
"hexx", "hexx",

View File

@ -1,7 +1,7 @@
[package] [package]
name = "hexlab" name = "hexlab"
authors = ["Kristofers Solo <dev@kristofers.xyz>"] authors = ["Kristofers Solo <dev@kristofers.xyz>"]
version = "0.1.2" version = "0.1.3"
edition = "2021" edition = "2021"
description = "A hexagonal maze generation and manipulation library" description = "A hexagonal maze generation and manipulation library"
repository = "https://github.com/kristoferssolo/hexlab" repository = "https://github.com/kristoferssolo/hexlab"

View File

@ -1,13 +1,47 @@
use std::{
fmt::Debug,
ops::{Deref, DerefMut},
};
#[cfg(feature = "bevy")] #[cfg(feature = "bevy")]
use bevy::prelude::*; use bevy::prelude::{Component, Reflect, ReflectComponent};
use hexx::EdgeDirection; use hexx::EdgeDirection;
/// Represents the walls of a hexagonal tile using bit flags /// A bit-flag representation of walls in a hexagonal tile.
///
/// `Walls` uses an efficient bit-flag system to track the presence or absence of walls
/// along each edge of a hexagonal tile. Each of the six possible walls is represented
/// by a single bit in an 8-bit integer, allowing for fast operations and minimal memory usage.
///
/// # Examples
///
/// Creating and manipulating walls:
/// ```rust
/// use hexlab::prelude::*;
///
/// // Create a hexagon with all walls
/// let walls = Walls::new();
/// assert!(walls.is_closed());
///
/// // Create a hexagon with no walls
/// let mut walls = Walls::empty();
/// assert!(walls.is_empty());
///
/// // Add specific walls
/// walls.add(EdgeDirection::FLAT_NORTH);
/// walls.add(EdgeDirection::FLAT_SOUTH);
/// assert_eq!(walls.count(), 2);
/// ```
///
/// Using walls in game logic:
///
/// ```rust
/// use hexlab::prelude::*;
/// let mut walls = Walls::empty();
///
/// // Add walls to create a corner
/// walls.add(EdgeDirection::FLAT_NORTH);
/// walls.add(EdgeDirection::FLAT_SOUTH_EAST);
///
/// // Check if a specific direction has a wall
/// assert!(walls.contains(EdgeDirection::FLAT_NORTH));
/// assert!(!walls.contains(EdgeDirection::FLAT_SOUTH));
/// ```
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "bevy", derive(Reflect, Component))] #[cfg_attr(feature = "bevy", derive(Reflect, Component))]
@ -15,38 +49,279 @@ use hexx::EdgeDirection;
pub struct Walls(u8); pub struct Walls(u8);
impl Walls { impl Walls {
/// Creates a new set of walls with all edges closed.
///
/// This is the default state where all six edges of the hexagon have walls.
///
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let walls = Walls::new();
/// assert!(walls.is_closed());
/// assert_eq!(walls.count(), 6);
/// ```
pub fn new() -> Self {
Self::default()
}
/// Creates a new set of walls with no edges (completely open).
///
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let walls = Walls::empty();
/// assert!(walls.is_empty());
/// assert_eq!(walls.count(), 0);
/// ```
pub fn empty() -> Self {
Self(0)
}
/// Checks if the walls are currently empty
///
/// Returns `true` if all directions have no walls set.
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let walls = Walls::empty();
/// assert!(walls.is_empty());
///
/// let walls = Walls::new();
/// assert!(!walls.is_empty());
/// ```
pub fn is_empty(&self) -> bool {
self.0 == 0
}
/// Adds a wall in the specified direction /// Adds a wall in the specified direction
///
/// This method uses bitwise operations to efficiently set the wall flag
/// for the given direction. Multiple walls can be added to the same hexagon.
///
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::empty();
/// walls.add(EdgeDirection::FLAT_NORTH);
/// assert!(walls.contains(EdgeDirection::FLAT_NORTH));
/// assert!(!walls.contains(EdgeDirection::FLAT_SOUTH));
///
/// walls.add(EdgeDirection::FLAT_SOUTH);
/// assert!(walls.contains(EdgeDirection::FLAT_SOUTH));
/// assert_eq!(walls.count(), 2);
/// ```
#[inline] #[inline]
pub fn add<T>(&mut self, direction: T) pub fn add<T>(&mut self, direction: T)
where where
T: Into<Self>, T: Into<Self> + Copy,
{ {
self.0 |= direction.into().0; self.0 |= direction.into().0;
} }
/// Removes a wall in the specified direction /// Removes a wall in the specified direction
///
/// Returns `true` if a wall was actually removed, `false` if there was no wall
/// in the specified direction.
///
/// # Exmaples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::new();
/// assert!(walls.remove(EdgeDirection::FLAT_NORTH));
/// assert!(!walls.contains(EdgeDirection::FLAT_NORTH));
///
/// // Removing a non-existent wall returns false
/// assert!(!walls.remove(EdgeDirection::FLAT_NORTH));
/// ```
#[inline] #[inline]
pub fn remove<T>(&mut self, direction: T) pub fn remove<T>(&mut self, direction: T) -> bool
where where
T: Into<Self>, T: Into<Self> + Copy,
{ {
self.0 &= !direction.into().0; let was_removed = self.contains(direction);
if was_removed {
self.0 &= !direction.into().0;
}
was_removed
} }
/// Returns true if there is a wall in the specified direction /// Returns true if there is a wall in the specified direction
///
/// Uses efficient bitwise operations to check for the presence of a wall.
///
/// # Exmaples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::empty();
///
/// walls.add(EdgeDirection::FLAT_NORTH);
/// assert!(walls.contains(EdgeDirection::FLAT_NORTH));
/// assert!(!walls.contains(EdgeDirection::FLAT_SOUTH));
/// ```
#[inline] #[inline]
pub fn contains<T>(&self, other: T) -> bool pub fn contains<T>(&self, other: T) -> bool
where where
T: Into<Self>, T: Into<Self> + Copy,
{ {
self.0 & other.into().0 != 0 self.0 & other.into().0 != 0
} }
/// Returns the raw bit representation of the walls /// Returns the raw bit representation of the walls
///
/// This method provides access to the underlying bit flags for advanced usage.
/// The bits are ordered according to the `EdgeDirection` indices.
///
/// # Exmaples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::new();
///
/// assert_eq!(walls.as_bits(), 0b111111);
/// ```
#[inline] #[inline]
pub fn as_bits(&self) -> u8 { pub fn as_bits(&self) -> u8 {
self.0 self.0
} }
/// Returns the total number of walls present
///
/// Efficiently counts the number of set bits in the internal representation.
///
/// # Exmaples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::empty();
///
/// assert_eq!(walls.count(), 0);
///
/// walls.add(EdgeDirection::FLAT_NORTH);
/// walls.add(EdgeDirection::FLAT_SOUTH);
/// assert_eq!(walls.count(), 2);
/// ```
#[inline]
pub fn count(&self) -> u8 {
self.0.count_ones() as u8
}
/// Returns all possible directions as a `Walls` value
///
/// This represents a hexagon with walls in all six directions.
///
/// # Exmaples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let all_walls = Walls::all_directions();
///
/// assert_eq!(all_walls.count(), 6);
/// assert!(all_walls.is_closed());
/// ```
#[inline]
pub fn all_directions() -> Self {
Self(0b111111)
}
/// Toggles a wall in the specified direction.
///
/// If a wall exists in the given direction, it will be removed.
/// If no wall exists, one will be added.
/// Returns the previous state (`true` if a wall was present).
///
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::empty();
///
/// assert!(!walls.toggle(EdgeDirection::FLAT_NORTH)); // Returns false, wall was not present
/// assert!(walls.contains(EdgeDirection::FLAT_NORTH)); // Wall is now present
///
/// let mut walls = Walls::new();
///
/// assert!(walls.toggle(EdgeDirection::FLAT_NORTH)); // Returns true, wall was present
/// assert!(!walls.contains(EdgeDirection::FLAT_NORTH)); // Wall is now removed
/// ```
pub fn toggle<T>(&mut self, direction: T) -> bool
where
T: Into<Self> + Copy,
{
let is_present = self.contains(direction);
if is_present {
self.remove(direction);
} else {
self.add(direction);
}
is_present
}
/// Checks if walls are present in all six directions.
///
/// Returns `true` if the hexagon has all possible walls, making it completely enclosed.
///
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let walls = Walls::new();
/// assert!(walls.is_closed());
///
/// let mut walls = Walls::empty();
/// assert!(!walls.is_closed());
/// // Add all walls manually
/// for direction in EdgeDirection::iter() {
/// walls.add(direction);
/// }
/// assert!(walls.is_closed());
/// ```
#[inline]
pub fn is_closed(&self) -> bool {
self.count() == 6
}
/// Sets walls for multiple directions at once.
///
/// This method efficiently adds multiple walls in a single operation while
/// preserving any existing walls not specified in the input.
///
/// # Examples
///
/// ```rust
/// use hexlab::prelude::*;
///
/// let mut walls = Walls::empty();
/// walls.add(EdgeDirection::FLAT_NORTH);
///
/// walls.fill([EdgeDirection::FLAT_SOUTH, EdgeDirection::FLAT_SOUTH_EAST]);
///
/// assert!(walls.contains(EdgeDirection::FLAT_SOUTH));
/// assert_eq!(walls.count(), 3);
/// ```
#[inline]
pub fn fill<T>(&mut self, other: T)
where
T: Into<Self>,
{
self.0 |= other.into().0;
}
} }
impl From<EdgeDirection> for Walls { impl From<EdgeDirection> for Walls {
@ -55,33 +330,25 @@ impl From<EdgeDirection> for Walls {
} }
} }
impl From<[EdgeDirection; 6]> for Walls {
fn from(value: [EdgeDirection; 6]) -> Self {
let mut walls = 0u8;
for direction in value {
walls |= 1 << direction.index();
}
Self(walls)
}
}
impl From<u8> for Walls { impl From<u8> for Walls {
fn from(value: u8) -> Self { fn from(value: u8) -> Self {
Self(1 << value) Self(1 << value)
} }
} }
impl Deref for Walls { impl FromIterator<EdgeDirection> for Walls {
type Target = u8; fn from_iter<T: IntoIterator<Item = EdgeDirection>>(iter: T) -> Self {
let mut walls = 0u8;
fn deref(&self) -> &Self::Target { for direction in iter {
&self.0 walls |= 1 << direction.index();
}
Self(walls)
} }
} }
impl DerefMut for Walls { impl<const N: usize> From<[EdgeDirection; N]> for Walls {
fn deref_mut(&mut self) -> &mut Self::Target { fn from(value: [EdgeDirection; N]) -> Self {
&mut self.0 value.into_iter().collect()
} }
} }
@ -95,119 +362,308 @@ impl Default for Walls {
mod tests { mod tests {
use super::*; use super::*;
// all_directions
#[test] #[test]
fn new_walls() { fn all_directions_creates_closed_walls() {
let walls = Walls::default(); let walls = Walls::all_directions();
// All walls should be present by default assert!(walls.is_closed());
for direction in EdgeDirection::iter() { assert!(!walls.is_empty());
assert!( assert_eq!(walls.as_bits(), 0b111111);
walls.contains(direction),
"Wall should exist in direction {:?}",
direction
);
}
} }
// as_bits
#[test] #[test]
fn add_remove_single_wall() { fn as_bits_empty() {
let mut walls = Walls::default(); let walls = Walls::empty();
// Remove and verify each wall
walls.remove(EdgeDirection::FLAT_TOP);
assert!(!walls.contains(EdgeDirection::FLAT_TOP));
// Add back and verify
walls.add(EdgeDirection::FLAT_TOP);
assert!(walls.contains(EdgeDirection::FLAT_TOP));
}
#[test]
fn multiple_operations() {
let mut walls = Walls::default();
// Remove multiple walls
walls.remove(EdgeDirection::FLAT_TOP);
walls.remove(EdgeDirection::FLAT_BOTTOM);
// Verify removed walls
assert!(!walls.contains(EdgeDirection::FLAT_TOP));
assert!(!walls.contains(EdgeDirection::FLAT_BOTTOM));
// Verify other walls still exist
assert!(walls.contains(EdgeDirection::FLAT_TOP_RIGHT));
assert!(walls.contains(EdgeDirection::FLAT_TOP_LEFT));
// Add back one wall
walls.add(EdgeDirection::FLAT_TOP);
assert!(walls.contains(EdgeDirection::FLAT_TOP));
assert!(!walls.contains(EdgeDirection::FLAT_BOTTOM));
}
#[test]
fn bit_patterns() {
let mut walls = Walls::default();
assert_eq!(
walls.as_bits(),
0b111111,
"Initial state should have all walls"
);
walls.remove(EdgeDirection::FLAT_BOTTOM_RIGHT);
assert_eq!(walls.as_bits() & 0b000001, 0, "First bit should be cleared");
walls.add(EdgeDirection::FLAT_BOTTOM_RIGHT);
assert_eq!(walls.as_bits() & 0b000001, 1, "First bit should be set");
}
#[test]
fn remove_all_walls() {
let mut walls = Walls::default();
// Remove all walls
for direction in EdgeDirection::iter() {
walls.remove(direction);
}
// Verify all walls are removed
assert_eq!(walls.as_bits(), 0, "All walls should be removed");
// Verify each direction
for direction in EdgeDirection::iter() {
assert!(
!walls.contains(direction),
"No wall should exist in direction {:?}",
direction
);
}
}
#[test]
fn deref_operations() {
let mut walls = Walls::default();
// Test Deref
let bits: &u8 = walls.deref();
assert_eq!(*bits, 0b111111);
// Test DerefMut
*walls.deref_mut() = 0;
assert_eq!(walls.as_bits(), 0); assert_eq!(walls.as_bits(), 0);
} }
#[test] #[test]
fn idempotent_operations() { fn as_bits_single_wall() {
let mut walls = Walls::default(); let mut walls = Walls::empty();
walls.add(EdgeDirection::FLAT_NORTH);
assert_eq!(walls.as_bits(), 0b010000);
}
// Adding twice shouldn't change the result #[test]
walls.add(EdgeDirection::FLAT_TOP); fn as_bits_multiple_walls() {
let first_add = walls.as_bits(); let mut walls = Walls::empty();
walls.add(EdgeDirection::FLAT_TOP); walls.add(EdgeDirection::FLAT_NORTH);
assert_eq!(walls.as_bits(), first_add); walls.add(EdgeDirection::FLAT_SOUTH);
assert_eq!(walls.as_bits(), 0b010010);
}
// Removing twice shouldn't change the result #[test]
walls.remove(EdgeDirection::FLAT_TOP); fn as_bits_all_walls() {
let first_remove = walls.as_bits(); let walls = Walls::new();
walls.remove(EdgeDirection::FLAT_TOP); assert_eq!(walls.as_bits(), 0b111111);
assert_eq!(walls.as_bits(), first_remove); }
// new
#[test]
fn new_created_closed_walls() {
let walls = Walls::new();
assert!(walls.is_closed());
assert_eq!(walls.as_bits(), 0b111111);
}
// empty
#[test]
fn empty_creates_no_walls() {
let walls = Walls::empty();
assert!(walls.is_empty());
assert_eq!(walls.as_bits(), 0);
}
// add
#[test]
fn add_single_wall() {
let mut walls = Walls::empty();
walls.add(EdgeDirection::FLAT_NORTH);
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
assert_eq!(walls.count(), 1);
}
// remove
#[test]
fn remove_existing_wall() {
let mut walls = Walls::new();
assert!(walls.remove(EdgeDirection::FLAT_NORTH));
assert!(!walls.contains(EdgeDirection::FLAT_NORTH));
}
#[test]
fn remove_nonexistent_wall() {
let mut walls = Walls::empty();
assert!(!walls.remove(EdgeDirection::FLAT_NORTH));
walls.add(EdgeDirection::FLAT_NORTH);
assert!(walls.remove(EdgeDirection::FLAT_NORTH));
}
// toggle
#[test]
fn toggle_adds_wall() {
let mut walls = Walls::empty();
assert!(!walls.toggle(EdgeDirection::FLAT_NORTH));
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
}
#[test]
fn toggle_removes_wall() {
let mut walls = Walls::new();
assert!(walls.toggle(EdgeDirection::FLAT_NORTH));
assert!(!walls.contains(EdgeDirection::FLAT_NORTH));
}
// fill
#[test]
fn fill_adds_multiple_walls() {
let mut walls = Walls::empty();
walls.fill([EdgeDirection::FLAT_NORTH, EdgeDirection::FLAT_SOUTH]);
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
assert!(walls.contains(EdgeDirection::FLAT_SOUTH));
assert_eq!(walls.count(), 2);
}
#[test]
fn fill_preserves_existing_walls() {
let mut walls = Walls::empty();
walls.add(EdgeDirection::FLAT_NORTH);
walls.fill([EdgeDirection::FLAT_SOUTH, EdgeDirection::FLAT_SOUTH_EAST]);
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
assert!(walls.contains(EdgeDirection::FLAT_SOUTH));
assert!(walls.contains(EdgeDirection::FLAT_SOUTH_EAST));
assert_eq!(walls.count(), 3);
}
#[test]
fn from_edge_direction_conversion() {
let walls: Walls = EdgeDirection::FLAT_NORTH.into();
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
assert_eq!(walls.count(), 1);
}
#[test]
fn from_u8_conversion() {
let walls: Walls = 0u8.into();
assert!(walls.contains(EdgeDirection::FLAT_SOUTH_EAST));
assert_eq!(walls.count(), 1);
}
#[test]
fn from_array_conversion() {
let walls: Walls = [EdgeDirection::FLAT_NORTH, EdgeDirection::FLAT_SOUTH].into();
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
assert!(walls.contains(EdgeDirection::FLAT_SOUTH));
assert_eq!(walls.count(), 2);
}
#[test]
fn from_iterator_handles_duplicates() {
let directions = vec![
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_SOUTH,
EdgeDirection::FLAT_NORTH, // Duplicate
];
let walls: Walls = directions.into_iter().collect();
assert_eq!(walls.count(), 2);
}
#[test]
fn default_creates_closed_walls() {
let walls = Walls::default();
assert!(walls.is_closed());
assert_eq!(walls.as_bits(), 0b111111);
}
#[test]
fn from_iterator() {
let directions = vec![
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_SOUTH,
EdgeDirection::FLAT_NORTH, // Duplicate should not affect result
];
let walls: Walls = directions.into_iter().collect();
assert_eq!(walls.count(), 2);
assert!(walls.contains(EdgeDirection::FLAT_NORTH));
assert!(walls.contains(EdgeDirection::FLAT_SOUTH));
}
#[test]
fn bit_manipulation() {
let mut walls = Walls::empty();
// Test single bit operations
walls.add(EdgeDirection::FLAT_NORTH);
assert_eq!(walls.as_bits(), 0b010000);
walls.add(EdgeDirection::FLAT_SOUTH);
assert_eq!(walls.as_bits(), 0b010010);
// Test removing middle bit
walls.add(EdgeDirection::FLAT_SOUTH_EAST);
assert_eq!(walls.as_bits(), 0b010011);
walls.remove(EdgeDirection::FLAT_SOUTH);
assert_eq!(walls.as_bits(), 0b010001);
}
// From<EdgeDirection> tests
#[test]
fn from_edge_direction_flat_south_east() {
let walls = Walls::from(EdgeDirection::FLAT_SOUTH_EAST);
assert_eq!(walls.as_bits(), 0b000001);
}
#[test]
fn from_edge_direction_flat_south() {
let walls = Walls::from(EdgeDirection::FLAT_SOUTH);
assert_eq!(walls.as_bits(), 0b000010);
}
#[test]
fn from_edge_direction_flat_south_west() {
let walls = Walls::from(EdgeDirection::FLAT_SOUTH_WEST);
assert_eq!(walls.as_bits(), 0b000100);
}
#[test]
fn from_edge_direction_flat_north_west() {
let walls = Walls::from(EdgeDirection::FLAT_NORTH_WEST);
assert_eq!(walls.as_bits(), 0b001000);
}
#[test]
fn from_edge_direction_flat_north() {
let walls = Walls::from(EdgeDirection::FLAT_NORTH);
assert_eq!(walls.as_bits(), 0b010000);
}
#[test]
fn from_edge_direction_flat_east() {
let walls = Walls::from(EdgeDirection::FLAT_NORTH_EAST);
assert_eq!(walls.as_bits(), 0b100000);
}
// FromIterator tests
#[test]
fn from_iterator_empty() {
let walls = Vec::new().into_iter().collect::<Walls>();
assert!(walls.is_empty());
}
#[test]
fn from_iterator_single() {
let walls = vec![EdgeDirection::FLAT_SOUTH]
.into_iter()
.collect::<Walls>();
assert_eq!(walls.as_bits(), 0b000010);
}
#[test]
fn from_iterator_multiple() {
let walls = vec![EdgeDirection::FLAT_NORTH, EdgeDirection::FLAT_SOUTH]
.into_iter()
.collect::<Walls>();
assert_eq!(walls.as_bits(), 0b010010);
}
#[test]
fn from_iterator_duplicates() {
let walls = vec![
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_SOUTH,
]
.into_iter()
.collect::<Walls>();
assert_eq!(walls.as_bits(), 0b010010);
}
#[test]
fn from_iterator_all_directions() {
let walls = EdgeDirection::iter().collect::<Walls>();
assert_eq!(walls.as_bits(), 0b111111);
}
// From<[EdgeDirection; N]> tests
#[test]
fn from_array_empty() {
let walls = Walls::from([]);
assert!(walls.is_empty());
}
#[test]
fn from_array_single() {
let walls = Walls::from([EdgeDirection::FLAT_NORTH]);
assert_eq!(walls.as_bits(), 0b010000);
}
#[test]
fn from_array_multiple() {
let walls = Walls::from([EdgeDirection::FLAT_NORTH, EdgeDirection::FLAT_SOUTH]);
assert_eq!(walls.as_bits(), 0b010010);
}
#[test]
fn from_array_duplicates() {
let walls = Walls::from([
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_SOUTH,
]);
assert_eq!(walls.as_bits(), 0b010010);
}
#[test]
fn from_array_all_directions() {
let walls = Walls::from([
EdgeDirection::FLAT_NORTH,
EdgeDirection::FLAT_NORTH_EAST,
EdgeDirection::FLAT_SOUTH_EAST,
EdgeDirection::FLAT_SOUTH,
EdgeDirection::FLAT_SOUTH_WEST,
EdgeDirection::FLAT_NORTH_WEST,
]);
assert_eq!(walls.as_bits(), 0b111111);
} }
} }