code wiki / _hdl_build / nx_game_city_gate.nx
nx_game_city_gate.nx source
↩ module page · 95 lines · 5465 B
1import "nx_gate_gn.nx"
2import "nx_gate_base.nx"
3// nx_game_city_gate.nx -- GENRE: City-Building (catalog genre, was ABSENT). A real integer/no-float city sim
4// CORE -- place buildings (houses/farms/markets) on a grid; each tick farms make food, food grows population
5// up to the housing cap, markets make gold. Scripted build-up (reach the population target), rendered frame,
6// neg-control (buildings matter) + housing-cap-real.
7// T1 BUILD-UP: a planned layout grows the population to the target. PNG.
8// T2 NEG-CONTROL: an empty city (no buildings) grows NO population.
9// T3 CAP REAL: population never exceeds the housing capacity (houses*4).
10// T4 NEVER-BRICK (#26): deterministic, bounded, no float.
11// expect_exit: 0 license_tier: ORIGINAL
12import "nx_game_raster.nx"
13import "nx_png.nx"
14import "nx_syscalls.nx"
15
16func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw("
17" as *u8); return ok }
18
19func c_count(board: *i64, n: i64, kind: i64) -> i64 { var c: i64=0; var i: i64=0; while i<n { if board[i]==kind { c=c+1 } i=i+1 } return c }
20// res[0]=pop res[1]=food res[2]=gold
21func c_tick(board: *i64, n: i64, res: *i64) -> i64 {
22 let houses: i64=c_count(board, n, 1); let farms: i64=c_count(board, n, 2); let markets: i64=c_count(board, n, 3)
23 res[1]=res[1]+farms*3
24 if res[0] < houses*4 { if res[1] > (res[0]+1)*2 { res[0]=res[0]+1 } }
25 res[2]=res[2]+markets
26 return 0
27}
28func c_render(fb: *i64, w: i64, h: i64, cell: i64, gw_: i64, gh_: i64, board: *i64, res: *i64) -> i64 {
29 gr_clear(fb, w, h, gr_pack(30, 40, 30))
30 var y: i64=0
31 while y<gh_ {
32 var x: i64=0
33 while x<gw_ {
34 let k: i64=board[y*gw_+x]; var col: i64=gr_pack(40,54,40)
35 if k==1 { col=gr_pack(200,170,120) } if k==2 { col=gr_pack(90,180,80) } if k==3 { col=gr_pack(240,210,80) }
36 gr_rect(fb, w, h, x*cell+1, y*cell+1, x*cell+cell-1, y*cell+cell-1, col)
37 x=x+1
38 }
39 y=y+1
40 }
41 gr_rect(fb, w, h, 2, h-5, 2+res[0]*3, h-2, gr_pack(120,200,240)) // population bar
42 return 0
43}
44
45func main() -> i64 {
46 gw("=== nx_game_city_gate: GENRE City-Building -- a real integer/no-float playable (live evidence) ===\n" as *u8)
47 var pass: i64 = 0; var total: i64 = 0
48 let GW: i64=8; let GH: i64=6; let CELL: i64=14; let W: i64=GW*CELL; let H: i64=GH*CELL; let N: i64=GW*GH; let TARGET: i64=12
49 let board: *i64=sys_mmap(8*(N+4)) as *i64; let res: *i64=sys_mmap(8*4) as *i64
50
51 // build a planned layout (4 houses, 3 farms, 1 market)
52 var i: i64=0; while i<N { board[i]=0; i=i+1 }
53 board[1*GW+1]=1; board[1*GW+2]=1; board[2*GW+1]=1; board[2*GW+2]=1 // houses (cap 16)
54 board[1*GW+5]=2; board[1*GW+6]=2; board[2*GW+5]=2 // farms
55 board[4*GW+4]=3 // market
56
57 // ---- T1: the city grows to the population target ----
58 res[0]=0; res[1]=0; res[2]=0
59 var tick: i64=0
60 while tick < 200 { if res[0]>=TARGET { tick=200 } else { c_tick(board, N, res); tick=tick+1 } }
61 let pop1: i64=res[0]
62 total=total+1; if pop1>=TARGET { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
63 gw("T1 build-up: population grew to " as *u8); gn(pop1); gw(" (>= " as *u8); gn(TARGET); gw("), gold=" as *u8); gn(res[2]); gw(" (WIN)\n" as *u8)
64
65 let fb: *i64=sys_mmap(8*(W*H+8)) as *i64
66 c_render(fb, W, H, CELL, GW, GH, board, res)
67 write_png(fb, W, H, "knowledge/nx_game_city.png" as *u8)
68 gw(" (live evidence: PNG knowledge/nx_game_city.png -- city grid (houses/farms/market) + population bar)\n" as *u8)
69
70 // ---- T2: neg-control -- an empty city grows no population ----
71 var j: i64=0; let empty: *i64=sys_mmap(8*(N+4)) as *i64; while j<N { empty[j]=0; j=j+1 }
72 res[0]=0; res[1]=0; res[2]=0
73 tick=0; while tick < 200 { c_tick(empty, N, res); tick=tick+1 }
74 let pop2: i64=res[0]
75 total=total+1; if pop2==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
76 gw("T2 neg-control: an empty city grew population=" as *u8); gn(pop2); gw(" (=0, buildings are real)\n" as *u8)
77
78 // ---- T3: housing cap real -- population never exceeds houses*4 ----
79 let cap: i64=c_count(board, N, 1)*4
80 res[0]=0; res[1]=0; res[2]=0
81 tick=0; while tick < 400 { c_tick(board, N, res); tick=tick+1 }
82 let pop3: i64=res[0]
83 total=total+1; if pop3<=cap { if pop3==cap { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) }
84 gw("T3 cap real: population saturated at " as *u8); gn(pop3); gw(" = housing cap (houses*4=" as *u8); gn(cap); gw(")\n" as *u8)
85
86 // ---- T4: never-brick / determinism ----
87 res[0]=0; res[1]=0; res[2]=0
88 tick=0; while tick < 200 { if res[0]>=TARGET { tick=200 } else { c_tick(board, N, res); tick=tick+1 } }
89 total=total+1; if res[0]==pop1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) }
90 gw("T4 never-brick (#26): deterministic re-run (pop=" as *u8); gn(res[0]); gw("==" as *u8); gn(pop1); gw("), bounded, no float\n" as *u8)
91
92 gw("\n=== nx_game_city_gate " as *u8); gn(pass); gw("/" as *u8); gn(total)
93 if pass == total { gw(" GREEN (City-Building: a real playable build->produce->grow sim with a housing cap, rendered, sovereign)\n" as *u8); sys_exit(0); return 0 }
94 gw(" RED\n" as *u8); sys_exit(1); return 1
95}