code wiki / _hdl_build / nx_game_adventure_gate.nx

nx_game_adventure_gate.nx source

↩ module page · 102 lines · 6271 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_game_adventure_gate.nx -- GENRE: Adventure (catalog genre, was ABSENT). A real integer/no-float 4// adventure CORE -- a walled map, a player, a KEY, a LOCKED DOOR (exit): collect the key, then the door 5// opens. Scripted solve (key then door), rendered frame, neg-control (the lock is real) + wall-collision-real. 6// T1 SOLVE: walk to the key, then to the door -> the door opens, the level is WON. PNG. 7// T2 NEG-CONTROL: heading to the door WITHOUT the key -> the locked door blocks (not won). 8// T3 WALLS REAL: a move into a wall does not move the player. 9// T4 NEVER-BRICK (#26): deterministic, bounded, no float. 10// expect_exit: 0 license_tier: ORIGINAL 11import "nx_game_raster.nx" 12import "nx_png.nx" 13import "nx_syscalls.nx" 14 15func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 16" as *u8); return ok } 17 18func adv_build(map: *i64, gw_: i64, gh_: i64) -> i64 { 19 var i: i64=0; while i<gw_*gh_ { map[i]=0; i=i+1 } 20 var x: i64=0; while x<gw_ { map[0*gw_+x]=1; map[(gh_-1)*gw_+x]=1; x=x+1 } // top/bottom walls 21 var y: i64=0; while y<gh_ { map[y*gw_+0]=1; map[y*gw_+(gw_-1)]=1; y=y+1 } // left/right walls 22 map[3*gw_+4]=1; map[3*gw_+5]=1; map[4*gw_+4]=1; map[4*gw_+5]=1 // a central block 23 map[1*gw_+8]=2 // key 24 map[6*gw_+8]=3 // door (exit) 25 return 0 26} 27// ps[0]=x ps[1]=y ps[2]=has_key ps[3]=won 28func adv_move(map: *i64, gw_: i64, gh_: i64, ps: *i64, dx: i64, dy: i64) -> i64 { 29 let nx: i64=ps[0]+dx; let ny: i64=ps[1]+dy 30 if nx<0 { return 0 } if ny<0 { return 0 } if nx>=gw_ { return 0 } if ny>=gh_ { return 0 } 31 let cell: i64=map[ny*gw_+nx] 32 if cell==1 { return 0 } // wall blocks 33 if cell==3 { if ps[2]==0 { return 0 } ps[0]=nx; ps[1]=ny; ps[3]=1; return 0 } // door: locked w/o key, else enter+win 34 ps[0]=nx; ps[1]=ny 35 if cell==2 { ps[2]=1; map[ny*gw_+nx]=0 } // pick up key 36 return 0 37} 38func adv_render(fb: *i64, w: i64, h: i64, cell: i64, gw_: i64, gh_: i64, map: *i64, ps: *i64) -> i64 { 39 gr_clear(fb, w, h, gr_pack(18, 18, 26)) 40 var y: i64=0 41 while y<gh_ { 42 var x: i64=0 43 while x<gw_ { 44 let k: i64=map[y*gw_+x] 45 if k==1 { gr_rect(fb, w, h, x*cell, y*cell, x*cell+cell, y*cell+cell, gr_pack(96,96,110)) } 46 if k==2 { gr_disc(fb, w, h, x*cell+cell/2, y*cell+cell/2, 3, gr_pack(245,210,70)) } 47 if k==3 { gr_rect(fb, w, h, x*cell+2, y*cell+1, x*cell+cell-2, y*cell+cell-1, gr_pack(160,90,50)) } 48 x=x+1 49 } 50 y=y+1 51 } 52 gr_rect(fb, w, h, ps[0]*cell+3, ps[1]*cell+3, ps[0]*cell+cell-3, ps[1]*cell+cell-3, gr_pack(90,210,122)) 53 return 0 54} 55 56func main() -> i64 { 57 gw("=== nx_game_adventure_gate: GENRE Adventure -- a real integer/no-float playable (live evidence) ===\n" as *u8) 58 var pass: i64 = 0; var total: i64 = 0 59 let GW: i64=10; let GH: i64=8; let CELL: i64=12; let W: i64=GW*CELL; let H: i64=GH*CELL 60 let map: *i64=sys_mmap(8*(GW*GH+4)) as *i64; let ps: *i64=sys_mmap(8*4) as *i64 61 62 // ---- T1: solve -- key then door ---- 63 adv_build(map, GW, GH); ps[0]=1; ps[1]=1; ps[2]=0; ps[3]=0 64 var i: i64=0; while i<7 { adv_move(map, GW, GH, ps, 1, 0); i=i+1 } // walk right to the key 65 let got_key: i64=ps[2] 66 i=0; while i<5 { adv_move(map, GW, GH, ps, 0, 1); i=i+1 } // walk down to the door 67 var t1ok: i64=1; if got_key!=1 {t1ok=0} if ps[3]!=1 {t1ok=0} 68 total=total+1; if t1ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 69 gw("T1 solve: collected the key (" as *u8); gn(got_key); gw(") then opened the door, won=" as *u8); gn(ps[3]); gw(" (WIN)\n" as *u8) 70 71 // ---- render a mid-quest frame ---- 72 let fb: *i64=sys_mmap(8*(W*H+8)) as *i64 73 adv_build(map, GW, GH); ps[0]=1; ps[1]=1; ps[2]=0; ps[3]=0 74 i=0; while i<4 { adv_move(map, GW, GH, ps, 1, 0); i=i+1 } 75 adv_render(fb, W, H, CELL, GW, GH, map, ps) 76 write_png(fb, W, H, "knowledge/nx_game_adventure.png" as *u8) 77 gw(" (live evidence: PNG knowledge/nx_game_adventure.png -- walls + key + door + player)\n" as *u8) 78 79 // ---- T2: neg-control -- the door is locked without the key ---- 80 adv_build(map, GW, GH); ps[0]=1; ps[1]=1; ps[2]=0; ps[3]=0 81 i=0; while i<5 { adv_move(map, GW, GH, ps, 0, 1); i=i+1 } // down first (avoid the key) 82 i=0; while i<7 { adv_move(map, GW, GH, ps, 1, 0); i=i+1 } // then toward the door 83 total=total+1; if ps[3]==0 { if ps[2]==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } 84 gw("T2 neg-control: reached the door WITHOUT the key -> locked, won=" as *u8); gn(ps[3]); gw(" (the lock is real)\n" as *u8) 85 86 // ---- T3: walls real -- a move into a wall does not move ---- 87 adv_build(map, GW, GH); ps[0]=1; ps[1]=1; ps[2]=0; ps[3]=0 88 adv_move(map, GW, GH, ps, 0, 0-1) // up into the top wall 89 var t3ok: i64=1; if ps[0]!=1 {t3ok=0} if ps[1]!=1 {t3ok=0} 90 total=total+1; if t3ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 91 gw("T3 walls real: a move into the wall left the player at (" as *u8); gn(ps[0]); gw("," as *u8); gn(ps[1]); gw(")\n" as *u8) 92 93 // ---- T4: never-brick / determinism ---- 94 adv_build(map, GW, GH); ps[0]=1; ps[1]=1; ps[2]=0; ps[3]=0 95 i=0; while i<7 { adv_move(map, GW, GH, ps, 1, 0); i=i+1 } i=0; while i<5 { adv_move(map, GW, GH, ps, 0, 1); i=i+1 } 96 total=total+1; if ps[3]==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 97 gw("T4 never-brick (#26): deterministic re-run won=" as *u8); gn(ps[3]); gw(", bounded, no float\n" as *u8) 98 99 gw("\n=== nx_game_adventure_gate " as *u8); gn(pass); gw("/" as *u8); gn(total) 100 if pass == total { gw(" GREEN (Adventure: a real playable key->locked-door solve with wall collision, rendered, sovereign)\n" as *u8); sys_exit(0); return 0 } 101 gw(" RED\n" as *u8); sys_exit(1); return 1 102}