code wiki / (root) / nx_procgen_signature_test.nx

nx_procgen_signature_test.nx source

↩ module page · 151 lines · 5023 B

1// nx_procgen_signature_test.nx -- KATs for the P1 composed-primitives 2// signature features. Exit 0 = all pass; first failing KAT's number is 3// the exit code (loud, names the failure). 4// 5// KAT 1 peak apex: center cell rises by exactly amp (d2=0 term). 6// KAT 2 peak reach: a cell beyond radius is untouched. 7// KAT 3 ridge symmetry: cells mirrored across the segment move equally. 8// KAT 4 valley is ridge negated: same geometry, opposite sign. 9// KAT 5 cliff is antisymmetric: left side up, right side down. 10// KAT 6 compose determinism: same (seed,preset) twice -> identical maps. 11// KAT 7 compose moves EXTREMES: graded ext after >= before on the same 12// fbm base (the P1 gate axis, proven at module level). 13// license_tier: ORIGINAL 14 15import "nx_syscalls.nx" 16import "nx_tier.nx" 17import "nx_procgen_signature.nx" 18import "nx_world_quality_grader.nx" 19import "nx_perlin.nx" 20 21const TW: nx_int = 64 22const TH: nx_int = 64 23 24func t_fill_zero(hm: *nx_int, n: nx_int) -> nx_int { 25 var i: nx_int = 0 26 while i < n { hm[i] = 0; i = i + 1 } 27 return 0 28} 29 30func t_fill_fbm(hm: *nx_int, seed: nx_int) -> nx_int { 31 let st: *PerlinState = nx_perlin_alloc(seed) 32 var y: nx_int = 0 33 while y < TH { 34 var x: nx_int = 0 35 while x < TW { 36 hm[y * TW + x] = nx_perlin_fbm_2d(st, x * 102, y * 102, 4, 614) 37 x = x + 1 38 } 39 y = y + 1 40 } 41 return 0 42} 43 44func main() -> i64 { 45 let n: nx_int = TW * TH 46 let hm: *nx_int = sys_mmap(n * 8) as *nx_int 47 let hm2: *nx_int = sys_mmap(n * 8) as *nx_int 48 49 // ---- KAT 1: peak apex == amp on a zero map ---- 50 t_fill_zero(hm, n) 51 nx_sig_peak(hm, TW, TH, 32, 32, 10, 700) 52 if hm[32 * TW + 32] != 700 { return 1 } 53 54 // ---- KAT 2: beyond radius untouched ---- 55 if hm[32 * TW + 32 + 11] != 0 { return 2 } 56 57 // ---- KAT 3: ridge symmetry across a horizontal segment ---- 58 t_fill_zero(hm, n) 59 nx_sig_ridge(hm, TW, TH, 16, 32, 48, 32, 6, 500) 60 if hm[(32 - 3) * TW + 32] != hm[(32 + 3) * TW + 32] { return 3 } 61 if hm[32 * TW + 32] <= 0 { return 3 } 62 63 // ---- KAT 4: valley == negated ridge ---- 64 t_fill_zero(hm2, n) 65 nx_sig_valley(hm2, TW, TH, 16, 32, 48, 32, 6, 0 - 500) 66 var i: nx_int = 0 67 while i < n { 68 if hm2[i] != 0 - hm[i] { return 4 } 69 i = i + 1 70 } 71 72 // ---- KAT 5: cliff antisymmetric across the segment ---- 73 t_fill_zero(hm, n) 74 nx_sig_cliff(hm, TW, TH, 32, 16, 32, 48, 8, 400) 75 let up: nx_int = hm[32 * TW + (32 + 3)] 76 let dn: nx_int = hm[32 * TW + (32 - 3)] 77 if up <= 0 { return 5 } 78 if dn >= 0 { return 5 } 79 if up != 0 - dn { return 5 } 80 81 // ---- KAT 6: compose determinism ---- 82 t_fill_fbm(hm, 42) 83 t_fill_fbm(hm2, 42) 84 nx_sig_compose(hm, TW, TH, 42, 4) 85 nx_sig_compose(hm2, TW, TH, 42, 4) 86 i = 0 87 while i < n { 88 if hm[i] != hm2[i] { return 6 } 89 i = i + 1 90 } 91 92 // ---- KAT 7: EXTREMES axis moves up on the fbm base ---- 93 let v_before: *i64 = sys_mmap(8 * 12) as *i64 94 let v_after: *i64 = sys_mmap(8 * 12) as *i64 95 var worst_gain: nx_int = 99999 96 var s: nx_int = 0 97 while s < 3 { 98 let seed: nx_int = 1000 + s * 777 99 t_fill_fbm(hm, seed) 100 nx_world_quality_grade(hm, TW, TH, 1024, 0 as *i64, 0 as *i64, 0, v_before) 101 nx_sig_compose(hm, TW, TH, seed, 4) 102 nx_world_quality_grade(hm, TW, TH, 1024, 0 as *i64, 0 as *i64, 0, v_after) 103 let gain: nx_int = v_after[3] - v_before[3] 104 if gain < worst_gain { worst_gain = gain } 105 s = s + 1 106 } 107 if worst_gain <= 0 { return 7 } 108 109 // ---- KAT 8: mesa core is FLAT on a varied base ---- 110 t_fill_fbm(hm, 42) 111 nx_sig_peak(hm, TW, TH, 32, 32, 16, 700) 112 if hm[32 * TW + 32] != hm[32 * TW + 36] { return 8 } 113 if hm[32 * TW + 32] != hm[36 * TW + 32] { return 8 } 114 115 // ---- KAT 9: terraced rim = few distinct strata, smooth rim = many ---- 116 t_fill_zero(hm, n) 117 nx_sig_peak_t(hm, TW, TH, 32, 32, 16, 800, 4) 118 var d_terr: nx_int = 0 119 var px: nx_int = 32 120 var prev: nx_int = hm[32 * TW + 32] + 1 // sentinel != first 121 while px <= 48 { 122 let v: nx_int = hm[32 * TW + px] 123 if v != prev { d_terr = d_terr + 1; prev = v } 124 px = px + 1 125 } 126 t_fill_zero(hm2, n) 127 nx_sig_peak(hm2, TW, TH, 32, 32, 16, 800) 128 var d_smooth: nx_int = 0 129 px = 32 130 prev = hm2[32 * TW + 32] + 1 131 while px <= 48 { 132 let v: nx_int = hm2[32 * TW + px] 133 if v != prev { d_smooth = d_smooth + 1; prev = v } 134 px = px + 1 135 } 136 if d_terr > 6 { return 9 } // core + <= steps rings + outside 137 if d_terr >= d_smooth { return 9 } // strictly fewer strata 138 139 // ---- KAT 10: steps=0 == smooth contract, byte-identical ---- 140 t_fill_fbm(hm, 42) 141 t_fill_fbm(hm2, 42) 142 nx_sig_peak_t(hm, TW, TH, 32, 32, 16, 700, 0) 143 nx_sig_peak(hm2, TW, TH, 32, 32, 16, 700) 144 i = 0 145 while i < n { 146 if hm[i] != hm2[i] { return 10 } 147 i = i + 1 148 } 149 150 return 0 151}