code wiki / _hdl_build / nx_playtest_creature.nx
nx_playtest_creature.nx source
↩ module page · 101 lines · 6220 B
1// nx_playtest_creature.nx -- a SOVEREIGN AUTOMATED PLAYTESTER (the Google/DeepMind-style "agents actually play the
2// game" tooling, built hardware-rung-up). It drives nx_creature_game BLACK-BOX (only cg_status/cg_nlegal/
3// cg_observe/cg_step -- no privileged internals), across many seeds x two policies (RANDOM exploration + a
4// HEURISTIC player), checking INVARIANTS every step (state stays valid, a legal move always exists while ongoing,
5// the game always TERMINATES). Then it renders an HONEST verdict that CAN FAIL: a game is PLAYABLE only if 0
6// invariant violations, 0 hangs/softlocks, it is WINNABLE under good play, AND it has real fail states + skill
7// depth (heuristic beats random). If this fails, our game ecosystem is not delivering a real game yet. license_tier: ORIGINAL expect_exit: 0
8import "nx_creature_game.nx"
9import "nx_syscalls.nx"
10const N_MAGIC_1103515245: i64 = 1103515245
11const N_MAGIC_12345: i64 = 12345
12const N_MAGIC_32767: i64 = 32767
13const N_MAGIC_2654435761: i64 = 2654435761
14
15const N_SESS: i64 = 64
16
17func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
18func wn(v: i64) -> i64 { var m: i64=v; if m<0{w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
19func pol_rng(b: *i64) -> i64 { var x: i64 = b[0]; x = x*N_MAGIC_1103515245 + N_MAGIC_12345; b[0]=x; return (x >> 16) & N_MAGIC_32767 }
20
21// invariants that must hold for ANY play. 0 ok, else the violated id.
22func pt_inv(o: *i64, nlegal: i64, status: i64) -> i64 {
23 if o[1] < 0 { return 1 } // lead hp >= 0
24 if o[1] > o[2] { return 1 } // lead hp <= max
25 if o[0] == 1 { if o[3] < 0 { return 1 } if o[3] > o[4] { return 1 } } // wild hp bounds in encounter
26 if o[5] < 0 { return 2 } // balls >= 0
27 if o[6] < 0 { return 2 } if o[6] > o[7] { return 2 } // caught in [0,goal]
28 if o[8] < 0 { return 2 } if o[8] > o[9] { return 2 } // pos in [0,routelen]
29 if o[0] < 0 { return 2 } if o[0] > 3 { return 2 } // mode valid
30 if status == 0 { if nlegal < 1 { return 3 } } // a legal move exists while ongoing
31 return 0
32}
33
34// play ONE session. policy 0=random 1=heuristic. returns 1 win, 2 lose, 3 violation, 4 hang. vbox = violated id.
35func pt_session(seed: i64, policy: i64, vbox: *i64) -> i64 {
36 let st: *i64 = cg_init(seed)
37 let o: *i64 = sys_mmap(8*16) as *i64
38 let pb: *i64 = sys_mmap(16) as *i64; pb[0] = seed*N_MAGIC_2654435761 + N_MAGIC_12345
39 var guard: i64 = 0; var run: i64 = 1; var result: i64 = 0
40 while run == 1 {
41 guard = guard + 1
42 if guard > 600 { result = 4; run = 0 } else {
43 let status: i64 = cg_status(st)
44 cg_observe(st, o)
45 let nl: i64 = cg_nlegal(st)
46 let v: i64 = pt_inv(o, nl, status)
47 if v != 0 { vbox[0] = v; result = 3; run = 0 } else {
48 if status == 1 { result = 1; run = 0 } else {
49 if status == 2 { result = 2; run = 0 } else {
50 var a: i64 = 0
51 if policy == 0 { a = pol_rng(pb) % nl } else {
52 if o[0] == 1 { if o[5] <= 0 { a = 3 } else { if o[3] > o[4]/2 { a = 0 } else { a = 2 } } } else { a = 0 }
53 }
54 cg_step(st, a)
55 }
56 }
57 }
58 }
59 }
60 return result
61}
62// run N sessions of a policy; tally into r[0]=win r[1]=lose r[2]=violation r[3]=hang ; vbox keeps last violated id.
63func pt_run(policy: i64, base: i64, r: *i64, vbox: *i64) -> i64 {
64 r[0]=0; r[1]=0; r[2]=0; r[3]=0
65 var i: i64 = 0
66 while i < N_SESS {
67 let res: i64 = pt_session(base + i*7 + 1, policy, vbox)
68 if res==1 { r[0]=r[0]+1 } if res==2 { r[1]=r[1]+1 } if res==3 { r[2]=r[2]+1 } if res==4 { r[3]=r[3]+1 }
69 i = i + 1
70 }
71 return 0
72}
73
74func main(argc: i64, argv: *i64) -> i64 {
75 w("=== nx_playtest_creature -- SOVEREIGN automated playtester (agents actually PLAY the game, black-box) ===\n" as *u8)
76 w(" drives nx_creature_game across "); wn(N_SESS); w(" seeds x {random, heuristic}; checks invariants every step.\n\n" as *u8)
77 let rr: *i64 = sys_mmap(64) as *i64; let rh: *i64 = sys_mmap(64) as *i64
78 let vb: *i64 = sys_mmap(16) as *i64; vb[0] = 0
79 pt_run(0, 1000, rr, vb)
80 pt_run(1, 1000, rh, vb)
81 w(" RANDOM policy: win="); wn(rr[0]); w(" lose="); wn(rr[1]); w(" violation="); wn(rr[2]); w(" hang="); wn(rr[3]); w("\n" as *u8)
82 w(" HEURISTIC policy: win="); wn(rh[0]); w(" lose="); wn(rh[1]); w(" violation="); wn(rh[2]); w(" hang="); wn(rh[3]); w("\n\n" as *u8)
83
84 let viol: i64 = rr[2] + rh[2]
85 let hang: i64 = rr[3] + rh[3]
86 var ok: i64 = 1
87 if viol != 0 { w(" FAIL: "); wn(viol); w(" invariant VIOLATION(s) -> the game produced INVALID states (last id="); wn(vb[0]); w(") = broken\n" as *u8); ok = 0 }
88 if hang != 0 { w(" FAIL: "); wn(hang); w(" HANG(s)/softlock -> the game did not terminate = broken\n" as *u8); ok = 0 }
89 if rh[0] <= 0 { w(" FAIL: heuristic NEVER won -> the game is UNWINNABLE under good play\n" as *u8); ok = 0 }
90 if rr[1] <= 0 { w(" FAIL: random NEVER lost -> no real fail states (trivial, not a real game)\n" as *u8); ok = 0 }
91 if rh[0] <= rr[0] { w(" FAIL: heuristic did not beat random -> no skill depth (decisions don't matter)\n" as *u8); ok = 0 }
92
93 if ok == 1 {
94 w("PLAYTEST verdict=PASS (PLAYABLE: 0 violations, 0 hangs, winnable under good play, real fail states, skill matters)\n" as *u8)
95 w(" HONEST: this proves the tiny creature game RUNS as a real game under automated play. It is NOT s-class:\n" as *u8)
96 w(" no visuals/UI/audio/content/2D-world/multiplayer; 1 species, 1 route. The PLAYTESTER is the deliverable rung.\n" as *u8)
97 sys_exit(0); return 0
98 }
99 w("PLAYTEST verdict=FAIL -> our game ecosystem is NOT delivering a working game here yet (see FAIL lines above). HONEST.\n" as *u8)
100 sys_exit(1); return 1
101}