feat(levels): give every level an opening worth watching
The chain locks all four of its pieces at the opening by construction, and the pieces grown around it are mostly locked too, so a level built from it hands a player two rim pieces and a third of a second of animation before any thinking starts. Measured across the 235-level pool: median two tappable pieces at the opening, and the best departure available plays for 0.57s. Growth now reserves a couple of slots for showcase pieces — tappable at the opening, with a route long enough to read as a journey and short enough to stay under the animation ceiling. Median opening choices go 2 to 3 and the best opening show 0.72s to 1.12s, without shortcutting the lock: each candidate is still put through the solver. Rotation quota is gone from the board. Turning is free and it is what the game is about, so depth is grown rather than capped; what is gated is whether each turn pays out, whether pieces swing between hopeless and trivial, and whether there is a show up front. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,8 +72,7 @@ const STATUS = {
|
||||
done: ['完成', 'good'], doing: ['进行中', 'live'], todo: ['待办', 'idle'], blocked: ['受阻', 'bad'],
|
||||
};
|
||||
|
||||
const quota = board.targets.rotationQuota;
|
||||
const quotaRows = Object.entries(quota).map(([r, want]) => ({ r, want, have: pool.rot[r] || 0 }));
|
||||
const depthRows = Object.entries(pool.rot).sort((a, b) => Number(a[0]) - Number(b[0]));
|
||||
|
||||
const html = `<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
@@ -191,9 +190,10 @@ footer{margin-top:56px;padding-top:20px;border-top:1px solid var(--rule);color:v
|
||||
</div>
|
||||
|
||||
<div class="scroll"><table>
|
||||
<thead><tr><th>旋转数</th><th class="n">目标关数</th><th class="n">现有</th><th>缺口</th></tr></thead>
|
||||
<thead><tr><th>最少旋转数</th><th class="n">候选关数</th><th>说明</th></tr></thead>
|
||||
<tbody>
|
||||
${quotaRows.map(q => `<tr><td>${q.r} 转</td><td class="n">${q.want}</td><td class="n">${q.have}</td><td>${q.have >= q.want ? '<span class="tag good">已满足</span>' : `<span class="tag ${q.have ? 'live' : 'idle'}">还差 ${q.want - q.have}</span>`}</td></tr>`).join('\n')}
|
||||
${depthRows.map(([r, n]) => `<tr><td>${r} 转</td><td class="n">${n}</td><td class="sub">${Number(r) <= 3 ? '浅' : Number(r) <= 5 ? '中' : '深'}</td></tr>`).join('\n')}
|
||||
${depthRows.length <= 1 ? '<tr><td colspan="3" class="sub">旋转深度没有梯度——生成器把最少旋转写死了,这正是「太简单」的根因</td></tr>' : ''}
|
||||
</tbody></table></div>
|
||||
<p class="sub">路线家族分布:${Object.entries(pool.families).map(([k, v]) => `${esc(k)} ×${v}`).join(' · ') || '—'} 终局可走朝向分布:${JSON.stringify(pool.endgame)}</p>
|
||||
|
||||
@@ -205,7 +205,7 @@ ${board.definition.rules.map(r => `<li><b>${esc(r.k)}</b>:${esc(r.v)}<span cla
|
||||
<div class="scroll"><table>
|
||||
<thead><tr><th>关号区间</th><th>旋转数</th><th>目标 difficulty 评分</th></tr></thead>
|
||||
<tbody>
|
||||
${board.targets.difficultyCurve.map(b => `<tr><td>${esc(b.band)}</td><td>${esc(b.rot)}</td><td class="mono">${esc(b.difficulty)}</td></tr>`).join('\n')}
|
||||
${board.targets.rotationDepth.map(b => `<tr><td>${esc(b.band)}</td><td>${esc(b.rot)}</td><td class="mono">${esc(b.difficulty)}</td></tr>`).join('\n')}
|
||||
</tbody></table></div>
|
||||
|
||||
<h2><span class="num">C</span>任务</h2>
|
||||
|
||||
Reference in New Issue
Block a user