31 lines
3.8 KiB
JavaScript
31 lines
3.8 KiB
JavaScript
const{chromium}=require('playwright'),fs=require('fs'),assert=require('assert');
|
|
(async()=>{
|
|
const b=await chromium.launch({channel:'chrome',headless:true}),p=await b.newPage({viewport:{width:640,height:1136}}),errors=[];
|
|
p.on('pageerror',e=>errors.push(String(e)));
|
|
await p.goto('http://127.0.0.1:8765/?version=pass16&level=6');await p.waitForFunction(()=>{if(!window.Laya?.stage)return false;function v(n){for(const c of n._components||[])if(c.playerNodes)window.g=c;for(const ch of n._children||[])v(ch)}v(Laya.stage);return window.g?.total>0&&!g.busy;});
|
|
const selection=await p.evaluate(()=>{
|
|
const car=g.queues[0][1], actual=g.selectDirectPassengers(car).cells;
|
|
const fire=g.carNodes.get(car).transform.position,cols=g.board[0].length;let center=0,min=Infinity;
|
|
for(let c=0;c<cols;c++){const d=Math.abs(g.boardWorldPoint(0,c).x-fire.x);if(d<min){min=d;center=c;}}
|
|
const n=g.parked.filter(c=>c.color===car.color).length,radius=n<2?Math.max(6,Math.ceil(.42*cols)):Math.max(5,Math.ceil(cols/(n+1.2)));
|
|
const expected=[];
|
|
for(let i=0;i<car.capacity;i++){let best=null,score=Infinity;g.board.forEach((row,r)=>row.forEach((v,c)=>{if(v!==car.color||expected.some(x=>x[0]===r&&x[1]===c)||g.reservedPassengers.has(`${r}:${c}`))return;
|
|
const pt=g.boardWorldPoint(r,c);let s=.35*r+Math.abs(pt.x-fire.x)+Math.abs(pt.z-fire.z)+.6*Math.max(0,Math.abs(c-center)-radius);
|
|
expected.forEach(([br,bc])=>{s+=1.2*Math.max(0,2.5-Math.abs(c-bc));if(Math.abs(br-r)<=1)s+=.8;});if(s<score){score=s;best=[r,c];}}));if(!best)break;expected.push(best);}
|
|
return{matches:JSON.stringify(actual)===JSON.stringify(expected),count:actual.length,first:actual.slice(0,6)};
|
|
});assert(selection.matches);
|
|
await p.evaluate(()=>{
|
|
window.jumps=[];const original=g.jumpIntoCar.bind(g);
|
|
g.jumpIntoCar=(node,target,speed,row,col,done)=>{const r={name:node.name,start:Laya.timer.currTimer,from:node.transform.position.clone(),target:target.clone(),scale:node.transform.localScale.x,scaleError:0,maxLift:0,frames:0,finished:false};jumps.push(r);
|
|
original(node,target,speed,row,col,()=>{r.elapsed=Laya.timer.currTimer-r.start;r.finished=true;done();});};
|
|
class Probe extends Laya.Script{onLateUpdate(){for(const r of jumps){if(r.finished)continue;const n=g.playerNodes.get(r.name.replace('player_','').replace('_',':'));if(!n||!n.active)continue;r.frames++;r.scaleError=Math.max(r.scaleError,Math.abs(n.transform.localScale.x-r.scale));r.maxLift=Math.max(r.maxLift,n.transform.position.y-Math.max(r.from.y,r.target.y));}}}
|
|
g.owner.addComponent(Probe);
|
|
});
|
|
const pt=await p.evaluate(()=>g.laneHits[0].localToGlobal(new Laya.Point(42,60)));await p.mouse.click(pt.x,pt.y);await p.waitForFunction(()=>g.activeMoves===0&&g.cleared>0,undefined,{timeout:25000});
|
|
const jumps=await p.evaluate(()=>jumps.map(r=>({frames:r.frames,scaleError:r.scaleError,maxLift:r.maxLift,elapsed:r.elapsed,finished:r.finished})));
|
|
assert(jumps.length>0);assert(jumps.every(j=>j.finished&&j.scaleError<.00001&&j.elapsed>=175&&j.elapsed<500));assert(jumps.some(j=>j.maxLift>.1));
|
|
await p.screenshot({path:'artifacts/original-ui-20261017/pass16/normal-arrivals.png'});
|
|
assert.deepEqual(errors,[]);const result={scope:'Real level6 normal-car clicks; scoring compared to independent port of static v10 formula, not original runtime playback',selection,jumpCount:jumps.length,minDuration:Math.min(...jumps.map(j=>j.elapsed)),maxDuration:Math.max(...jumps.map(j=>j.elapsed)),maxScaleError:Math.max(...jumps.map(j=>j.scaleError)),observedLift:Math.max(...jumps.map(j=>j.maxLift)),errors};
|
|
fs.writeFileSync('artifacts/original-ui-20261017/pass16/motion-regression.json',JSON.stringify(result,null,2));console.log(JSON.stringify(result));await Promise.race([b.close(),new Promise(r=>setTimeout(r,3000))]);process.exit(0);
|
|
})().catch(e=>{console.error(e);process.exit(1)});
|