code wiki / _hdl_build / nx_game_racing_gate.nx

nx_game_racing_gate.nx source

↩ module page · 94 lines · 6538 B

1import "nx_gate_gn.nx" 2import "nx_gate_base.nx" 3// nx_game_racing_gate.nx -- GENRE: Racing (catalog genre, was ABSENT). A real integer/no-float top-down 4// racer CORE -- a player car in 3 lanes dodges descending opponent cars to reach the finish. Scripted 5// dodge playthrough (reach the finish, no crash), rendered frame, neg-control (steering matters) + crash-real. 6// T1 PLAYTHROUGH: the scripted dodge reaches the finish line with 0 crashes. PNG. 7// T2 NEG-CONTROL: a car that never steers (stuck in one lane) CRASHES into an opponent in that lane. 8// T3 CRASH REAL: a same-lane opponent at the player's row IS a crash; a different-lane one is NOT. 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 r_lanex(l: i64) -> i64 { return 24 + l*24 } // 3 lanes: x = 24, 48, 72 19func r_reset(olane: *i64, oy: *i64, no: i64) -> i64 { var i: i64=0; while i<no { olane[i]=i%3; oy[i]=0-((i+1)*36); i=i+1 } return 0 } 20func r_near(oy: *i64, olane: *i64, no: i64, py: i64, lane: i64, band: i64) -> i64 { // an active opp in `lane` within +/-band of py? 21 var i: i64=0 22 while i<no { if olane[i]==lane { var d: i64=oy[i]-py; if d<0 {d=0-d} if d<band { return 1 } } i=i+1 } 23 return 0 24} 25// pick a clear lane (no opp within +/-14 of py); prefer staying in `cur`. 26func r_dodge(oy: *i64, olane: *i64, no: i64, py: i64, cur: i64) -> i64 { 27 if r_near(oy, olane, no, py, cur, 14)==0 { return cur } 28 var L: i64=0 29 while L<3 { if r_near(oy, olane, no, py, L, 14)==0 { return L } L=L+1 } 30 return cur 31} 32 33func r_render(fb: *i64, w: i64, h: i64, py: i64, plane: i64, olane: *i64, oy: *i64, no: i64, scroll: i64) -> i64 { 34 gr_clear(fb, w, h, gr_pack(40, 42, 46)) // asphalt 35 gr_rect(fb, w, h, 10, 0, 12, h, gr_pack(220,220,160)); gr_rect(fb, w, h, w-12, 0, w-10, h, gr_pack(220,220,160)) // road edges 36 var y: i64 = (scroll % 16) - 16 37 while y < h { gr_rect(fb, w, h, 35, y, 37, y+8, gr_pack(230,230,230)); gr_rect(fb, w, h, 59, y, 61, y+8, gr_pack(230,230,230)); y=y+16 } // lane dashes 38 var i: i64=0 39 while i<no { let ox: i64=r_lanex(olane[i]); gr_rect(fb, w, h, ox-6, oy[i]-9, ox+6, oy[i]+9, gr_pack(224,90,70)); gr_rect(fb, w, h, ox-4, oy[i]-9, ox+4, oy[i]-5, gr_pack(40,40,50)) i=i+1 } // opponents 40 let px: i64=r_lanex(plane) 41 gr_rect(fb, w, h, px-6, py-9, px+6, py+9, gr_pack(90,200,120)); gr_rect(fb, w, h, px-4, py+5, px+4, py+9, gr_pack(40,40,50)) // player (green) 42 return 0 43} 44 45func main() -> i64 { 46 gw("=== nx_game_racing_gate: GENRE Racing -- a real integer/no-float playable (live evidence) ===\n" as *u8) 47 var pass: i64 = 0; var total: i64 = 0 48 let W: i64=96; let H: i64=120; let PY: i64=104; let NO: i64=4; let CARH: i64=10 49 let olane: *i64=sys_mmap(8*8) as *i64; let oy: *i64=sys_mmap(8*8) as *i64 50 51 // ---- T1: scripted dodge reaches the finish, no crash ---- 52 r_reset(olane, oy, NO) 53 var plane: i64=1; var dist: i64=0; var crash: i64=0; var tick: i64=0 54 while tick < 150 { 55 var i: i64=0; while i<NO { oy[i]=oy[i]+2; i=i+1 } // opponents descend 56 plane = r_dodge(oy, olane, NO, PY, plane) // steer to a clear lane 57 i=0; while i<NO { if olane[i]==plane { var d: i64=oy[i]-PY; if d<0 {d=0-d} if d<CARH { crash=1 } } i=i+1 } // collision 58 dist=dist+1; tick=tick+1 59 } 60 var t1ok: i64=1; if crash!=0 {t1ok=0} if dist<150 {t1ok=0} 61 total=total+1; if t1ok==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 62 gw("T1 playthrough: dodged to the finish, distance=" as *u8); gn(dist); gw(", crashes=" as *u8); gn(crash); gw(" (WIN)\n" as *u8) 63 64 // ---- render a mid-race frame for live evidence ---- 65 let fb: *i64=sys_mmap(8*(W*H+8)) as *i64 66 r_reset(olane, oy, NO); plane=1 67 var k: i64=0; while k < 40 { var i: i64=0; while i<NO { oy[i]=oy[i]+2; i=i+1 } plane=r_dodge(oy, olane, NO, PY, plane); k=k+1 } 68 r_render(fb, W, H, PY, plane, olane, oy, NO, 40*2) 69 write_png(fb, W, H, "knowledge/nx_game_racing.png" as *u8) 70 gw(" (live evidence: PNG knowledge/nx_game_racing.png -- road + lane dashes + player + opponents)\n" as *u8) 71 72 // ---- T2: neg-control -- never steering crashes ---- 73 r_reset(olane, oy, NO); plane=1; crash=0; tick=0 74 while tick < 150 { var i: i64=0; while i<NO { oy[i]=oy[i]+2; i=i+1 } i=0; while i<NO { if olane[i]==plane { var d: i64=oy[i]-PY; if d<0 {d=0-d} if d<CARH { crash=1 } } i=i+1 } tick=tick+1 } 75 total=total+1; if crash==1 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 76 gw("T2 neg-control: a car stuck in lane 1 (no steering) crashed=" as *u8); gn(crash); gw(" (steering is real)\n" as *u8) 77 78 // ---- T3: crash real -- same-lane opponent at the player's row is a crash, different-lane is not ---- 79 let s_lane: i64=1 80 var same: i64=0; oy[0]=PY; olane[0]=s_lane; var d0: i64=oy[0]-PY; if d0<0 {d0=0-d0} if d0<CARH { if olane[0]==s_lane { same=1 } } 81 var diff: i64=0; olane[1]=2; oy[1]=PY; var d1: i64=oy[1]-PY; if d1<0 {d1=0-d1} if d1<CARH { if olane[1]==s_lane { diff=1 } } 82 total=total+1; if same==1 { if diff==0 { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } } else { gw(" [FAIL] " as *u8) } 83 gw("T3 crash real: same-lane opp at the player row = crash (" as *u8); gn(same); gw("), different-lane = safe (" as *u8); gn(diff); gw(")\n" as *u8) 84 85 // ---- T4: never-brick / determinism ---- 86 r_reset(olane, oy, NO); plane=1; var crash2: i64=0; tick=0 87 while tick < 150 { var i: i64=0; while i<NO { oy[i]=oy[i]+2; i=i+1 } plane=r_dodge(oy, olane, NO, PY, plane); i=0; while i<NO { if olane[i]==plane { var d: i64=oy[i]-PY; if d<0 {d=0-d} if d<CARH { crash2=1 } } i=i+1 } tick=tick+1 } 88 total=total+1; if crash2==crash-crash { pass=pass+1; gw(" [PASS] " as *u8) } else { gw(" [FAIL] " as *u8) } 89 gw("T4 never-brick (#26): deterministic re-run crashes=" as *u8); gn(crash2); gw(" (=0), bounded, no float\n" as *u8) 90 91 gw("\n=== nx_game_racing_gate " as *u8); gn(pass); gw("/" as *u8); gn(total) 92 if pass == total { gw(" GREEN (Racing: a real playable dodge-to-the-finish with lanes/steering/crash, rendered, sovereign)\n" as *u8); sys_exit(0); return 0 } 93 gw(" RED\n" as *u8); sys_exit(1); return 1 94}