code wiki / _hdl_build / nx_game_rts_gate.nx
nx_game_rts_gate.nx source
↩ module page · 82 lines · 5129 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_game_rts_gate.nx -- GENRE: Real-Time strategy (catalog genre, was ABSENT). A real integer/no-float RTS
4// CORE -- workers gather resources, resources build soldiers, soldiers attack the enemy base. Scripted match
5// (gather->build->destroy the base), rendered frame, neg-control (an army is needed) + economy-real.
6// T1 MATCH: gather + build an army -> the enemy base is destroyed (hp<=0 = WIN). PNG.
7// T2 NEG-CONTROL: gathering but building NO soldiers leaves the enemy base intact.
8// T3 ECONOMY REAL: building a soldier costs resources (resources go down on build).
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
18// st[0]=resources st[1]=workers st[2]=soldiers st[3]=enemy_base_hp
19func rts_reset(st: *i64) -> i64 { st[0]=0; st[1]=3; st[2]=0; st[3]=40; return 0 }
20func rts_tick(st: *i64, build: i64, scost: i64, maxs: i64) -> i64 {
21 st[0]=st[0]+st[1]*2 // workers gather
22 if build==1 { if st[0]>=scost { if st[2]<maxs { st[0]=st[0]-scost; st[2]=st[2]+1 } } } // train a soldier
23 st[3]=st[3]-st[2] // soldiers attack the enemy base
24 if st[3]<0 { st[3]=0 }
25 return 0
26}
27func rts_render(fb: *i64, w: i64, h: i64, st: *i64) -> i64 {
28 gr_clear(fb, w, h, gr_pack(26, 32, 24))
29 gr_rect(fb, w, h, 6, h-26, 26, h-6, gr_pack(70,120,210)) // your base (blue)
30 gr_rect(fb, w, h, w-26, 6, w-6, 26, gr_pack(210,70,60)) // enemy base (red)
31 var i: i64=0
32 while i < st[2] { if i < 12 { gr_disc(fb, w, h, 34+i*8, h-14, 3, gr_pack(110,220,140)) } i=i+1 } // soldiers
33 gr_rect(fb, w, h, 6, 4, 6+st[0], 8, gr_pack(240,210,90)) // resource bar
34 gr_rect(fb, w, h, w-46, 30, w-46+st[3], 33, gr_pack(220,90,80)) // enemy base hp bar
35 return 0
36}
37
38func main() -> i64 {
39 gw("=== nx_game_rts_gate: GENRE Real-Time strategy -- a real integer/no-float playable (live evidence) ===\n" as *u8)
40 var pass: i64 = 0; var total: i64 = 0
41 let W: i64=140; let H: i64=96; let SCOST: i64=6; let MAXS: i64=10
42 let st: *i64=sys_mmap(8*4) as *i64
43
44 // ---- T1: gather, build an army, destroy the enemy base ----
45 rts_reset(st)
46 var tick: i64=0
47 while tick < 120 { if st[3]<=0 { tick=120 } else { rts_tick(st, 1, SCOST, MAXS); tick=tick+1 } }
48 let ehp1: i64=st[3]; let army: i64=st[2]
49 total=total+1; if ehp1<=0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
50 gw("T1 match: built an army of " as *u8); gn(army); gw(" soldiers, enemy base hp=" as *u8); gn(ehp1); gw(" (DESTROYED = WIN)\n" as *u8)
51
52 // ---- render a mid-match frame ----
53 let fb: *i64=sys_mmap(8*(W*H+8)) as *i64
54 rts_reset(st)
55 var k: i64=0; while k < 18 { rts_tick(st, 1, SCOST, MAXS); k=k+1 }
56 rts_render(fb, W, H, st)
57 write_png(fb, W, H, "knowledge/nx_game_rts.png" as *u8)
58 gw(" (live evidence: PNG knowledge/nx_game_rts.png -- your base + soldiers + resources + enemy base)\n" as *u8)
59
60 // ---- T2: neg-control -- gathering but no army leaves the base intact ----
61 rts_reset(st)
62 tick=0; while tick < 120 { rts_tick(st, 0, SCOST, MAXS); tick=tick+1 }
63 let ehp2: i64=st[3]
64 total=total+1; if ehp2==40 { if st[2]==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
65 gw("T2 neg-control: no soldiers built (" as *u8); gn(st[2]); gw(") -> enemy base intact hp=" as *u8); gn(ehp2); gw(" (an army is real)\n" as *u8)
66
67 // ---- T3: economy real -- a soldier costs resources ----
68 rts_reset(st); st[0]=20; st[1]=0 // 20 resources, no gather this tick
69 let before: i64=st[0]
70 rts_tick(st, 1, SCOST, MAXS) // build one soldier
71 total=total+1; if st[0]==before-SCOST { if st[2]==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
72 gw("T3 economy real: building a soldier spent " as *u8); gn(SCOST); gw(" resources (" as *u8); gn(before); gw("->" as *u8); gn(st[0]); gw(")\n" as *u8)
73
74 // ---- T4: never-brick / determinism ----
75 rts_reset(st); tick=0; while tick < 120 { if st[3]<=0 { tick=120 } else { rts_tick(st, 1, SCOST, MAXS); tick=tick+1 } }
76 total=total+1; if st[3]==ehp1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
77 gw("T4 never-brick (#26): deterministic re-run (enemy hp=" as *u8); gn(st[3]); gw("==" as *u8); gn(ehp1); gw("), bounded, no float\n" as *u8)
78
79 gw("\n=== nx_game_rts_gate " as *u8); gn(pass); gw("/" as *u8); gn(total)
80 if pass == total { gw(" GREEN (Real-Time strategy: a real playable gather->build->attack economy, rendered, sovereign)\n" as *u8); sys_exit(0); return 0 }
81 gw(" RED\n" as *u8); sys_exit(1); return 1
82}