code wiki / (root) / nx_procgen_biome_test.nx

nx_procgen_biome_test.nx source

↩ module page · 129 lines · 4901 B

1// nx_procgen_biome_test.nx -- KATs for the P2 causal biome map. 2// Exit 0 = all pass; first failing KAT's number is the exit code. 3// 4// KAT 1 determinism: same (heightmap, seed) twice -> identical maps. 5// KAT 2 validity: every cell holds a sealed biome ID. 6// KAT 3 lawfulness: grader BIOME_COHERENCE >= 12000 on a generated world 7// (the R1 ladder target; lawful-by-construction, grader-proven). 8// KAT 4 moisture works: a different moisture seed changes the map, and 9// one map's MID band holds >= 2 distinct biomes. 10// KAT 5 tamper RED: an all-ICE map scores LOW coherence (< 8000) -- the 11// axis discriminates, it doesn't rubber-stamp. 12// KAT 6 flat-map refusal path: range 0 builds valid biomes, no crash. 13// KAT 7 every preset x 2 seeds: coherence >= 12000 (width, worst-case). 14// KAT 8 elevation band function mirrors the grader's quartile cuts. 15// license_tier: ORIGINAL 16 17import "nx_syscalls.nx" 18import "nx_tier.nx" 19import "nx_procgen_preset.nx" 20import "nx_procgen_biome.nx" 21import "nx_world_quality_grader.nx" 22 23const BW: nx_int = 64 24const BH: nx_int = 64 25 26func main() -> i64 { 27 let n: nx_int = BW * BH 28 let bm: *i64 = sys_mmap(n * 8) as *i64 29 let bm2: *i64 = sys_mmap(n * 8) as *i64 30 let v: *i64 = sys_mmap(8 * 12) as *i64 31 let null_ptr: *i64 = 0 as *i64 32 33 // one generated world (mountain preset = the banked-best family) 34 let land: *Landscape = nx_procgen_landscape(4242, NX_PROCGEN_PRESET_MOUNTAIN, BW, BH, 1024) 35 36 // ---- KAT 1: determinism ---- 37 nx_biome_map_build(land.heightmap, BW, BH, 4242, bm) 38 nx_biome_map_build(land.heightmap, BW, BH, 4242, bm2) 39 var i: nx_int = 0 40 while i < n { 41 if bm[i] != bm2[i] { return 1 } 42 i = i + 1 43 } 44 45 // ---- KAT 2: validity ---- 46 i = 0 47 while i < n { 48 if nx_biome_is_valid(bm[i]) != 1 { return 2 } 49 i = i + 1 50 } 51 52 // ---- KAT 3: lawful coherence on the generated world ---- 53 nx_world_quality_grade(land.heightmap, BW, BH, 1024, bm, null_ptr, 0, v) 54 if v[NX_WQG_OFF_BIOME_COHERENCE] < 12000 { return 3 } 55 56 // ---- KAT 4: moisture differentiates ---- 57 nx_biome_map_build(land.heightmap, BW, BH, 7777, bm2) 58 var n_diff: nx_int = 0 59 i = 0 60 while i < n { 61 if bm[i] != bm2[i] { n_diff = n_diff + 1 } 62 i = i + 1 63 } 64 if n_diff == 0 { return 4 } 65 // MID band of map 1 holds >= 2 distinct biomes 66 let mid_seen: *i64 = sys_mmap(NX_BIOME_ID_SPAN * 8) as *i64 67 var k: nx_int = 0 68 while k < NX_BIOME_ID_SPAN { mid_seen[k] = 0; k = k + 1 } 69 i = 0 70 while i < n { 71 let b: nx_int = bm[i] 72 if b == NX_BIOME_GRASSLAND { mid_seen[b] = 1 } 73 if b == NX_BIOME_BOREAL { mid_seen[b] = 1 } 74 if b == NX_BIOME_TEMPERATE { mid_seen[b] = 1 } 75 if b == NX_BIOME_TROPICAL { mid_seen[b] = 1 } 76 i = i + 1 77 } 78 var n_mid_kinds: nx_int = 0 79 n_mid_kinds = n_mid_kinds + mid_seen[NX_BIOME_GRASSLAND] 80 n_mid_kinds = n_mid_kinds + mid_seen[NX_BIOME_BOREAL] 81 n_mid_kinds = n_mid_kinds + mid_seen[NX_BIOME_TEMPERATE] 82 n_mid_kinds = n_mid_kinds + mid_seen[NX_BIOME_TROPICAL] 83 if n_mid_kinds < 2 { return 4 } 84 85 // ---- KAT 5: tamper RED ---- 86 i = 0 87 while i < n { bm2[i] = NX_BIOME_ICE; i = i + 1 } 88 nx_world_quality_grade(land.heightmap, BW, BH, 1024, bm2, null_ptr, 0, v) 89 if v[NX_WQG_OFF_BIOME_COHERENCE] > 8000 { return 5 } 90 91 // ---- KAT 6: flat map stays valid ---- 92 let flat: *i64 = sys_mmap(n * 8) as *i64 93 i = 0 94 while i < n { flat[i] = 100; i = i + 1 } 95 if nx_biome_map_build(flat, BW, BH, 42, bm2) != 0 { return 6 } 96 i = 0 97 while i < n { 98 if nx_biome_is_valid(bm2[i]) != 1 { return 6 } 99 i = i + 1 100 } 101 102 // ---- KAT 7: width -- every preset x 2 seeds ---- 103 var preset: nx_int = 0 104 while preset < NX_PROCGEN_N_PRESETS { 105 var s: nx_int = 0 106 while s < 2 { 107 let seed: nx_int = 1000 + s * 777 + preset * 31 108 let wl: *Landscape = nx_procgen_landscape(seed, preset, BW, BH, 1024) 109 nx_biome_map_build(wl.heightmap, BW, BH, seed, bm2) 110 nx_world_quality_grade(wl.heightmap, BW, BH, 1024, bm2, null_ptr, 0, v) 111 if v[NX_WQG_OFF_BIOME_COHERENCE] < 12000 { return 7 } 112 s = s + 1 113 } 114 preset = preset + 1 115 } 116 117 // ---- KAT 8: band function mirrors the grader's quartile law ---- 118 // range 100..200: cuts at 125 / 150 / 175 (strict-greater semantics) 119 if nx_biome_band(100, 100, 100) != 0 { return 8 } 120 if nx_biome_band(125, 100, 100) != 0 { return 8 } 121 if nx_biome_band(126, 100, 100) != 1 { return 8 } 122 if nx_biome_band(150, 100, 100) != 1 { return 8 } 123 if nx_biome_band(151, 100, 100) != 2 { return 8 } 124 if nx_biome_band(175, 100, 100) != 2 { return 8 } 125 if nx_biome_band(176, 100, 100) != 3 { return 8 } 126 if nx_biome_band(200, 100, 100) != 3 { return 8 } 127 128 return 0 129}