code wiki / (root) / nx_econ_game.nx

nx_econ_game.nx source

↩ module page · 49 lines · 4780 B

1// nx_econ_game.nx -- SOVEREIGN VISUAL ENGINE rung V3b: build-and-PLAY tycoon. 2// 3// Fuses the build-and-place board with a live economy: place factories (produce 4// goods) + stores (sell goods), pay upkeep, money ticks each month -> win at $5000 5// or go bankrupt. Economy mirrors the gated nx_caplab_* sim (produce/sell/margin). 6// The .nx organ emits the entire playable client (sovereign, organ-authored JS; 7// single-quoted -> no escaping). This is capitalism-lab build-and-place WITH 8// visuals, playable in-browser. license_tier: ORIGINAL. 9 10import "nx_syscalls.nx" 11 12func eg_app(out: *u8, off: *i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { out[off[0]] = s[i]; off[0] = off[0] + 1; i = i + 1 } return 0 } 13 14func nx_econ_game_page(out: *u8, out_cap: i64) -> i64 { 15 let off: *i64 = (sys_mmap(8)) as *i64 16 off[0] = 0 17 eg_app(out, off, "<!doctype html><html><head><meta charset=utf-8><title>Nishi Tycoon</title><style>" as *u8) 18 eg_app(out, off, "body{background:#12141c;color:#dde;font-family:system-ui,sans-serif;text-align:center;margin:14px}" as *u8) 19 eg_app(out, off, "button{padding:7px 12px;margin:3px;border:0;border-radius:6px;background:#0b2545;color:#fff;cursor:pointer}button.sel{background:#2a8a55}" as *u8) 20 eg_app(out, off, "#hud{margin:8px;font-size:1.05rem}#hud b{color:#9fe}canvas{margin-top:8px;border:2px solid #444;background:#3a5a3a;cursor:pointer}</style></head><body>" as *u8) 21 eg_app(out, off, "<h2>Nishi Tycoon &mdash; sovereign build &amp; play</h2><p style=color:#889;font-size:.85rem>Factory makes 10 goods/mo. Store sells 8/mo at $5. Each building costs $5/mo upkeep. Reach $5000 to win.</p>" as *u8) 22 eg_app(out, off, "<div id=hud></div>" as *u8) 23 eg_app(out, off, "<div><button id=bF class=sel onclick=sel('F')>Factory ($200)</button><button id=bS onclick=sel('S')>Store ($150)</button><button id=bX onclick=sel('X')>Bulldoze</button></div>" as *u8) 24 eg_app(out, off, "<canvas id=c width=480 height=384></canvas>" as *u8) 25 eg_app(out, off, "<script>var COLS=10,ROWS=8,CS=48,grid=[],cur='F',money=1000,month=1,inv=0,over=0,i;for(i=0;i<COLS*ROWS;i++)grid[i]=0;" as *u8) 26 eg_app(out, off, "var ctx=document.getElementById('c').getContext('2d');" as *u8) 27 eg_app(out, off, "function sel(t){cur=t;['F','S','X'].forEach(function(k){document.getElementById('b'+k).className=(k==t)?'sel':''})}" as *u8) 28 eg_app(out, off, "function cnt(v){var n=0,j;for(j=0;j<grid.length;j++)if(grid[j]==v)n++;return n}" as *u8) 29 eg_app(out, off, "function dFactory(x,y){ctx.fillStyle='#787c84';ctx.fillRect(x+6,y+18,36,24);ctx.fillStyle='#50545c';ctx.fillRect(x+6,y+12,36,7);ctx.fillRect(x+30,y+4,7,10);ctx.fillStyle='#cde6ff';ctx.fillRect(x+12,y+24,7,7);ctx.fillRect(x+28,y+24,7,7)}" as *u8) 30 eg_app(out, off, "function dStore(x,y){ctx.fillStyle='#965a46';ctx.fillRect(x+6,y+20,36,22);ctx.fillStyle='#c8463c';ctx.fillRect(x+4,y+14,40,7);ctx.fillStyle='#e6dcb4';ctx.fillRect(x+18,y+28,12,14)}" as *u8) 31 eg_app(out, off, "function render(){var cx,cy;for(cy=0;cy<ROWS;cy++)for(cx=0;cx<COLS;cx++){var x=cx*CS,y=cy*CS;ctx.fillStyle=((cx+cy)%2==0)?'#3c5a3c':'#365436';ctx.fillRect(x,y,CS,CS);ctx.strokeStyle='#2a402a';ctx.strokeRect(x,y,CS,CS);var v=grid[cy*COLS+cx];if(v==1)dFactory(x,y);if(v==2)dStore(x,y)}}" as *u8) 32 eg_app(out, off, "function hud(){var s='';if(over==1)s=' <b style=color:#7f7>YOU WIN!</b>';if(over==2)s=' <b style=color:#f77>BANKRUPT</b>';document.getElementById('hud').innerHTML='Money <b>$'+money+'</b> | Month <b>'+month+'</b> | Inventory <b>'+inv+'</b> | Factories <b>'+cnt(1)+'</b> | Stores <b>'+cnt(2)+'</b>'+s}" as *u8) 33 eg_app(out, off, "document.getElementById('c').onclick=function(e){if(over)return;var r=this.getBoundingClientRect();var cx=Math.floor((e.clientX-r.left)/CS),cy=Math.floor((e.clientY-r.top)/CS);if(cx<0||cy<0||cx>=COLS||cy>=ROWS)return;var k=cy*COLS+cx;if(cur=='X'){grid[k]=0}else if(cur=='F'){if(money>=200&&grid[k]==0){money-=200;grid[k]=1}}else if(cur=='S'){if(money>=150&&grid[k]==0){money-=150;grid[k]=2}}render();hud()};" as *u8) 34 eg_app(out, off, "function tick(){if(over)return;var nf=cnt(1),ns=cnt(2);inv+=nf*10;var sold=Math.min(inv,ns*8);inv-=sold;money+=sold*5-(nf+ns)*5;month++;if(money>=5000)over=1;if(money<0)over=2;hud()}" as *u8) 35 eg_app(out, off, "setInterval(tick,1000);render();hud();</script></body></html>\n" as *u8) 36 out[off[0]] = 0 as u8 37 return off[0] 38} 39 40func nx_econ_game_save(path: *u8) -> i64 { 41 let out: *u8 = sys_mmap(65536) 42 let len: i64 = nx_econ_game_page(out, 65536) 43 let fd: i64 = sys_openat_wr(path, 420) 44 if fd < 0 { return 0 - 1 } 45 var wr: i64 = 0 46 while wr < len { let c: i64 = sys_write(fd, out + wr, len - wr); if c <= 0 { break } wr = wr + c } 47 sys_close(fd) 48 return wr 49}