explodorama / files / test / levelgen.test.ts
levelgen.test.ts
| 1 | import { describe, expect, it } from 'vitest' |
| 2 | import { boardSize, generateLevel, START } from '../src/sim/levelgen' |
| 3 | import type { Vec } from '../src/sim/types' |
| 4 | |
| 5 | describe('levelgen', () => { |
| 6 | it('is the same for the same seed and level, and differs between levels', () => { |
| 7 | expect(generateLevel(42, 3)).toEqual(generateLevel(42, 3)) |
| 8 | expect(generateLevel(42, 3).cells).not.toEqual(generateLevel(42, 4).cells) |
| 9 | }) |
| 10 | |
| 11 | for (let seed = 1; seed <= 200; seed++) { |
| 12 | it(`seed ${seed}: walls, pillars, a clear start, everything reachable`, () => { |
| 13 | const level = 1 + (seed % 50) |
| 14 | const { width, height, cells, start } = generateLevel(seed, level) |
| 15 | expect({ width, height }).toEqual(boardSize(level)) |
| 16 | const at = (p: Vec) => cells[p.y * width + p.x] |
| 17 | for (let x = 0; x < width; x++) expect([at({ x, y: 0 }), at({ x, y: height - 1 })]).toEqual(['wall', 'wall']) |
| 18 | for (let y = 0; y < height; y++) expect([at({ x: 0, y }), at({ x: width - 1, y })]).toEqual(['wall', 'wall']) |
| 19 | expect(start).toEqual(START) |
| 20 | for (const p of [start, { x: 2, y: 1 }, { x: 1, y: 2 }]) expect(at(p)).toBe('floor') |
| 21 | |
| 22 | // With soft blocks gone, every non-wall tile is reachable from the start. |
| 23 | const seen = new Set([`${start.x},${start.y}`]) |
| 24 | const queue = [start] |
| 25 | while (queue.length) { |
| 26 | const p = queue.pop()! |
| 27 | for (const q of [{ x: p.x + 1, y: p.y }, { x: p.x - 1, y: p.y }, { x: p.x, y: p.y + 1 }, { x: p.x, y: p.y - 1 }]) { |
| 28 | if (at(q) !== 'wall' && !seen.has(`${q.x},${q.y}`)) { |
| 29 | seen.add(`${q.x},${q.y}`) |
| 30 | queue.push(q) |
| 31 | } |
| 32 | } |
| 33 | } |
| 34 | expect(seen.size).toBe(cells.filter((c) => c !== 'wall').length) |
| 35 | }) |
| 36 | } |
| 37 | }) |