nx_caplab_sim.nx source
↩ module page · 78 lines · 3162 B
1// nx_caplab_sim.nx -- Capitalism Lab R3: the simulation TICK LOOP (it becomes a
2// game, not a calculator). N firms compete over many turns: each tick the
3// market allocates demand by price (R1 share), each firm sells up to its
4// production capacity, and cash accumulates. Includes an AI competitor price
5// strategy and the CAPITALISM_LAB game config (the gmod/registry pattern).
6// Deterministic by construction (pure integer, no RNG) -> replay-identical.
7//
8// MODEL (per tick):
9// demand[i] = R1 appeal-share split of market_m by price
10// sold[i] = min(demand[i], capacity[i]) (capacity caps sales)
11// cash[i] += (price[i] - unit_cost[i]) * sold[i]
12//
13// nx_safety_envelope:
14// intended_use: capitalism-lab simulation core (pure functions, no I/O)
15// sil_target: SIL1
16// verdict: NOT_YET_EVALUATED
17//
18// genealogy_id: capitalism_lab_simulation_canon
19// lineage_id: nx_caplab_sim_v1
20
21import "nx_syscalls.nx"
22import "nx_tier.nx"
23import "nx_caplab_compete.nx"
24
25// ----- one simulation tick: allocate demand, cap by capacity, bank profit -----
26func nx_clab_sim_tick(n: nx_int, prices: *i64, unit_costs: *i64, caps: *i64,
27 choke: nx_int, market_m: nx_int, cash: *i64, sold: *i64) {
28 let demand: *i64 = (sys_mmap(n * NX_SIZEOF_NX_INT)) as *i64
29 nx_clab_split(n, prices, choke, market_m, demand)
30 var i: nx_int = 0
31 while i < n {
32 var s: nx_int = demand[i]
33 if s > caps[i] { s = caps[i] }
34 sold[i] = s
35 cash[i] = cash[i] + (prices[i] - unit_costs[i]) * s
36 i = i + 1
37 }
38}
39
40// ----- run `ticks` turns with fixed prices; accumulates into cash[] -----
41func nx_clab_sim_run(n: nx_int, prices: *i64, unit_costs: *i64, caps: *i64,
42 choke: nx_int, market_m: nx_int, cash: *i64, ticks: nx_int) {
43 let sold: *i64 = (sys_mmap(n * NX_SIZEOF_NX_INT)) as *i64
44 var t: nx_int = 0
45 while t < ticks {
46 nx_clab_sim_tick(n, prices, unit_costs, caps, choke, market_m, cash, sold)
47 t = t + 1
48 }
49}
50
51// ----- AI competitor: undercut the rival by delta, never below cost+1 -----
52// (a firm that prices below cost loses money on every unit, so the AI won't).
53func nx_clab_ai_price(rival_price: nx_int, my_cost: nx_int, delta: nx_int) -> nx_int {
54 var p: nx_int = rival_price - delta
55 let floorp: nx_int = my_cost + 1
56 if p < floorp { p = floorp }
57 return p
58}
59
60// ===== CAPITALISM_LAB gamemode config (gmod/registry record pattern) =========
61const NX_CLAB_MODE_ID: nx_int = 100
62const NX_CLAB_CFG_STRIDE: nx_int = 6
63const NX_CLAB_CFG_MODE: nx_int = 0
64const NX_CLAB_CFG_START_CASH: nx_int = 1
65const NX_CLAB_CFG_MARKET_M: nx_int = 2
66const NX_CLAB_CFG_CHOKE: nx_int = 3
67const NX_CLAB_CFG_TICKS: nx_int = 4
68const NX_CLAB_CFG_N_FIRMS: nx_int = 5
69
70// Default CAPITALISM_LAB scenario: a 12-month year, $1000 seed, 4 firms.
71func nx_clab_mode_init(cfg: *i64) {
72 cfg[NX_CLAB_CFG_MODE] = NX_CLAB_MODE_ID
73 cfg[NX_CLAB_CFG_START_CASH] = 1000
74 cfg[NX_CLAB_CFG_MARKET_M] = 120
75 cfg[NX_CLAB_CFG_CHOKE] = 100
76 cfg[NX_CLAB_CFG_TICKS] = 12
77 cfg[NX_CLAB_CFG_N_FIRMS] = 4
78}