Files
shanhe-puzzle/tests/magnet.test.cjs
codex-bot 4845826deb
Shanhe source and offline package checks / verify (pull_request) Failing after 5s
feat: sync Shanhe 2.2 source and add remote package verification
2026-11-01 17:13:46 +08:00

31 lines
3.8 KiB
JavaScript

const test=require('node:test'),assert=require('node:assert/strict'),M=require('matter-js');
const {Game,SNAP_DISTANCE,MAGNET_DISTANCE}=require('../src/game.js');
const square=(id,x)=>({id:String(id),name:'测试'+id,center:[x+50,50],rings:[[[x,0],[x+100,0],[x+100,100],[x,100]]]});
const level={id:'100000',name:'靠拢测试',width:1000,height:1000,regions:[square(0,0),square(1,100),square(2,200)],edges:[[0,1,0],[1,2,0]]};
function pair(distance=40,speed=0,bounce=0){const g=new Game(level,420,560,speed,()=>{},()=>.5,bounce);g.status='playing';g.queue=[];const ty=g.h-100*g.scale-.05;const a=g.createGroup([0],{tx:70,ty,angle:0}),b=g.createGroup([1],{tx:70+distance,ty,angle:0});return {g,a,b};}
test('正确配对仅施加等大反向力,唤醒地块且不瞬移或旋转',()=>{
const {g,a,b}=pair(),positions=g.groups.map(p=>({...p.body.position}));M.Sleeping.set(a.body,true);M.Sleeping.set(b.body,true);g.attractNearby();
assert.equal(g.magnetPairs,1);assert.deepEqual(g.groups.map(p=>({...p.body.position})),positions);assert.ok(a.body.force.x>0&&b.body.force.x<0);assert.ok(Math.abs(a.body.force.x+b.body.force.x)<1e-12);assert.equal(a.body.torque,0);assert.equal(b.body.torque,0);assert.ok(!a.body.isSleeping&&!b.body.isSleeping);g.destroy();
});
test('四速度四弹性下,40px误差的落地休眠邻块能靠拢进入26px并实际合并',()=>{
for(let speed=0;speed<4;speed++)for(let bounce=0;bounce<4;bounce++){const {g,a,b}=pair(40,speed,bounce);M.Sleeping.set(a.body,true);M.Sleeping.set(b.body,true);let merged=false;for(let i=0;i<180;i++){g.tick(1000/60);if(g.merges){merged=true;break;}}assert.ok(merged,JSON.stringify({speed,bounce}));assert.equal(g.groups.length,1);assert.deepEqual(g.groups[0].ids.slice().sort(),[0,1]);assert.equal(g.score,Math.round(100*g.speed.multiplier));g.destroy();}
});
test('45px含边界,26px直接合并区、过远、错向、错边和非邻接不额外牵引',()=>{
assert.equal(SNAP_DISTANCE,26);assert.equal(MAGNET_DISTANCE,45);const boundary=pair(45);boundary.g.attractNearby();assert.equal(boundary.g.magnetPairs,1);boundary.g.destroy();
for(const distance of [26,45.01,100]){const {g,a}=pair(distance);g.attractNearby();assert.equal(g.magnetPairs,0);assert.equal(a.body.force.x,0);g.destroy();}
const wrong=pair();M.Body.setAngle(wrong.b.body,.281);wrong.g.attractNearby();assert.equal(wrong.g.magnetPairs,0);wrong.g.destroy();
const noEdge=pair();noEdge.g.level={...level,edges:[]};noEdge.g.attractNearby();assert.equal(noEdge.g.magnetPairs,0);noEdge.g.destroy();
});
test('距离越近牵引越强,已经快速靠近时不追加助推',()=>{
const far=pair(44),near=pair(28);far.g.attractNearby();near.g.attractNearby();assert.ok(near.a.body.force.x>far.a.body.force.x);far.g.destroy();near.g.destroy();
const fast=pair();M.Body.setVelocity(fast.a.body,{x:3,y:0});fast.g.attractNearby();assert.equal(fast.g.magnetPairs,0);assert.equal(fast.a.body.force.x,0);fast.g.destroy();
});
test('同一组合只和最近的正确邻块配对,较重组合运动更小',()=>{
const {g,a,b}=pair(40);const c=g.createGroup([2],{tx:138,ty:g.pose(b).ty,angle:0});g.attractNearby();assert.equal(g.magnetPairs,1);assert.equal(a.body.force.x,0);assert.ok(b.body.force.x>0&&c.body.force.x<0);g.destroy();
const mass=pair();M.Body.setMass(mass.a.body,mass.b.body.mass*5);mass.g.attractNearby();assert.ok(Math.abs(mass.a.body.force.x/mass.a.body.mass)<Math.abs(mass.b.body.force.x/mass.b.body.mass));mass.g.destroy();
});
test('暂停和红线上方的预备块不受牵引',()=>{
const paused=pair();paused.g.status='paused';paused.g.attractNearby();assert.equal(paused.a.body.force.x,0);paused.g.destroy();
const g=new Game(level,420,560,4,()=>{},()=>.5,1);g.start();assert.ok(g.pending);g.attractNearby();assert.equal(g.magnetPairs,0);assert.equal(g.groups.length,0);g.destroy();
});