code wiki / _hdl_build / nx_game_actor_gate.nx

nx_game_actor_gate.nx source

↩ module page · 223 lines · 10246 B

1// nx_game_actor_gate.nx -- proves the character<->environment interaction floor (ws=game-interact). 2// Teeth follow the lane law: every equality carries a NON-VACUITY guard; the flagship tooth (T2/T5 3// occupancy) is designed so the mutation "ac_step skips the occupancy check" turns it RED while the 4// anti-vacuity tooth stays GREEN. license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_game_actor.nx" 7import "nx_pathfind.nx" 8import "nx_gamesave.nx" 9 10func p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 11func pn(v: i64) -> i64 { 12 let t: *u8 = sys_mmap(32) as *u8 13 var m: i64 = v 14 var w: i64 = 0 15 if m < 0 { t[w] = 45 as u8; w = w + 1; m = 0 - m } 16 if m == 0 { t[w] = 48 as u8; sys_write(1, t, w + 1); return 0 } 17 let d: *u8 = sys_mmap(32) as *u8 18 var k: i64 = 0 19 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 20 var j: i64 = 0 21 while j < k { t[w] = d[k - 1 - j]; w = w + 1; j = j + 1 } 22 sys_write(1, t, w) 23 return 0 24} 25func nl() -> i64 { p("\n" as *u8); return 0 } 26 27const GW2: i64 = 16 28const GH2: i64 = 12 29 30// deterministic scripted walk: fold a seed into a move dir each step 31func dir_dx(d: i64) -> i64 { if d == 0 { return 1 } if d == 1 { return 0-1 } return 0 } 32func dir_dy(d: i64) -> i64 { if d == 2 { return 1 } if d == 3 { return 0-1 } return 0 } 33 34func main() -> i64 { 35 p("=== nx_game_actor_gate (character<->environment interaction floor) ===\n" as *u8) 36 var pass: i64 = 0 37 let checks: i64 = 7 38 39 let wd: *i64 = sys_mmap(wd_bytes(GW2, GH2)) as *i64 40 wd_init(wd, GW2, GH2) 41 // border walls + one interior pillar 42 var i: i64 = 0 43 while i < GW2 { wd_set_wall(wd, i, 0, 1); wd_set_wall(wd, i, GH2 - 1, 1); i = i + 1 } 44 var j: i64 = 0 45 while j < GH2 { wd_set_wall(wd, 0, j, 1); wd_set_wall(wd, GW2 - 1, j, 1); j = j + 1 } 46 wd_set_wall(wd, 8, 5, 1) 47 48 let ar: *i64 = sys_mmap(en_bytes(64, AC_NC)) as *i64 49 en_init(ar, 64, AC_NC) 50 let out: *i64 = sys_mmap(64) as *i64 51 52 // T1 wall + oob collision, with the anti-vacuity half (an open move MUST succeed) 53 let hp2: i64 = ac_spawn(wd, ar, 7, 5, 0, 30, 0, 1, 12345) 54 var t1: i64 = 0 55 if ac_step(wd, ar, hp2, 1, 0, out) == AC_WALL { // into the pillar at (8,5) 56 if en_get(ar, hp2, A_X) == 7 { // position unchanged 57 if ac_step(wd, ar, hp2, 0, 1, out) == AC_MOVED { // open move works (non-vacuous) 58 if en_get(ar, hp2, A_Y) == 6 { t1 = 1 } 59 } 60 } 61 } 62 if t1 == 1 { pass = pass + 1; p("T1 GREEN wall stops, open passes: pillar blocked pos held, open cell entered\n" as *u8) } 63 if t1 == 0 { p("T1 RED wall/open\n" as *u8) } 64 65 // T2 entity collision = BUMP with the right handle, nobody moves (the interaction primitive) 66 let he: i64 = ac_spawn(wd, ar, 7, 7, 1, 20, 1, 1, 777) 67 var t2: i64 = 0 68 let rc2: i64 = ac_step(wd, ar, hp2, 0, 1, out) // player at (7,6) -> into enemy (7,7) 69 if rc2 == AC_BUMP { 70 if out[0] == he { 71 if en_get(ar, hp2, A_Y) == 6 { 72 if en_get(ar, he, A_Y) == 7 { t2 = 1 } 73 } 74 } 75 } 76 if t2 == 1 { pass = pass + 1; p("T2 GREEN bump-to-interact: moving into an occupied cell returns the occupant, positions held\n" as *u8) } 77 if t2 == 0 { p("T2 RED bump\n" as *u8) } 78 79 // T3 oob refused (walls are the border here, so drive to a corner via a fresh open-map world) 80 let wd3: *i64 = sys_mmap(wd_bytes(4, 4)) as *i64 81 wd_init(wd3, 4, 4) 82 let ar3: *i64 = sys_mmap(en_bytes(8, AC_NC)) as *i64 83 en_init(ar3, 8, AC_NC) 84 let h3: i64 = ac_spawn(wd3, ar3, 0, 0, 0, 10, 0, 1, 1) 85 var t3: i64 = 0 86 if ac_step(wd3, ar3, h3, 0-1, 0, out) == AC_OOB { 87 if ac_step(wd3, ar3, h3, 1, 0, out) == AC_MOVED { t3 = 1 } 88 } 89 if t3 == 1 { pass = pass + 1; p("T3 GREEN oob refused at the true edge, in-bounds move fine\n" as *u8) } 90 if t3 == 0 { p("T3 RED oob\n" as *u8) } 91 92 // T4 determinism: 400-step scripted walk replayed twice -> identical ck; non-vacuity: ck must MOVE 93 var rep: i64 = 0 94 var ck1: i64 = 0 95 var ck2: i64 = 0 96 var moved_total: i64 = 0 97 while rep < 2 { 98 let wdr: *i64 = sys_mmap(wd_bytes(GW2, GH2)) as *i64 99 wd_init(wdr, GW2, GH2) 100 var bi: i64 = 0 101 while bi < GW2 { wd_set_wall(wdr, bi, 0, 1); wd_set_wall(wdr, bi, GH2 - 1, 1); bi = bi + 1 } 102 var bj: i64 = 0 103 while bj < GH2 { wd_set_wall(wdr, 0, bj, 1); wd_set_wall(wdr, GW2 - 1, bj, 1); bj = bj + 1 } 104 wd_set_wall(wdr, 8, 5, 1) 105 let arr: *i64 = sys_mmap(en_bytes(64, AC_NC)) as *i64 106 en_init(arr, 64, AC_NC) 107 let ha: i64 = ac_spawn(wdr, arr, 3, 3, 0, 30, 0, 1, 5) 108 let hb: i64 = ac_spawn(wdr, arr, 12, 8, 1, 20, 1, 1, 9) 109 let ck0: i64 = ac_ck(wdr, arr) 110 var s: i64 = 424242 111 var st: i64 = 0 112 while st < 400 { 113 s = s * 1103515245 + 12345 114 var d: i64 = (s >> 16) & 3 115 if d < 0 { d = 0 - d } 116 let rc: i64 = ac_step(wdr, arr, ha, dir_dx(d), dir_dy(d), out) 117 if rc == AC_MOVED { moved_total = moved_total + 1 } 118 s = s * 1103515245 + 12345 119 var d2: i64 = (s >> 16) & 3 120 if d2 < 0 { d2 = 0 - d2 } 121 ac_step(wdr, arr, hb, dir_dx(d2), dir_dy(d2), out) 122 st = st + 1 123 } 124 var ckf: i64 = ac_ck(wdr, arr) 125 if ckf == ck0 { ckf = 0 } // frozen world would be vacuous 126 if rep == 0 { ck1 = ckf } 127 if rep == 1 { ck2 = ckf } 128 rep = rep + 1 129 } 130 var t4: i64 = 0 131 if ck1 == ck2 { if ck1 != 0 { if moved_total > 100 { t4 = 1 } } } 132 if t4 == 1 { pass = pass + 1; p("T4 GREEN deterministic: 2x400-step replay ck identical ck=" as *u8); pn(ck1); p(" moved=" as *u8); pn(moved_total); nl() } 133 if t4 == 0 { p("T4 RED determinism ck1=" as *u8); pn(ck1); p(" ck2=" as *u8); pn(ck2); nl() } 134 135 // T5 occupancy invariant under churn: spawn/walk/remove cycles, then the invariant walker 136 var t5: i64 = 0 137 var churn_moves: i64 = 0 138 var s5: i64 = 31337 139 var c: i64 = 0 140 while c < 30 { 141 s5 = s5 * 1103515245 + 12345 142 var px: i64 = ((s5 >> 16) & 32767) % (GW2 - 2) + 1 143 s5 = s5 * 1103515245 + 12345 144 var py: i64 = ((s5 >> 16) & 32767) % (GH2 - 2) + 1 145 let hn: i64 = ac_spawn(wd, ar, px, py, 1, 10, 2, 1, s5) 146 if hn > 0 { 147 var mv: i64 = 0 148 while mv < 12 { 149 s5 = s5 * 1103515245 + 12345 150 var dd: i64 = (s5 >> 16) & 3 151 if dd < 0 { dd = 0 - dd } 152 if ac_step(wd, ar, hn, dir_dx(dd), dir_dy(dd), out) == AC_MOVED { churn_moves = churn_moves + 1 } 153 mv = mv + 1 154 } 155 if (c % 3) == 0 { ac_remove(wd, ar, hn) } 156 } 157 c = c + 1 158 } 159 if ac_occ_check(wd, ar) == 0 { if churn_moves > 20 { if en_count(ar) > 2 { t5 = 1 } } } 160 if t5 == 1 { pass = pass + 1; p("T5 GREEN occupancy invariant held through churn: moves=" as *u8); pn(churn_moves); p(" actors=" as *u8); pn(en_count(ar)); nl() } 161 if t5 == 0 { p("T5 RED occupancy violations=" as *u8); pn(ac_occ_check(wd, ar)); nl() } 162 163 // T6 the shared grid REALLY drives pf_astar: path around the pillar exists and every path cell is open 164 var t6: i64 = 0 165 let n6: i64 = GW2 * GH2 166 let g6: *i64 = sys_mmap(n6 * 8) as *i64 167 let f6: *i64 = sys_mmap(n6 * 8) as *i64 168 let cm6: *i64 = sys_mmap(n6 * 8) as *i64 169 let of6: *i64 = sys_mmap(n6 * 8) as *i64 170 let cl6: *i64 = sys_mmap(n6 * 8) as *i64 171 let pa6: *i64 = sys_mmap(n6 * 8) as *i64 172 let plen: i64 = pf_astar(wd_grid(wd), GW2, GH2, 1, 5, 14, 5, g6, f6, cm6, of6, cl6, pa6) 173 if plen > 0 { 174 var okcells: i64 = 1 175 var pi: i64 = 0 176 while pi < plen { 177 let cell: i64 = pa6[pi] 178 if wd_wall(wd, cell % GW2, cell / GW2) != 0 { okcells = 0 } 179 pi = pi + 1 180 } 181 if okcells == 1 { if plen >= 13 { t6 = 1 } } // straight line is 13; pillar may force more 182 } 183 if t6 == 1 { pass = pass + 1; p("T6 GREEN pf_astar consumes the live world grid: path len=" as *u8); pn(plen); p(" all cells open\n" as *u8) } 184 if t6 == 0 { p("T6 RED astar-on-world plen=" as *u8); pn(plen); nl() } 185 186 // T7 gamesave transparency (GX-9): save world+actors, load into ZEROED arenas, ck equal + non-vacuous 187 var t7: i64 = 0 188 let wn: i64 = wd_words(GW2, GH2) 189 let an: i64 = en_words(64, AC_NC) 190 let S: *i64 = sys_mmap((wn + an) * 8) as *i64 191 var si: i64 = 0 192 while si < wn { S[si] = wd[si]; si = si + 1 } 193 var sj: i64 = 0 194 while sj < an { S[wn + sj] = ar[sj]; sj = sj + 1 } 195 let ckpre: i64 = ac_ck(wd, ar) 196 let rcs: i64 = gs_save("knowledge/nx_actor_t7.sav" as *u8, 9101, S, wn + an, 1000) 197 let L: *i64 = sys_mmap((wn + an) * 8) as *i64 198 let meta: *i64 = sys_mmap(64) as *i64 199 let rcl: i64 = gs_load("knowledge/nx_actor_t7.sav" as *u8, L, wn + an, meta) 200 if rcs > 0 { if rcl >= 0 { 201 let wd7: *i64 = sys_mmap(wn * 8) as *i64 202 let ar7: *i64 = sys_mmap(an * 8) as *i64 203 var li: i64 = 0 204 while li < wn { wd7[li] = L[li]; li = li + 1 } 205 var lj: i64 = 0 206 while lj < an { ar7[lj] = L[wn + lj]; lj = lj + 1 } 207 let ckpost: i64 = ac_ck(wd7, ar7) 208 if ckpost == ckpre { if en_count(ar7) > 2 { if churn_moves > 0 { 209 // resumed world must CONTINUE identically: same scripted step on both 210 ac_step(wd, ar, hp2, 0, 0-1, out) 211 let hp7: i64 = hp2 // same handle value is valid in the copy 212 ac_step(wd7, ar7, hp7, 0, 0-1, out) 213 if ac_ck(wd, ar) == ac_ck(wd7, ar7) { t7 = 1 } 214 } } } 215 } } 216 if t7 == 1 { pass = pass + 1; p("T7 GREEN save/load transparent: ck equal pre/post + resumed step identical (non-vacuous world)\n" as *u8) } 217 if t7 == 0 { p("T7 RED save/load rcs=" as *u8); pn(rcs); p(" rcl=" as *u8); pn(rcl); nl() } 218 219 p("nx_game_actor_gate: " as *u8); pn(pass); p("/" as *u8); pn(checks); nl() 220 if pass == checks { p("VERDICT GREEN\n" as *u8); return 0 } 221 p("VERDICT RED\n" as *u8) 222 return 1 223}