summaryrefslogtreecommitdiff
path: root/dungeon/tests/bsp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'dungeon/tests/bsp.rs')
-rw-r--r--dungeon/tests/bsp.rs135
1 files changed, 135 insertions, 0 deletions
diff --git a/dungeon/tests/bsp.rs b/dungeon/tests/bsp.rs
new file mode 100644
index 0000000..60198a5
--- /dev/null
+++ b/dungeon/tests/bsp.rs
@@ -0,0 +1,135 @@
+//! Integration Tests for BSP dungeon generation
+#[cfg(test)]
+mod tests {
+ use dungeon::*;
+ use pos::Pos;
+ use rand::{Rng, SeedableRng, rngs::SmallRng};
+
+ /// Generate a set of test seeds for reproducibility with a seeded RNG
+ fn generate_test_seeds(seed: u64) -> Vec<u64> {
+ let mut rng = SmallRng::seed_from_u64(seed);
+ // Generate 100 random u64 seeds
+ (0..100).map(|_| rng.random_range(0..u64::MAX)).collect()
+ }
+
+ /// Basic integration test for BSP generation
+ #[test]
+ fn test_bsp_integration() {
+ let test_seeds = generate_test_seeds(123456);
+ for seed in test_seeds {
+ let rng = SmallRng::seed_from_u64(seed);
+ let floor = bsp::generate(seed, rng);
+ // Basic integration test: ensure we get valid data
+ assert!(!floor.tiles().is_empty());
+ }
+ }
+
+ /// Test that BSP-generated floors have a valid player start
+ #[test]
+ fn test_bsp_player_start() {
+ let test_seeds = generate_test_seeds(654321);
+ for seed in test_seeds {
+ let rng = SmallRng::seed_from_u64(seed);
+ let floor = bsp::generate(seed, rng);
+ // Ensure player start is a room tile
+ let start = floor.player_start();
+ assert_eq!(floor.get(start), map::Tile::Room);
+ }
+ }
+
+ /// Test that BSP-generated floors have at least one room tile
+ #[test]
+ fn test_bsp_2_or_more_rooms() {
+ let test_seeds = generate_test_seeds(111222);
+ for seed in test_seeds {
+ let rng = SmallRng::seed_from_u64(seed);
+ let floor = bsp::generate(seed, rng);
+ // Ensure we have at least one room tile
+ let room_count = floor
+ .tiles()
+ .iter()
+ .filter(|&&tile| tile == map::Tile::Room)
+ .count();
+ assert!(
+ room_count >= 1,
+ "Expected at least one room tile, found {room_count}"
+ );
+ }
+ }
+
+ /// Test that BSP-generated floors have walls on the borders
+ #[test]
+ fn test_bsp_walls_on_borders() {
+ let test_seeds = generate_test_seeds(777888);
+ for seed in test_seeds {
+ let rng = SmallRng::seed_from_u64(seed);
+ let floor = bsp::generate(seed, rng);
+ // Go through all tiles, and ensure border tiles are walls
+ for pos in Pos::values() {
+ if pos.is_border() {
+ assert_eq!(
+ floor.get(pos),
+ map::Tile::Wall,
+ "Expected wall at border position {pos:?}"
+ );
+ }
+ }
+ }
+ }
+
+ // Test that BSP-generated floors are reproducible with the same seed
+ #[test]
+ fn test_bsp_reproducibility() {
+ let test_seeds = generate_test_seeds(111111);
+ for seed in test_seeds {
+ let rng1 = SmallRng::seed_from_u64(seed);
+ let rng2 = SmallRng::seed_from_u64(seed);
+ let floor1 = bsp::generate(seed, rng1);
+ let floor2 = bsp::generate(seed, rng2);
+ assert_eq!(
+ floor1.tiles(),
+ floor2.tiles(),
+ "Tiles differ for same seed {seed}"
+ );
+ assert_eq!(
+ floor1.player_start(),
+ floor2.player_start(),
+ "Player starts differ for same seed {seed}"
+ );
+ }
+ }
+
+ // Test that all `air` tiles (`Tile::Room` and `Tile::Hallway`) are reachable from the player start
+ #[test]
+ fn test_bsp_all_air_tiles_reachable() {
+ let test_seeds = generate_test_seeds(333444);
+ for seed in test_seeds {
+ check_air_tiles_reachable(seed);
+ }
+ }
+
+ // Helper function to check that all air tiles are reachable from player start
+ fn check_air_tiles_reachable(seed: u64) {
+ let rng = SmallRng::seed_from_u64(seed);
+ let floor = bsp::generate(seed, rng);
+
+ // BFS to find all reachable air tiles
+ let mut visited = vec![false; TILE_COUNT];
+ let mut queue = vec![floor.player_start()];
+ visited[floor.player_start().idx()] = true;
+ while let Some(pos) = queue.pop() {
+ for neighbor in pos.neighbors() {
+ let idx = neighbor.idx();
+ if !visited[idx] && floor.get(neighbor) != map::Tile::Wall {
+ visited[idx] = true;
+ queue.push(neighbor);
+ }
+ }
+ }
+ for (i, &tile) in floor.tiles().iter().enumerate() {
+ if tile == map::Tile::Room || tile == map::Tile::Hallway {
+ assert!(visited[i], "Unreachable air tile at index {i}");
+ }
+ }
+ }
+}