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}