import { expect } from "@esm-bundle/chai"; import { VoxelGrid } from "../../src/grid/VoxelGrid.js"; import { RuinGenerator } from "../../src/generation/RuinGenerator.js"; describe("System: Procedural Generation (Scatter)", () => { let grid; beforeEach(() => { grid = new VoxelGrid(20, 5, 20); }); it("CoA 1: scatterCover should place objects on valid floors", () => { const gen = new RuinGenerator(grid, 12345); // 1. Generate empty rooms first // Note: RuinGenerator runs applyTextures() automatically at the end of generate(), // so floor IDs will be 200+, not 1. gen.generate(1, 10, 10); // 2. Count empty floor tiles (Air above Solid) let floorCount = 0; for (let x = 0; x < 20; x++) { for (let z = 0; z < 20; z++) { // Check for Air at y=1 const isAirAbove = grid.getCell(x, 1, z) === 0; // Check for ANY solid block at y=0 (Floor ID is likely 200+) const isSolidBelow = grid.getCell(x, 0, z) !== 0; if (isAirAbove && isSolidBelow) { floorCount++; } } } // 3. Scatter Cover (ID 10) at 50% density gen.scatterCover(10, 0.5); // 4. Count Cover let coverCount = 0; for (let x = 0; x < 20; x++) { for (let z = 0; z < 20; z++) { if (grid.getCell(x, 1, z) === 10) { coverCount++; } } } // Expect roughly 50% of the floor to be covered // Allow a wider margin (30-70%) for small sample sizes where RNG variance is higher const expectedMin = Math.floor(floorCount * 0.3); const expectedMax = Math.ceil(floorCount * 0.7); expect(floorCount).to.be.greaterThan(0, "No floors were generated!"); expect(coverCount).to.be.within( expectedMin, expectedMax, `Cover count ${coverCount} not within 30-70% of floor count ${floorCount}` ); }); it("CoA 2: scatterCover should NOT place objects in mid-air", () => { const gen = new RuinGenerator(grid, 12345); gen.generate(); gen.scatterCover(10, 1.0); // 100% density to force errors if logic is wrong // Scan for floating cover for (let x = 0; x < 20; x++) { for (let z = 0; z < 20; z++) { for (let y = 1; y < 4; y++) { if (grid.getCell(x, y, z) === 10) { const below = grid.getCell(x, y - 1, z); // Cover must have something solid below it expect(below).to.not.equal( 0, `Found floating cover at ${x},${y},${z}` ); } } } } }); });