import {PracticeBudget} from './practice-budget.ts'; import {environments as spatial} from './engine-spatial.ts'; import {environments as temporal} from './engine-temporal.ts'; import {environments as logic} from './engine-logic.ts'; import data from './benchmark.json'; const $=(s:string)=>document.querySelector(s) as HTMLElement; const escape=(s:unknown)=>String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]!)); const PALETTE=['#111d25','#344e59','#ecce76','#64b5b0','#dc765a','#8b8fc9','#e0b5c7','#73a773','#e9e5d5','#d8a262','#5d687f','#b7ce9c','#d49ca0','#82a6bb','#9e805e','#f3f0e8']; const descriptions:Record={a001:'Pivot cargo: translation, rotation and collision across six levels.',a005:'Local frame rover: motion relative to heading, floor transforms and cargo.',d009:'Escrow Cycle: delayed transfers, account capacity and settlement.',e005:'Transitive islands: connected and separated node-pair constraints.'}; const narratives:Record={a001:'Astra completes all six levels; DeepSeek clears five and Luna three before the normal time limit.',a005:'Qwen completes all six near the deadline. GPT-6 Sol clears five, while GPT-5.6 Sol reaches the action cap after one: a task-specific reversal of the overall Sol ordering.',d009:'Astra and GPT-5.6 Sol finish. GPT-6 Sol reaches the time limit and Terra the action limit without a verified first-level win.',e005:'Two full completions, two levels for GPT-6 Sol, and zero for Luna. Different valid edge configurations can satisfy the same graph constraints.'}; const environments=[...spatial,...temporal,...logic]; let env=environments.find(e=>e.id==='a001')!,seed=503117,level=1,state:any,initial:any,budget=new PracticeBudget(),completed:number[]=[]; function initializeLevel(){const value=env.init(level,seed);state=structuredClone(value.state);initial=structuredClone(value.state);/* Constructive witness is deliberately not retained or displayed. */} function remaining(){return budget.remaining();} function observation(){const o=env.observe(structuredClone(state));return{pixels:o.pixels.map(r=>r.slice()),actions:[...o.actions],level,status:env.solved(structuredClone(state))?'won':'playing'};} function terminal(){return budget.ending();} function draw(){const o=observation(),canvas=$('#pixels')as HTMLCanvasElement,scale=Math.max(4,Math.min(12,Math.floor(650/Math.max(o.pixels.length,o.pixels[0].length))));canvas.width=o.pixels[0].length*scale;canvas.height=o.pixels.length*scale;const ctx=canvas.getContext('2d')!;ctx.imageSmoothingEnabled=false;o.pixels.forEach((row,y)=>row.forEach((c,x)=>{ctx.fillStyle=PALETTE[c];ctx.fillRect(x*scale,y*scale,scale,scale)}));const stop=terminal(),won=o.status==='won';$('#game-label').textContent=`${env.id} · level ${level} / 6`;$('#game-actions').textContent=`${budget.actions} / 512 actions`;$('#game-clock').textContent=`${Math.ceil(remaining())} s left`;$('#case-description').textContent=descriptions[env.id];$('#game-controls').innerHTML=o.actions.map(b=>``).join('');document.querySelectorAll('[data-button]').forEach(b=>(b as HTMLButtonElement).onclick=()=>act({button:Number((b as HTMLElement).dataset.button)}));($('#reset-level')as HTMLButtonElement).disabled=!!stop||won;$('#next-level').hidden=!won||!!stop||level>=6;$('#game-status').textContent=stop==='time_budget'?`Time limit · ${completed.length}/6 completed`:stop==='action_budget'?`Action limit · ${completed.length}/6 completed`:won?(level===6?'All six levels complete.':`Level ${level} complete.`):`${completed.length}/6 completed · explore the controls`; } function act(action:any){if(terminal()||env.solved(structuredClone(state)))return;const o=observation();if(action.control==='reset'){state=structuredClone(initial);}else{if(!o.actions.includes(action.button))return;state=env.step(structuredClone(state),action);}if(env.solved(structuredClone(state))&&!completed.includes(level))completed.push(level);budget.recordAction(completed.length);draw();} function newPractice(id=env.id){const c=data.cases.find(c=>c.id===id)!;env=environments.find(e=>e.id===id)!;seed=c.seed;level=1;budget=new PracticeBudget();completed=[];initializeLevel();draw();} ($('#environment')as HTMLSelectElement).onchange=e=>newPractice((e.target as HTMLSelectElement).value); $('#new-practice').onclick=()=>newPractice();$('#reset-level').onclick=()=>act({control:'reset'});$('#next-level').onclick=()=>{if(!terminal()&&env.solved(structuredClone(state))&&level<6){level++;initializeLevel();draw();}}; $('#pixels').onclick=e=>{const c=e.currentTarget as HTMLCanvasElement,o=observation();if(!o.actions.includes(6))return;const r=c.getBoundingClientRect();act({button:6,x:Math.floor((e.clientX-r.left)*o.pixels[0].length/r.width),y:Math.floor((e.clientY-r.top)*o.pixels.length/r.height)});}; document.addEventListener('keydown',e=>{if(e.target instanceof HTMLSelectElement||e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement)return;const b=Number(e.key);if(Number.isInteger(b)&&b>=1&&b<=6){e.preventDefault();act({button:b});}if(e.key.toLowerCase()==='r'){e.preventDefault();act({control:'reset'});}}); setInterval(()=>{const stop=terminal();$('#game-clock').textContent=`${Math.ceil(remaining())} s left`;if(stop&&!$('#game-status').textContent?.includes('limit'))draw();},250); $('#leaderboard').innerHTML=data.models.map(m=>`${m.rank}${escape(m.name)}${m.full}/150${m.fullRate.toFixed(2)}%${m.levels}/900${m.levelRate.toFixed(2)}%${m.time}`).join(''); const charts:Record={'fullwins-vs-levels':{alt:'Complete task rates and cleared level rates for eleven configurations',caption:'Exact count columns use 150 tasks and 900 levels as separate denominators.'},'completion-depth-0-to-6':{alt:'Episode completion depth from zero through all six levels for eleven configurations',caption:'Every model has 150 episodes. Small segments are retained; the exact depth data accompany the dataset.'},'authored-family-heatmap':{alt:'Cleared levels across ten authored task families for eleven configurations',caption:'Each family offers 90 levels. Cell text is the cleared-level count; color encodes its percentage.'},'normal-budget-endings':{alt:'Normal completion, time limits, action limits and abandoned endings for eleven configurations',caption:'Ordinary budget exhaustion is a valid unfinished outcome; confirmed engineering exclusions are accounted separately.'}}; document.querySelectorAll('[data-chart]').forEach(b=>b.addEventListener('click',()=>{const key=(b as HTMLElement).dataset.chart!;document.querySelectorAll('[data-chart]').forEach(t=>t.setAttribute('aria-selected',String(t===b)));($('#result-chart')as HTMLImageElement).src=key+'.svg';($('#result-chart')as HTMLImageElement).alt=charts[key].alt;$('#chart-caption').textContent=charts[key].caption;})); function example(id:string){const c=data.cases.find(c=>c.id===id)!;$('#recorded-example').innerHTML=`
Shared initial observation for ${escape(id)}
${escape(id)} · seed ${c.seed} · shared initial observation

${escape(narratives[id])}

These are actual selected episodes, not newly simulated model traces.

${c.panels.map(p=>`

${escape(p.model)}

Actual terminal observation for ${escape(p.model)} on ${escape(id)}
${p.levels} / 6 levels

${p.actions} actions · ${p.seconds.toFixed(3)} s

${p.end==='won'?'Full completion':p.end==='time_budget'?'Normal time limit':'Normal action limit'} · image at level ${p.levelShown}

`).join('')}
`;} document.querySelectorAll('[data-example]').forEach(b=>b.addEventListener('click',()=>{document.querySelectorAll('[data-example]').forEach(t=>t.setAttribute('aria-selected',String(t===b)));example((b as HTMLElement).dataset.example!);})); (window as any).recursivePlayDemo={snapshot:()=>({environment:env.id,seed,level,spent:budget.actions,completedLevels:[...completed],status:terminal()||observation().status,pixels:observation().pixels,remainingSeconds:remaining()}),newPractice}; newPractice('a001');example('a001');