diff options
Diffstat (limited to 'dungeon/tests/bsp.rs')
| -rw-r--r-- | dungeon/tests/bsp.rs | 135 |
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}"); + } + } + } +} |