fuzzyworld

tower / files / test / rock-hull.test.ts

rock-hull.test.ts

Blame: the commit that last changed each line · file · history

908833aa 2026-09-28 Pavel Safronov1import { describe, expect, it } from 'vitest'
ab6ae94f 2026-09-28 Pavel Safronov2import { ROCK_COVER, ROCK_MIN_KM, rockCover, rockShell } from '../src/views/rock-hull.js'
908833aa 2026-09-28 Pavel Safronov3
4describe('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})
ab6ae94f 2026-09-28 Pavel Safronov27
28describe('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})