tower / files / test / rock-hull.test.ts
rock-hull.test.ts
| 1 | import { describe, expect, it } from 'vitest' |
| 2 | import { ROCK_COVER, ROCK_MIN_KM, rockCover, rockShell } from '../src/views/rock-hull.js' |
| 3 | |
| 4 | describe('the rock shell (D-076)', () => { |
| 5 | const h = rockShell() |
| 6 | |
| 7 | it('never sinks into the metal skin', () => { |
| 8 | for (let i = 0; i < 4000; i++) { |
| 9 | const v = h((i * 2.399963) % (2 * Math.PI), (i * 0.1357) % 542 - 1) |
| 10 | expect(v).toBeGreaterThanOrEqual(ROCK_MIN_KM) |
| 11 | } |
| 12 | }) |
| 13 | |
| 14 | it('is one surface across the seam at theta = 0', () => { |
| 15 | for (const z of [3, 120, 333, 539]) expect(h(1e-9, z)).toBeCloseTo(h(2 * Math.PI - 1e-9, z), 5) |
| 16 | }) |
| 17 | |
| 18 | it('has relief worth the name: kilometres, not metres', () => { |
| 19 | const vals = Array.from({ length: 2000 }, (_, i) => h((i * 0.61) % (2 * Math.PI), (i * 0.27) % 540)) |
| 20 | expect(Math.max(...vals) - Math.min(...vals)).toBeGreaterThan(3) |
| 21 | }) |
| 22 | |
| 23 | it('is the same rock on every load', () => { |
| 24 | expect(rockShell()(1, 100)).toBe(h(1, 100)) |
| 25 | }) |
| 26 | }) |
| 27 | |
| 28 | describe('the rock laid over the plant (D-081)', () => { |
| 29 | const cover = rockCover() |
| 30 | const samples = Array.from({ length: 4000 }, (_, i) => cover((i * 2.399963) % (2 * Math.PI), (i * 0.1357) % 540)) |
| 31 | |
| 32 | it('covers most of the hull and leaves some bare', () => { |
| 33 | const covered = samples.filter((c) => c >= ROCK_COVER).length / samples.length |
| 34 | expect(covered).toBeGreaterThan(0.5) |
| 35 | expect(covered).toBeLessThan(0.75) |
| 36 | }) |
| 37 | |
| 38 | it('is one field across the seam at theta = 0', () => { |
| 39 | for (const z of [3, 120, 333, 539]) expect(cover(1e-9, z)).toBeCloseTo(cover(2 * Math.PI - 1e-9, z), 5) |
| 40 | }) |
| 41 | |
| 42 | it('is dug clear round a clearing', () => { |
| 43 | const dug = rockCover([{ theta: 1, z: 200, r: 14 }]) |
| 44 | for (let a = 0; a < 2 * Math.PI; a += 0.3) { |
| 45 | const d = 13 * Math.random() |
| 46 | expect(dug(1 + (d * Math.cos(a)) / 51, 200 + d * Math.sin(a))).toBe(0) |
| 47 | } |
| 48 | }) |
| 49 | }) |