code wiki / (root) / nx_perlin_test.nx

nx_perlin_test.nx source

↩ module page · 77 lines · 3317 B

1// nx_perlin_test.nx -- smoke for seeded Perlin noise + classification. 2 3import "nx_syscalls.nx" 4import "nx_tier.nx" 5import "nx_perlin.nx" 6 7func main() -> nx_int { 8 // === Test 1: same seed -> identical permutation tables === 9 let s_a: *PerlinState = nx_perlin_alloc(42) 10 let s_b: *PerlinState = nx_perlin_alloc(42) 11 var i: nx_int = 0 12 while i < 16 { 13 if s_a.perm[i] != s_b.perm[i] { return 1 } 14 i = i + 1 15 } 16 17 // === Test 2: different seed -> different table (at least one cell) === 18 let s_c: *PerlinState = nx_perlin_alloc(99) 19 var any_diff: nx_int = 0 20 var j: nx_int = 0 21 while j < 256 { 22 if s_a.perm[j] != s_c.perm[j] { any_diff = 1 } 23 j = j + 1 24 } 25 if any_diff != 1 { return 2 } 26 27 // === Test 3: 2D noise at integer cell corners returns 0 === 28 // At any integer (cell corner), fractional offsets are 0, dot 29 // products with gradient are 0, so noise = 0. 30 let n_corner: nx_int = nx_perlin_2d(s_a, 0, 0) 31 if n_corner != 0 { return 10 } 32 let n_corner2: nx_int = nx_perlin_2d(s_a, 1024 * 5, 1024 * 3) 33 if n_corner2 != 0 { return 11 } 34 35 // === Test 4: 2D noise mid-cell is in valid range === 36 // At fractional (0.5, 0.5), magnitude bounded by gradient 37 // contribution -- well within [-Q, Q] = [-1024, 1024]. 38 let n_mid: nx_int = nx_perlin_2d(s_a, 512, 512) 39 if n_mid < (0 - 1024) { return 20 } 40 if n_mid > 1024 { return 21 } 41 42 // === Test 5: determinism -- two calls at same point return same value === 43 let v1: nx_int = nx_perlin_2d(s_a, 300, 700) 44 let v2: nx_int = nx_perlin_2d(s_a, 300, 700) 45 if v1 != v2 { return 30 } 46 47 // === Test 6: FBM bounded === 48 let f: nx_int = nx_perlin_fbm_2d(s_a, 512, 512, 4, 512) 49 if f < (0 - 1024) { return 40 } 50 if f > 1024 { return 41 } 51 52 // === Test 7: qualitative classification bands === 53 // Sealed-enum validity predicate behaves correctly. 54 if nx_perlin_band_is_valid(NX_PERLIN_BAND_VOID) != 1 { return 50 } 55 if nx_perlin_band_is_valid(NX_PERLIN_BAND_SATURATED) != 1 { return 51 } 56 if nx_perlin_band_is_valid(99) != 0 { return 52 } 57 if nx_perlin_band_is_valid(0 - 1) != 0 { return 53 } 58 // Specific values map to expected bands. 59 if nx_perlin_classify(0) != NX_PERLIN_BAND_VOID { return 60 } 60 if nx_perlin_classify(50) != NX_PERLIN_BAND_VOID { return 61 } 61 if nx_perlin_classify(200) != NX_PERLIN_BAND_QUIET { return 62 } 62 if nx_perlin_classify(500) != NX_PERLIN_BAND_MODERATE { return 63 } 63 if nx_perlin_classify(700) != NX_PERLIN_BAND_STRONG { return 64 } 64 if nx_perlin_classify(1000) != NX_PERLIN_BAND_SATURATED { return 65 } 65 // Signed: negative values classify by magnitude. 66 if nx_perlin_classify(0 - 200) != NX_PERLIN_BAND_QUIET { return 66 } 67 if nx_perlin_classify(0 - 1000) != NX_PERLIN_BAND_SATURATED { return 67 } 68 69 // === Test 8: 1D noise also returns 0 at integer cells === 70 let n_1d: nx_int = nx_perlin_1d(s_a, 0) 71 if n_1d != 0 { return 70 } 72 let n_1d_mid: nx_int = nx_perlin_1d(s_a, 512) 73 if n_1d_mid < (0 - 1024) { return 71 } 74 if n_1d_mid > 1024 { return 72 } 75 76 return 0 77}