A mechanic package depends on ludic.base and nothing else: ports (records of function values for now) for questions, queues for facts, verbs for changes, phases for order and its own versioned save section. The runner inits, resets, saves and loads systems in the order added and ticks them phase by phase; a missing save section is a reset. Tests for each piece and a worked route between two toy mechanics live under tests/. The old ludic.core (engine ECS components) is used by examples/library and stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 lines
1.9 KiB
Text
71 lines
1.9 KiB
Text
# rng_test.ludic - an Rng is a stream of its own: the same seed rolls the same, two streams do
|
|
# not disturb each other or the global generator, and the ranges hold
|
|
import "ludic.base"
|
|
program RngTest {
|
|
numbers float
|
|
|
|
# a stream seeded with seed that has already rolled n times
|
|
function rng_after(seed: int, n: int) -> Rng {
|
|
let r = rng_new(seed)
|
|
for i in 0 .. n { rng_next(r) }
|
|
return r
|
|
}
|
|
|
|
test "the same seed rolls the same sequence" {
|
|
let a = rng_new(42)
|
|
let b = rng_new(42)
|
|
for i in 0 .. 100 { expect_eq(rng_next(a), rng_next(b)) }
|
|
}
|
|
|
|
test "different seeds differ" {
|
|
let a = rng_new(1)
|
|
let b = rng_new(2)
|
|
var same = 0
|
|
for i in 0 .. 50 { if rng_next(a) == rng_next(b) { same += 1 } }
|
|
expect(same < 5)
|
|
}
|
|
|
|
test "drawing from one stream does not move another" {
|
|
let a = rng_new(7)
|
|
let b = rng_new(7)
|
|
let noise = rng_new(99)
|
|
for i in 0 .. 20 {
|
|
rng_next(noise)
|
|
expect_eq(rng_next(a), rng_next(b))
|
|
}
|
|
}
|
|
|
|
test "reseeding starts the sequence again" {
|
|
let r = rng_new(5)
|
|
let first = rng_next(r)
|
|
rng_next(r)
|
|
rng_seed(r, 5)
|
|
expect_eq(rng_next(r), first)
|
|
}
|
|
|
|
test "the ranges hold and reach both ends" {
|
|
let r = rng_new(123)
|
|
var lo_seen = false
|
|
var hi_seen = false
|
|
for i in 0 .. 2000 {
|
|
let n = rng_between(r, 3, 6)
|
|
expect(n >= 3 and n <= 6)
|
|
if n == 3 { lo_seen = true }
|
|
if n == 6 { hi_seen = true }
|
|
let f = rng_float(r)
|
|
expect(f >= 0.0 and f < 1.0)
|
|
let s = rng_span(r, -2.0, 2.0)
|
|
expect(s >= -2.0 and s < 2.0)
|
|
expect(rng_next(r) >= 0)
|
|
}
|
|
expect(lo_seen and hi_seen)
|
|
expect_eq(rng_between(r, 4, 4), 4)
|
|
}
|
|
|
|
test "a known seed gives a known roll on every machine" {
|
|
let r = rng_new(1)
|
|
let x = rng_next(r)
|
|
expect_eq(x, 1822124854)
|
|
expect_eq(rng_between(r, 1, 6), rng_between(rng_after(1, 1), 1, 6))
|
|
}
|
|
}
|