// Headless-Balance-Messung (temporär). node sim-harness.mjs import { createState, place, upgrade, callNextWave, tick, GOALS } from '../../App/sims/tourismusregion/js/model.js'; import { BUILDINGS, GAME_LEN } from '../../App/sims/tourismusregion/js/data.js'; const ALL_TYPES = Object.keys(BUILDINGS); function upgradeAllMax(s) { for (const b of s.buildings) { const def = BUILDINGS[b.type]; let guard = 0; while (b.level < def.cost.length && s.budget >= def.cost[b.level] && guard++ < 6) { const r = upgrade(s, b); if (!r || !r.ok) break; } } } function run(strategy, mapId = 'talschleife') { const s = createState({ mapId, seed: 12345 }); const dt = 0.5; let t = 0; function tryBuildAll() { for (let i = 0; i < s.slots.length; i++) { const slot = s.slots[i]; if (slot.building || slot.blocked) continue; for (const type of ALL_TYPES) { const def = BUILDINGS[type]; if (!def || s.budget < def.cost[0]) continue; const r = place(s, type, i); if (r && r.ok) break; } } } function buildOneCafe() { // Minimal-Strategie: genau EIN Café (Thomas' „5-Sterne-Café macht alles grün") if (s.buildings.length) return; for (let i = 0; i < s.slots.length; i++) { if (s.slots[i].building || s.slots[i].blocked) continue; const r = place(s, 'cafe', i); if (r && r.ok) return; } } let guard = 0; while (t < GAME_LEN && s.phase < 8 && guard++ < 2000) { if (strategy === 'buildAll' || strategy === 'maxedAll') tryBuildAll(); if (strategy === 'maxedAll') upgradeAllMax(s); if (strategy === 'oneCafe') buildOneCafe(); try { callNextWave(s); } catch (_) {} for (let k = 0; k < 40 && t < GAME_LEN; k++) { tick(s, dt); t += dt; } } if (strategy === 'maxedAll') upgradeAllMax(s); // Restzeit auslaufen lassen while (t < GAME_LEN && guard++ < 6000) { tick(s, dt); t += dt; } const stars = s.stats.all.count ? s.stats.all.stars / s.stats.all.count : 0; return { strategy, env: Math.round(s.env), avgStars: +stars.toFixed(2), visitorsExited: s.stats.all.count, budget: Math.round(s.budget), buildings: s.buildings.length, traffic: Math.round(s.traffic || 0), goalsMet: GOALS.filter(g => g.check(s)).length + '/' + GOALS.length, }; } console.log('=== Tourismusregion Balance-Messung (talschleife) ==='); for (const strat of ['maxedAll', 'buildAll', 'oneCafe']) { const r = run(strat); console.log(`${strat.padEnd(9)} → env ${String(r.env).padStart(3)} · Ø${r.avgStars}★ · ${r.buildings} Geb. · Verkehr ${r.traffic} · Ziele ${r.goalsMet} · Budget ${r.budget}`); }