31 lines
6.3 KiB
Python
31 lines
6.3 KiB
Python
from pathlib import Path
|
|
root=Path(r'G:\项目\NumberSwipe-Variants')
|
|
p=root/'tools/ui-template.mjs';s=p.read_text(encoding='utf-8-sig')
|
|
s=s.replace('canAppend,hint}', 'canAppend,hint,doorOpen,directionNames}')
|
|
s=s.replace("for(const c of level.cells)if(c.direction)add(c.direction==='straight'?'↔ 必须直行':'↱ 必须转弯',[c.id]);", "for(const c of level.cells)if(c.direction)add(directionNames[c.direction]+' · 可反向',[c.id]);")
|
|
s=s.replace("add('○ → △ → ○ · 每步换一类',[]);", "add('🔵 蓝 → 🟠 橙 → 🔵 蓝 · 每步换颜色',[]);")
|
|
s=s.replace(" for(let i=0;i<(level.gates||[]).length;i++)add", " for(let i=0;i<(level.walls||[]).length;i++)add('黑黄墙 · 永久封闭',level.walls[i]);\n for(const d of level.doors||[])add(doorOpen(d,path.length)?'门开 · 再落一格就关':'门关 · 再落一格就开',d.edge);\n for(let i=0;i<(level.gates||[]).length;i++)add")
|
|
s=s.replace("ctx.fillStyle=badIds.has(c.id)?'#ffe0dc':visited?'#ddd8ff':c.category==='circle'?'#e4f3ff':c.category==='triangle'?'#fff0d4':'#f0f0f6';", "ctx.fillStyle=c.category==='circle'?'#64acf3':c.category==='triangle'?'#ffae55':badIds.has(c.id)?'#ffe0dc':visited?'#ddd8ff':'#f0f0f6';")
|
|
s=s.replace(" for(let i=0;i<(level.gates||[]).length;i++){const gate=", " for(const edge of level.walls||[])drawBarrier(edge,'wall');\n for(const d of level.doors||[])drawBarrier(d.edge,doorOpen(d,path.length)?'open':'closed');\n for(let i=0;i<(level.gates||[]).length;i++){const gate=")
|
|
s=s.replace("if(c.direction)symbol=c.direction==='straight'?'↔':'↱';", "if(c.direction)symbol='';")
|
|
s=s.replace(" ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillStyle=", " if(c.direction)drawChannel(c.direction,x,y-(step?font*.72:0),Math.min(unit*.28,step?font*.4:20));\n ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillStyle=")
|
|
s=s.replace(" if(bad.length)setStatus", " if(level.doors?.length)renderConstraints();\n if(bad.length)setStatus")
|
|
a=s.index('function inside(')
|
|
s=s[:a]+'''function drawChannel(kind,x,y,r){const vector={l:[-1,0],r:[1,0],u:[0,-1],d:[0,1]};const [a,b]=kind.split('').map(k=>vector[k]);ctx.beginPath();ctx.moveTo(x+a[0]*r,y+a[1]*r);ctx.lineTo(x,y);ctx.lineTo(x+b[0]*r,y+b[1]*r);ctx.lineCap='round';ctx.lineJoin='round';ctx.lineWidth=9;ctx.strokeStyle='#c1daf7';ctx.stroke();ctx.lineWidth=4;ctx.strokeStyle='#15497b';ctx.stroke();}
|
|
function drawBarrier(edge,kind){const left=polygons.filter(p=>p.id===edge[0]),right=polygons.filter(p=>p.id===edge[1]);let common=null;for(const a of left)for(const b of right)for(let i=0;i<a.p.length;i++)for(let j=0;j<b.p.length;j++){const p=a.p[i],q=a.p[(i+1)%a.p.length],r=b.p[j],t=b.p[(j+1)%b.p.length];if(Math.hypot(p[0]-t[0],p[1]-t[1])<.01&&Math.hypot(q[0]-r[0],q[1]-r[1])<.01)common=[p,q];}if(!common)return;const [a,b]=common;const point=f=>[a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f];ctx.lineCap='butt';ctx.lineWidth=9;ctx.strokeStyle=kind==='open'?'#23895f':kind==='wall'?'#272638':'#aa4d25';ctx.beginPath();if(kind==='open'){ctx.moveTo(...point(.05));ctx.lineTo(...point(.26));ctx.moveTo(...point(.74));ctx.lineTo(...point(.95));}else{ctx.moveTo(...point(.05));ctx.lineTo(...point(.95));}ctx.stroke();if(kind==='wall'){ctx.lineWidth=4;ctx.strokeStyle='#ffc542';ctx.setLineDash([5,4]);ctx.beginPath();ctx.moveTo(...point(.05));ctx.lineTo(...point(.95));ctx.stroke();ctx.setLineDash([]);}if(kind!=='wall'){const [x,y]=point(.5);ctx.font='700 11px system-ui';ctx.textAlign='center';ctx.fillStyle=kind==='open'?'#12623f':'#993b1e';ctx.fillText(kind==='open'?'开':'关',x+10,y-8);}}
|
|
''' +s[a:]
|
|
s=s.replace("markError(id,path.length?'此处类别相同或门尚未打开。':'请从数字 1 开始。');", "markError(id,path.length?(level.walls?.some(e=>e.includes(path.at(-1))&&e.includes(id))?'这是永久墙,不能穿过。':level.doors?.some(d=>d.edge.includes(path.at(-1))&&d.edge.includes(id))?'门现在关闭;绕行落格后会切换。':'同色格不能连续经过,请换另一种颜色。'):'请从数字 1 开始。');")
|
|
s=s.replace("openedGates:(level.gates||[]).map(g=>path.includes(g.switchCell))", "openedGates:(level.gates||[]).map(g=>path.includes(g.switchCell)),doors:(level.doors||[]).map(d=>doorOpen(d,path.length))")
|
|
p.write_text(s,encoding='utf-8')
|
|
p=root/'tools/build.mjs';s=p.read_text(encoding='utf-8-sig').replace('Built 7 standalone pages + index.','Built 5 standalone pages + index.').replace('一笔路径,七种推理','一笔路径,五种推理').replace('56 个机制验证候选关','40 个机制验证候选关').replace('门和类别限制会阻止移动','永久墙、关闭的门和同色移动会阻止移动')
|
|
s=s.replace("${esc(d.rule)}</p></a>", "${esc(d.rule)}</p></a>")
|
|
s=s.replace('</div><footer>40 个', '</div><details><summary>设计说明与答案图</summary>${definitions.map(d=>`<p><a href="modes/${d.id}/DESIGN.html">${d.title} · 设计评审</a></p>`).join(\'\')}</details><footer>40 个')
|
|
p.write_text(s,encoding='utf-8')
|
|
p=root/'tools/design-pages.mjs';s=p.read_text(encoding='utf-8-sig')
|
|
s=s.replace("import {units,constraints}", "import {units,constraints,directionNames}")
|
|
s=s.replace("c.category==='circle'?'#e4f3ff':c.category==='triangle'?'#fff0d4'", "c.category==='circle'?'#64acf3':c.category==='triangle'?'#ffae55'")
|
|
s=s.replace("c.direction==='straight'?'↔':c.direction==='turn'?'↱':''", "c.direction?({lr:'─',du:'│',ru:'└',dr:'┌',dl:'┐',lu:'┘'})[c.direction]:''")
|
|
s=s.replace("for(let i=0;i<(l.gates||[]).length;i++){", "for(const item of [...(l.walls||[]).map(edge=>({edge,kind:'wall'})),...(l.doors||[]).map(d=>({edge:d.edge,kind:'door'}))]){const [a,b]=item.edge.map(id=>tr(centers.get(id))),x=(a[0]+b[0])/2,y=(a[1]+b[1])/2,angle=Math.atan2(b[1]-a[1],b[0]-a[0])*180/Math.PI;svg+=`<line x1=\"${x}\" y1=\"${y-s*.38}\" x2=\"${x}\" y2=\"${y+s*.38}\" stroke=\"${item.kind==='wall'?'#272638':'#aa4d25'}\" stroke-width=\"8\" transform=\"rotate(${angle} ${x} ${y})\"/>`;if(item.kind==='wall')svg+=`<line x1=\"${x}\" y1=\"${y-s*.38}\" x2=\"${x}\" y2=\"${y+s*.38}\" stroke=\"#ffc542\" stroke-width=\"4\" stroke-dasharray=\"5 4\" transform=\"rotate(${angle} ${x} ${y})\"/>`;else svg+=`<text x=\"${x+8}\" y=\"${y-8}\" font-size=\"12\">步进门</text>`;}for(let i=0;i<(l.gates||[]).length;i++){")
|
|
s=s.replace('Generated 56 original boards, 56 solutions and 7 design review pages.','Generated 40 original boards, 40 solutions and 5 design review pages.')
|
|
p.write_text(s,encoding='utf-8')
|