Seed expansion uses SplitMix64 so all 32 seed bytes affect the stream; copying the seed directly into xoshiro state left the first draw dependent only on bytes 8-15. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
52 lines
1.0 KiB
Go
52 lines
1.0 KiB
Go
package sim
|
|
|
|
import "testing"
|
|
|
|
func TestRNGIsDeterministic(t *testing.T) {
|
|
var seed [32]byte
|
|
copy(seed[:], "quantum-arcade-test-seed")
|
|
a, b := NewRNG(seed), NewRNG(seed)
|
|
for i := 0; i < 1000; i++ {
|
|
if x, y := a.Uint64(), b.Uint64(); x != y {
|
|
t.Fatalf("iteration %d: %d != %d", i, x, y)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDifferentSeedsDiverge(t *testing.T) {
|
|
var s1, s2 [32]byte
|
|
copy(s1[:], "seed-one")
|
|
copy(s2[:], "seed-two")
|
|
a, b := NewRNG(s1), NewRNG(s2)
|
|
same := 0
|
|
for i := 0; i < 100; i++ {
|
|
if a.Uint64() == b.Uint64() {
|
|
same++
|
|
}
|
|
}
|
|
if same > 1 {
|
|
t.Fatalf("streams collided %d times in 100 draws", same)
|
|
}
|
|
}
|
|
|
|
func TestZeroSeedDoesNotDegenerate(t *testing.T) {
|
|
var seed [32]byte // all zeros
|
|
r := NewRNG(seed)
|
|
first := r.Uint64()
|
|
if first == 0 && r.Uint64() == 0 {
|
|
t.Fatal("zero seed produced a degenerate all-zero stream")
|
|
}
|
|
}
|
|
|
|
func TestUnitInRange(t *testing.T) {
|
|
var seed [32]byte
|
|
seed[0] = 9
|
|
r := NewRNG(seed)
|
|
for i := 0; i < 10000; i++ {
|
|
u := r.Unit()
|
|
if u < 0 || u >= 1<<32 {
|
|
t.Fatalf("Unit() = %v out of [0,1)", u)
|
|
}
|
|
}
|
|
}
|