纠正仓库内容为衍生项目,标明 campaign-200-r2 最新版
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
from pathlib import Path
|
||||
root=Path(r'G:\项目\NumberSwipe-Variants')
|
||||
p=root/'tests/rules.test.mjs';s=p.read_text(encoding='utf-8-sig')
|
||||
s=s.replace('canAppend,violations,hint,assertStructure}', 'canAppend,violations,hint,assertStructure,doorOpen,directionAt}')
|
||||
s=s.replace("const straight=(a.x===b.x&&b.x===d.x)||(a.y===b.y&&b.y===d.y);if(straight!==(c.direction==='straight'))return false;", "const side=x=>x.x<b.x?'l':x.x>b.x?'r':x.y<b.y?'u':'d';if([side(a),side(d)].sort().join('')!==c.direction)return false;")
|
||||
s=s.replace(" for(const g of level.gates||[])", " for(const w of level.walls||[])for(let i=1;i<p.length;i++)if(w.includes(p[i-1])&&w.includes(p[i]))return false;\n for(const door of level.doors||[])for(let i=1;i<p.length;i++)if(door.edge.includes(p[i-1])&&door.edge.includes(p[i])&&!(Boolean(door.initialOpen)!==Boolean(i%2)))return false;\n for(const g of level.gates||[])")
|
||||
s=s.replace('all 56 author','all 40 author').replace('assert.equal(n,56)','assert.equal(n,40)')
|
||||
a=s.index("test('relative difference");b=s.index("test('alternating classes",a)
|
||||
s=s[:a]+'''test('six exact channel orientations are reversible and reject other ports',()=>{
|
||||
const coords={l:[-1,0],r:[1,0],u:[0,-1],d:[0,1]};for(const kind of ['lr','du','ru','dr','dl','lu']){const cells=[{id:'center',x:0,y:0,direction:kind},...Object.entries(coords).map(([id,[x,y]])=>({id,x,y}))];const l={mode:'direction',geometry:'square',cells};const [a,b]=kind;assert.equal(violations(l,[a,'center',b],{complete:false}).length,0);assert.equal(violations(l,[b,'center',a],{complete:false}).length,0);assert.equal(violations(l,[a,'center'],{complete:false}).length,0);const wrong=Object.keys(coords).find(k=>!kind.includes(k));assert.ok(violations(l,[a,'center',wrong],{complete:false}).length);assert.ok(violations(l,['center',a],{complete:false}).length);assert.ok(violations(l,[a,'center'],{complete:true}).length);}
|
||||
});
|
||||
test('permanent walls block both directions and never react to visited count',()=>{const l={mode:'walls',geometry:'square',cells:[{id:'a',x:0,y:0},{id:'b',x:1,y:0},{id:'c',x:0,y:1},{id:'d',x:1,y:1}],walls:[['a','b']]};assert.equal(canAppend(l,['a'],'b'),false);assert.equal(canAppend(l,['b'],'a'),false);assert.equal(canAppend(l,['c','d','b'],'a'),false);assert.ok(violations(l,['a','b']).length);});
|
||||
test('step door starts closed, includes start, toggles and restores after undo',()=>{const d={edge:['b','d'],initialOpen:false};assert.deepEqual([0,1,2,3,4].map(t=>doorOpen(d,t)),[false,true,false,true,false]);const l={mode:'rhythm-door',geometry:'square',cells:[{id:'a',x:0,y:0},{id:'b',x:1,y:0},{id:'c',x:0,y:1},{id:'d',x:1,y:1}],doors:[d]};assert.equal(canAppend(l,['a','b'],'d'),false);assert.equal(canAppend(l,['a','c','d'],'b'),true);assert.equal(canAppend(l,['b'],'d'),true);assert.equal(doorOpen(d,0),false);});
|
||||
test('dynamic connectivity retains future door opportunities and static walls cannot replace it',()=>{const pack=packs.find(p=>p.mode==='rhythm-door');for(const l of pack.levels){assert.deepEqual(solve(l,{prune:true}),solve(l,{prune:false}));const copy=structuredClone(l);copy.walls=copy.doors.map(d=>d.edge);delete copy.doors;assert.notEqual(solve(copy).length,1);}});
|
||||
test('hex fusion needs each permanent wall and the alternating rule',()=>{const pack=packs.find(p=>p.mode==='hex-alternation');assert.ok(pack.levels[6].cells.some(c=>c.r===2));for(const l of pack.levels){assert.ok(l.walls.length);assert.ok(solve(l,{omit:'alternation'}).length>=2);for(let i=0;i<l.walls.length;i++)assert.ok(solve(l,{omit:'wall:'+i}).length>=2);}});
|
||||
''' +s[b:]
|
||||
p.write_text(s,encoding='utf-8')
|
||||
p=root/'tests/offline-ui.test.mjs';s=p.read_text(encoding='utf-8-sig');a=s.index("test('fast drag");s=s[:a]+'''test('fast drag samples crossed cells and preserves prefix after release',()=>{const ui=boot('walls'),p=solve(JSON.parse(fs.readFileSync(new URL('../modes/walls/levels.json',import.meta.url),'utf8')).levels[0])[0];const start=ui.snapshot().centers[p[0]],next=ui.snapshot().centers[p[1]];ui.canvas.handlers.pointerdown({preventDefault(){},pointerId:1,clientX:start[0],clientY:start[1]});ui.canvas.handlers.pointermove({preventDefault(){},clientX:next[0],clientY:next[1]});ui.canvas.handlers.pointerup({});assert.deepEqual(ui.snapshot().path,p.slice(0,2));});
|
||||
test('step door UI shows current and next state and undo/restart restore it',()=>{const ui=boot('rhythm-door'),l=JSON.parse(fs.readFileSync(new URL('../modes/rhythm-door/levels.json',import.meta.url),'utf8')).levels[0],p=solve(l)[0];assert.deepEqual(ui.snapshot().doors,[false]);assert.match(ui.get('constraints').children[0].textContent,/门关.*就开/);ui.press(p[0]);assert.deepEqual(ui.snapshot().doors,[true]);assert.match(ui.get('constraints').children[0].textContent,/门开.*就关/);ui.press(p[1]);assert.deepEqual(ui.snapshot().doors,[false]);ui.get('undo').click();assert.deepEqual(ui.snapshot().doors,[true]);ui.get('restart').click();assert.deepEqual(ui.snapshot().doors,[false]);});
|
||||
test('alternation keeps blue/orange fill after visits and uses clear colour legend',()=>{for(const mode of ['block-alternation','hex-alternation']){const ui=boot(mode),l=JSON.parse(fs.readFileSync(new URL('../modes/'+mode+'/levels.json',import.meta.url),'utf8')).levels[0],p=solve(l)[0];const colours=()=>ui.draws.filter(d=>d.kind==='fill').map(d=>d.color);assert.ok(colours().includes('#64acf3'));assert.ok(colours().includes('#ffae55'));ui.press(p[0]);ui.press(p[1]);assert.ok(colours().includes('#64acf3'));assert.ok(colours().includes('#ffae55'));assert.match(ui.get('constraints').children[0].textContent,/蓝.*橙.*换颜色/);}});
|
||||
test('retired modes are absent from the active launcher',()=>{const html=fs.readFileSync(new URL('../index.html',import.meta.url),'utf8');for(const id of ['relative','order','window','gates'])assert.ok(!html.includes('modes/'+id+'/'));assert.ok(html.includes('modes/walls/'));assert.ok(html.includes('modes/rhythm-door/'));});
|
||||
''';p.write_text(s,encoding='utf-8')
|
||||
p=root/'tools/validate.mjs';s=p.read_text(encoding='utf-8-sig').replace('7 个玩法','5 个玩法');p.write_text(s,encoding='utf-8')
|
||||
Reference in New Issue
Block a user