- 玩法一 数字一笔:规则库、求解器、26 关、竖屏触摸 Web 原型、测试 - 玩法二 连连气球:连消畅玩版核心、Web 原型、Cocos 球槽组件与导出脚本 - 玩法三 六边一笔:规则库、求解器、10 关 + 转墙实验包、Web 原型、测试 - 产品文档、UI 设计规范、各玩法 GDD / HANDOFF - 文档移除全部外部参考作引用;删除玩法二 v0 旧稿
81 lines
68 KiB
HTML
81 lines
68 KiB
HTML
<!doctype html>
|
|
<html lang="zh-CN" data-unlock-all="true">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta
|
|
name="viewport"
|
|
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
|
|
/>
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="theme-color" content="#ffffff" />
|
|
<title>数字一笔 · 试玩版</title>
|
|
<style>:root{--bg: #ffffff;--bg-app: #f2f2f6;--surface-2: #f3f3f7;--cell: #e6e7ec;--line: #e1e2ea;--ink: #23243a;--ink-2: #6b6d80;--ink-3: #a3a5b5;--primary: #6558f5;--primary-bright: #7d72ff;--primary-soft: #eceafe;--on-primary: #ffffff;--danger: #e5484d;--danger-soft: #fdecec;--hint: #f5a524;--hint-soft: #fef3dd;--clue-ring: #23243a;--overlay: rgba(35, 36, 58, .92);--shadow-primary: 0 6px 18px rgba(101, 88, 245, .28);--shadow-primary-pressed: 0 3px 10px rgba(101, 88, 245, .22);--shadow-frame: 0 20px 60px rgba(20, 20, 40, .14);--font: ui-rounded, "SF Pro Rounded", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, -apple-system, "Segoe UI", sans-serif;--fs-display: 34px;--fs-title: 22px;--fs-heading: 17px;--fs-body: 15px;--fs-label: 14px;--fs-caption: 13px;--fs-micro: 12px;--r-sm: 10px;--r-md: 14px;--r-lg: 18px;--r-xl: 24px;--r-pill: 999px;--sp-1: 4px;--sp-2: 8px;--sp-3: 12px;--sp-4: 16px;--sp-5: 20px;--sp-6: 24px;--sp-7: 28px;--t-fast: .12s;--t-base: .2s;--t-slow: .32s;--t-hold: .5s;--ease-out: cubic-bezier(.22, 1, .36, 1);--ease-in: cubic-bezier(.4, 0, 1, 1);--ease-in-out: cubic-bezier(.65, 0, .35, 1);--ease-spring: cubic-bezier(.34, 1.56, .64, 1);--tap: 44px;--safe-top: env(safe-area-inset-top, 0px);--safe-bottom: env(safe-area-inset-bottom, 0px);--safe-left: env(safe-area-inset-left, 0px);--safe-right: env(safe-area-inset-right, 0px)}*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}html,body{margin:0;height:100%;background:var(--bg-app);color:var(--ink);font-family:var(--font);font-size:var(--fs-body);line-height:1.3;-webkit-font-smoothing:antialiased;font-variant-numeric:tabular-nums;user-select:none;-webkit-user-select:none;touch-action:manipulation;overscroll-behavior:none}#app{position:relative;margin:0 auto;width:100%;max-width:480px;height:100vh;height:100dvh;background:var(--bg);overflow:hidden}.screen{position:absolute;inset:0;display:flex;flex-direction:column;padding:calc(var(--safe-top) + var(--sp-3)) calc(var(--safe-right) + var(--sp-5)) calc(var(--safe-bottom) + var(--sp-4)) calc(var(--safe-left) + var(--sp-5))}.screen.hidden{display:none}.screen.enter{animation:screen-in var(--t-base) var(--ease-out) both}button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;-webkit-touch-callout:none;transition:transform var(--t-fast) var(--ease-out),background-color var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out),opacity var(--t-fast) var(--ease-out)}button:active{transform:scale(.97)}button:focus-visible{outline:3px solid var(--primary);outline-offset:2px}.select-header{padding:var(--sp-7) var(--sp-1) var(--sp-2)}.select-header h1{margin:0;font-size:var(--fs-display);font-weight:800;letter-spacing:.02em;line-height:1.15}.select-header .sub{margin:var(--sp-2) 0 0;color:var(--ink-2);font-size:var(--fs-body);font-weight:500}.overall{display:flex;align-items:center;gap:var(--sp-3);margin-top:var(--sp-4)}.overall-bar{flex:1;height:6px;border-radius:var(--r-pill);background:var(--cell);overflow:hidden}.overall-bar i{display:block;height:100%;width:0;border-radius:var(--r-pill);background:var(--primary);transition:width var(--t-slow) var(--ease-out)}.overall-text{color:var(--ink-3);font-size:var(--fs-caption);font-weight:600;min-width:52px;text-align:right}.pack-list{flex:1;overflow-y:auto;margin-top:var(--sp-3);padding-bottom:var(--sp-5);min-height:0;-webkit-mask-image:linear-gradient(to bottom,transparent,#000 12px,#000 calc(100% - 20px),transparent);mask-image:linear-gradient(to bottom,transparent,#000 12px,#000 calc(100% - 20px),transparent)}.pack{margin-top:var(--sp-7)}.pack-list>.pack:first-child{margin-top:var(--sp-2)}.pack-title{display:flex;align-items:baseline;justify-content:space-between;padding:0 var(--sp-1) var(--sp-3);font-size:var(--fs-heading);font-weight:700}.pack-progress{color:var(--ink-3);font-size:var(--fs-label);font-weight:600}.pack.done .pack-progress{color:var(--primary)}.level-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-3)}.level-tile{position:relative;aspect-ratio:1;border-radius:var(--r-md);background:var(--cell);color:var(--ink);font-size:20px;font-weight:700;display:flex;align-items:center;justify-content:center}.level-tile:active{transform:scale(.94)}.level-tile.cleared{background:var(--primary);color:var(--on-primary)}.level-tile.cleared:after{content:"";position:absolute;right:8px;top:6px;width:4px;height:8px;border:solid rgba(255,255,255,.9);border-width:0 2px 2px 0;transform:rotate(45deg)}.level-tile.current{box-shadow:inset 0 0 0 3px var(--primary);background:var(--primary-soft);color:var(--primary);animation:breathe 2.4s var(--ease-in-out) infinite}.level-tile.locked{color:var(--ink-3);background:var(--surface-2)}.level-tile.locked:before{content:"";width:10px;height:12px;border:2px solid var(--ink-3);border-radius:3px;border-top-width:3px}.level-tile.locked span{display:none}.level-tile.shake{animation:shake var(--t-slow) var(--ease-out)}.primary{margin-top:auto;height:54px;border-radius:var(--r-lg);background:var(--primary);color:var(--on-primary);font-size:var(--fs-heading);font-weight:700;letter-spacing:.02em;box-shadow:var(--shadow-primary)}.primary:active{transform:scale(.98);box-shadow:var(--shadow-primary-pressed)}.select-footer{display:flex;justify-content:center;gap:var(--sp-2);padding-top:var(--sp-4)}.chip{height:34px;padding:0 var(--sp-4);border-radius:var(--r-pill);background:var(--surface-2);color:var(--ink-2);font-size:var(--fs-caption);font-weight:600}.chip.on{background:var(--primary-soft);color:var(--primary)}.chip.danger{color:var(--danger)}.topbar{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;height:52px}.topbar .icon{justify-self:start;width:var(--tap);height:var(--tap);display:flex;align-items:center;justify-content:center;color:var(--ink-2);border-radius:var(--r-pill);margin-left:-8px}.topbar .icon:active{background:var(--surface-2)}.level-info{text-align:center;line-height:1.1}.level-title{font-size:var(--fs-title);font-weight:800;letter-spacing:.02em}.level-sub{margin-top:3px;color:var(--ink-3);font-size:var(--fs-micro);font-weight:600;letter-spacing:.04em;white-space:nowrap}.remaining{justify-self:end;display:inline-flex;align-items:center;gap:5px;height:32px;padding:0 var(--sp-3) 0 10px;border-radius:var(--r-pill);background:var(--surface-2);color:var(--ink-2);font-size:var(--fs-label);font-weight:700;min-width:52px;justify-content:center;transition:background-color var(--t-base) var(--ease-out),color var(--t-base) var(--ease-out)}.remaining-icon{color:var(--ink-3);transition:color var(--t-base) var(--ease-out)}.remaining-icon.check{display:none}.remaining.bump{animation:bump var(--t-base) var(--ease-spring)}.remaining.done{background:var(--primary-soft);color:var(--primary)}.remaining.done .remaining-icon{color:var(--primary)}.remaining.done .remaining-icon.tile{display:none}.remaining.done .remaining-icon.check{display:block}.level-progress{display:flex;gap:3px;height:4px;margin:var(--sp-2) var(--sp-1) 0}.level-progress i{flex:1;border-radius:2px;background:var(--cell);transition:background-color var(--t-slow) var(--ease-out),opacity var(--t-slow) var(--ease-out)}.level-progress i.cleared{background:var(--primary);opacity:.4}.level-progress i.current{background:var(--primary);opacity:1}.caption{height:36px;margin-top:var(--sp-2);display:flex;align-items:center;justify-content:center;color:var(--ink-2);font-size:var(--fs-body);font-weight:500;text-align:center;transition:opacity var(--t-base) var(--ease-out)}.caption:empty{opacity:0}.board-wrap{flex:1;min-height:0;position:relative}#board{position:absolute;inset:0;width:100%;height:100%;touch-action:none;display:block}.bottombar{display:flex;justify-content:center;gap:var(--sp-3);padding-top:var(--sp-3)}.gesture-help{margin:0;padding-top:var(--sp-2);color:var(--ink-2);font-size:var(--fs-caption);text-align:center}.action{flex:1;max-width:170px;height:56px;border-radius:var(--r-lg);background:var(--surface-2);color:var(--ink);font-size:var(--fs-body);font-weight:700;display:flex;align-items:center;justify-content:center;gap:var(--sp-1)}.action svg{color:var(--ink-2)}.action:active{background:var(--cell)}.action.pulse{animation:pulse .9s var(--ease-in-out) infinite}.action:disabled{opacity:.4;pointer-events:none}.toast{position:absolute;left:50%;bottom:calc(var(--safe-bottom) + 128px);transform:translate(-50%,8px);padding:10px var(--sp-4);border-radius:var(--r-md);background:var(--overlay);color:#fff;font-size:var(--fs-label);font-weight:600;width:max-content;max-width:calc(100% - 40px);text-align:center;opacity:0;pointer-events:none;transition:opacity var(--t-base) var(--ease-out),transform var(--t-base) var(--ease-out)}.toast.show{opacity:1;transform:translate(-50%)}@keyframes screen-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes shake{0%,to{transform:translate(0)}25%{transform:translate(-5px)}50%{transform:translate(5px)}75%{transform:translate(-3px)}}@keyframes pulse{0%,to{box-shadow:0 0 #f5a52400}50%{box-shadow:0 0 0 5px #f5a52459}}@keyframes bump{0%{transform:scale(1)}40%{transform:scale(1.14)}to{transform:scale(1)}}@keyframes breathe{0%,to{box-shadow:inset 0 0 0 3px var(--primary),0 0 #6558f500}50%{box-shadow:inset 0 0 0 3px var(--primary),0 0 0 6px #6558f529}}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation:none!important;transition:none!important}}@media (min-width: 520px){body{padding:var(--sp-6) 0}#app{height:calc(100vh - 48px);height:calc(100dvh - 48px);border-radius:28px;box-shadow:var(--shadow-frame)}}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<!-- 选关 -->
|
|
<section id="screen-select" class="screen">
|
|
<header class="select-header">
|
|
<h1>数字一笔</h1>
|
|
<p class="sub">全部关卡开放,自由选关试玩</p>
|
|
<div class="overall" aria-label="总进度">
|
|
<div class="overall-bar"><i id="overall-fill"></i></div>
|
|
<span id="overall-text" class="overall-text">0 / 0</span>
|
|
</div>
|
|
</header>
|
|
<div id="pack-list" class="pack-list"></div>
|
|
<button id="btn-continue" class="primary">继续</button>
|
|
<footer class="select-footer">
|
|
<button id="btn-sound" class="chip">音效</button>
|
|
<button id="btn-haptic" class="chip">振动</button>
|
|
<button id="btn-reset-progress" class="chip danger">重置进度</button>
|
|
</footer>
|
|
</section>
|
|
|
|
<!-- 对局 -->
|
|
<section id="screen-play" class="screen hidden">
|
|
<header class="topbar">
|
|
<button id="btn-back" class="icon" aria-label="返回选关">
|
|
<svg viewBox="0 0 24 24" width="26" height="26" aria-hidden="true"><path d="M15 5l-7 7 7 7" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
</button>
|
|
<div class="level-info">
|
|
<div id="level-title" class="level-title">1-1</div>
|
|
<div id="level-sub" class="level-sub">入门 · 第 1 关</div>
|
|
</div>
|
|
<div id="remaining" class="remaining" aria-live="polite" aria-label="剩余格数">
|
|
<svg class="remaining-icon tile" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="4.5" fill="none" stroke="currentColor" stroke-width="2.4"/></svg>
|
|
<svg class="remaining-icon check" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7.5" fill="none" stroke="currentColor" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
<span id="remaining-n">0</span>
|
|
</div>
|
|
</header>
|
|
<div id="level-progress" class="level-progress" aria-hidden="true"></div>
|
|
<div id="caption" class="caption"></div>
|
|
<div id="board-wrap" class="board-wrap">
|
|
<canvas id="board"></canvas>
|
|
</div>
|
|
<p class="gesture-help">按住滑动连线 · 点已走格回退</p>
|
|
<footer class="bottombar">
|
|
<button id="btn-restart" class="action">
|
|
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M4 12a8 8 0 1 0 2.5-5.8" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/><path d="M4 4v5h5" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
<span>重开</span>
|
|
</button>
|
|
<button id="btn-hint" class="action">
|
|
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M9 18h6M10 21h4M12 3a6 6 0 0 0-3.6 10.8c.6.5 1 1.2 1.1 2.2h5c.1-1 .5-1.7 1.1-2.2A6 6 0 0 0 12 3z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
<span>补数字</span>
|
|
</button>
|
|
<button id="btn-route-hint" class="action">
|
|
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true"><path d="M5 19v-7a4 4 0 0 1 4-4h10m-4-4 4 4-4 4" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
<span>指路</span>
|
|
</button>
|
|
</footer>
|
|
</section>
|
|
<div id="toast" class="toast" role="status"></div>
|
|
</div>
|
|
<script>"use strict";(()=>{var X={mode:"01-number-stroke",pack:1,title:"\u5165\u95E8",notes:"10 \u5173\u30021-1 \u5230 1-4 \u662F\u7AD6\u76F4\u5207\u9762\u5FC5\u987B\u624B\u505A\u7684\u5173\uFF1B\u6BCF\u5173\u53EA\u52A0\u4E00\u4E2A\u65CB\u94AE\u3002\u5750\u6807\u539F\u70B9\u5DE6\u4E0A\uFF0C\u5355\u4F4D\u683C\u3002\u5168\u90E8\u7ECF tools/validate.ts \u65AD\u8A00\u552F\u4E00\u89E3\u3002",levels:[{id:"1-1",teach:"\u6ED1\u52A8\uFF0C\u90BB\u683C\u81EA\u52A8\u51FA\u6B65\u53F7",caption:"\u4ECE 1 \u5F00\u59CB\uFF0C\u6ED1\u5230\u65C1\u8FB9\u7684\u683C",cells:[{id:"a",x:0,y:0,w:1,h:1,clue:1},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1}]},{id:"1-2",teach:"\u5FC5\u987B\u8D70\u5B8C\u6240\u6709\u683C",caption:"\u8D70\u5B8C\u6BCF\u4E00\u683C\uFF0C\u6570\u5B57\u8981\u5BF9\u4E0A",cells:[{id:"a",x:0,y:0,w:1,h:1,clue:1},{id:"b",x:0,y:1,w:1,h:1},{id:"c",x:0,y:2,w:1,h:1},{id:"d",x:1,y:2,w:1,h:1,clue:4}]},{id:"1-3",teach:"\u8D70\u9519\u53EF\u4EE5\u9000\u3002\u5148\u5F80\u4E0B\u4F1A\u9519\u8FC7 3\u3002",caption:"\u8D70\u9519\u4E86\uFF0C\u70B9\u5DF2\u8D70\u683C\u5C31\u80FD\u9000\u56DE",cells:[{id:"start",x:0,y:0,w:1,h:1,clue:1},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1,clue:3},{id:"d",x:1,y:1,w:1,h:1},{id:"c",x:2,y:1,w:1,h:1}]},{id:"1-4",teach:"\u5927\u683C\u53EA\u7B97\u4E00\u6B65",caption:"\u5927\u683C\u4E5F\u53EA\u7B97\u4E00\u6B65",cells:[{id:"start",x:0,y:0,w:1,h:1,clue:1},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1},{id:"big",x:1,y:1,w:2,h:2,clue:3}]},{id:"1-5",teach:"\u4E2D\u6BB5\u7EBF\u7D22\u3002\u5FC5\u987B\u5148\u8D70\u5B8C\u9876\u884C\uFF0C4 \u624D\u843D\u5728\u53F3\u4E0A\u89D2\u3002",cells:[{id:"start",x:0,y:0,w:1,h:1,clue:1},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1},{id:"c",x:3,y:0,w:1,h:1,clue:4},{id:"d",x:2,y:1,w:1,h:1},{id:"e",x:3,y:1,w:1,h:1},{id:"f",x:2,y:2,w:1,h:1}]},{id:"1-6",teach:"\u7A7A\u6D1E\u3002\u4E2D\u95F4\u7F3A\u4E00\u683C\uFF0Ca \u4E0E f \u9694\u6D1E\u4E0D\u76F8\u90BB\uFF1B9 \u5728\u5DE6\u8FB9\uFF0C\u5FC5\u987B\u7ED5\u73AF\u4E00\u5708\u6700\u540E\u5230\u5B83\u3002\u5148\u5F80\u4E0B\u8D70\u4F1A\u628A 9 \u63D0\u524D\u8E29\u6210 3\u3002",cells:[{id:"s",x:1,y:0,w:1,h:1,clue:1},{id:"a",x:2,y:0,w:1,h:1},{id:"b",x:3,y:0,w:1,h:1},{id:"t",x:0,y:1,w:1,h:1,clue:9},{id:"c",x:1,y:1,w:1,h:1},{id:"d",x:3,y:1,w:1,h:1},{id:"e",x:1,y:2,w:1,h:1},{id:"f",x:2,y:2,w:1,h:1},{id:"g",x:3,y:2,w:1,h:1}]},{id:"1-7",teach:"\u5148\u63A8\u518D\u753B\u3002\u4E09\u5904\u5206\u53C9\uFF1Ab \u5904\u8981\u8D70 f \u624D\u80FD\u8BA9 e=4\uFF1Bk \u5904\u8981\u8D70 g \u624D\u80FD\u8BA9 g=8\uFF1Bg \u5904\u8981\u5148\u53D6 c\uFF0C\u5426\u5219 l \u88AB\u5B64\u7ACB\u3002",cells:[{id:"a",x:0,y:0,w:1,h:1,clue:1},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:0,y:1,w:1,h:1,clue:4},{id:"f",x:1,y:1,w:1,h:1},{id:"g",x:2,y:1,w:1,h:1,clue:8},{id:"h",x:3,y:1,w:1,h:1},{id:"i",x:0,y:2,w:1,h:1},{id:"j",x:1,y:2,w:1,h:1},{id:"k",x:2,y:2,w:1,h:1},{id:"l",x:3,y:2,w:1,h:1}]},{id:"1-8",teach:"2\xD72 \u5F53\u67A2\u7EBD\u3002B \u6709 6 \u4E2A\u51FA\u53E3\uFF0C\u4F46\u53EA\u80FD\u8FDB\u51FA\u5404\u4E00\u6B21\uFF1A\u4ECE B \u51FA\u53BB\u5FC5\u987B\u6311 c \u6216 d\uFF08\u8FDC\u89D2\uFF09\uFF0C\u6311 e/f/h/i \u90FD\u4F1A\u5B64\u7ACB\u4E00\u4FA7\u3002h=8 \u51B3\u5B9A\u987A\u65F6\u9488\u3002",cells:[{id:"a",x:1,y:0,w:1,h:1,clue:1},{id:"b",x:1,y:1,w:1,h:1},{id:"c",x:0,y:2,w:1,h:1},{id:"B",x:1,y:2,w:2,h:2},{id:"d",x:3,y:2,w:1,h:1},{id:"e",x:0,y:3,w:1,h:1},{id:"f",x:3,y:3,w:1,h:1},{id:"g",x:0,y:4,w:1,h:1},{id:"h",x:1,y:4,w:1,h:1,clue:8},{id:"i",x:2,y:4,w:1,h:1},{id:"j",x:3,y:4,w:1,h:1}]},{id:"1-9",teach:"\u6A2A\u957F\u6761\uFF0C\u51FA\u53E3\u5728\u957F\u8FB9\u4E0A\u3002b \u7D27\u6328\u7740 1 \u5374\u8981\u7B2C 6 \u6B65\u624D\u5230\uFF1A\u53EA\u80FD\u4ECE\u957F\u6761 H \u7684\u4E0B\u8FB9\u8FDB\u3001\u4E0A\u8FB9\u51FA\uFF08h\u2192H\u2192b\uFF09\uFF0C\u5148\u7ED5\u5DE6\u4E0B\u89D2\u3002",cells:[{id:"a",x:0,y:0,w:1,h:1,clue:1},{id:"b",x:1,y:0,w:1,h:1,clue:6},{id:"c",x:2,y:0,w:1,h:1},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:0,y:1,w:1,h:1},{id:"H",x:1,y:1,w:2,h:1},{id:"f",x:3,y:1,w:1,h:1},{id:"g",x:0,y:2,w:1,h:1},{id:"h",x:1,y:2,w:1,h:1},{id:"i",x:2,y:2,w:1,h:1},{id:"j",x:3,y:2,w:1,h:1}]},{id:"1-10",teach:"\u5C0F\u8003\uFF1A2\xD72 + \u7AD6\u957F\u6761 + \u7A7A\u6D1E\u3002\u9876\u884C\u76F4\u8D70\u5230 e \u53EA\u6709 5 \u6B65\uFF0Ce=6 \u8981\u6C42\u591A\u57AB\u4E00\u6B65\u2014\u2014\u4ECE b \u4E0B\u5230 B \u518D\u56DE c\uFF08a,b,B,c,d,e\uFF09\u3002\u4E4B\u540E\u7ED5\u53F3\u4E0B\u56DE\u5230\u5DE6\u4FA7\uFF0CV \u6536\u5C3E\u3002\u9677\u9631\uFF1Aa,V,B,c \u4E5F\u80FD\u8BA9 e=6\uFF0C\u4F46 b \u4F1A\u88AB\u5B64\u7ACB\u3002",cells:[{id:"a",x:0,y:0,w:1,h:1,clue:1},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:4,y:0,w:1,h:1,clue:6},{id:"V",x:0,y:1,w:1,h:2},{id:"B",x:1,y:1,w:2,h:2},{id:"f",x:4,y:1,w:1,h:1},{id:"g",x:3,y:2,w:1,h:1},{id:"h",x:4,y:2,w:1,h:1},{id:"i",x:0,y:3,w:1,h:1},{id:"j",x:1,y:3,w:1,h:1},{id:"k",x:2,y:3,w:1,h:1},{id:"l",x:3,y:3,w:1,h:1}]}]};var K={mode:"01-number-stroke",pack:2,title:"\u8FDB\u9636",notes:"10 \u5173\uFF0Ctools/generate.ts \u81EA\u52A8\u751F\u6210\uFF08seed=43\uFF09+ \u4EBA\u5DE5\u8FC7\u76EE\u300215+ \u683C\u3001\u4FC4\u7F57\u65AF\u65B9\u5757\u5F02\u5F62\u683C\u3001\u5F00\u5C40 5~7 \u6B65\u5185\u6709\u5F15\u5BFC\u7EBF\u7D22\u3001\u4E4B\u540E\u9760\u6B65\u53F7\u5DEE\u4E0A\u96BE\u5EA6\uFF0C\u90E8\u5206\u5173\u4E0D\u5E26\u7EBF\u7D22 1\u3002",levels:[{id:"2-1",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=16 \u591A\u5355\u4F4D\u683C=3(\u5F02\u5F622) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=230 \u7EBF\u7D22=1/7/14 \u6B65\u53F7\u5DEE=6/7/2 \u96BE\u5EA6\u5206=75.5\u3002\u4F5C\u8005\u89E3: d \u2192 c \u2192 b \u2192 a \u2192 e \u2192 A \u2192 f \u2192 B \u2192 g \u2192 C \u2192 j \u2192 m \u2192 l \u2192 i \u2192 h \u2192 k",cells:[{id:"A",x:0,y:0,w:2,h:3,shape:[[0,0],[0,1],[0,2],[1,2]]},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1},{id:"c",x:3,y:0,w:1,h:1},{id:"d",x:4,y:0,w:1,h:1,clue:1},{id:"e",x:1,y:1,w:1,h:1},{id:"B",x:2,y:1,w:3,h:2,shape:[[2,0],[1,0],[0,0],[1,1]]},{id:"f",x:2,y:2,w:1,h:1,clue:7},{id:"g",x:4,y:2,w:1,h:1},{id:"h",x:0,y:3,w:1,h:1},{id:"i",x:1,y:3,w:1,h:1,clue:14},{id:"j",x:2,y:3,w:1,h:1},{id:"C",x:3,y:3,w:2,h:2},{id:"k",x:0,y:4,w:1,h:1},{id:"l",x:1,y:4,w:1,h:1},{id:"m",x:2,y:4,w:1,h:1}]},{id:"2-2",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=14 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F621) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=296 \u7EBF\u7D22=1/4/12 \u6B65\u53F7\u5DEE=3/8/2 \u96BE\u5EA6\u5206=79.2\u3002\u4F5C\u8005\u89E3: e \u2192 d \u2192 h \u2192 i \u2192 j \u2192 k \u2192 l \u2192 B \u2192 b \u2192 a \u2192 A \u2192 c \u2192 g \u2192 f",cells:[{id:"A",x:0,y:0,w:3,h:3},{id:"a",x:3,y:0,w:1,h:1},{id:"b",x:4,y:0,w:1,h:1},{id:"B",x:3,y:1,w:2,h:3,shape:[[1,2],[1,1],[1,0],[0,0]]},{id:"c",x:3,y:2,w:1,h:1,clue:12},{id:"d",x:0,y:3,w:1,h:1},{id:"e",x:1,y:3,w:1,h:1,clue:1},{id:"f",x:2,y:3,w:1,h:1},{id:"g",x:3,y:3,w:1,h:1},{id:"h",x:0,y:4,w:1,h:1},{id:"i",x:1,y:4,w:1,h:1,clue:4},{id:"j",x:2,y:4,w:1,h:1},{id:"k",x:3,y:4,w:1,h:1},{id:"l",x:4,y:4,w:1,h:1}]},{id:"2-3",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=18 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F622) \u7A7A\u6D1E=1 \u65E0\u7EBF\u7D22\u8DEF\u5F84=600+ \u7EBF\u7D22=1/4/8/16 \u6B65\u53F7\u5DEE=3/4/8/2 \u96BE\u5EA6\u5206=82.5\u3002\u4F5C\u8005\u89E3: k \u2192 o \u2192 p \u2192 l \u2192 h \u2192 g \u2192 e \u2192 A \u2192 b \u2192 a \u2192 c \u2192 B \u2192 d \u2192 f \u2192 j \u2192 i \u2192 m \u2192 n",cells:[{id:"a",x:0,y:0,w:1,h:1},{id:"b",x:1,y:0,w:1,h:1},{id:"A",x:2,y:0,w:3,h:2,shape:[[0,0],[1,0],[2,0],[2,1]],clue:8},{id:"B",x:0,y:1,w:2,h:3,shape:[[0,1],[0,2],[1,0],[1,1]]},{id:"c",x:0,y:1,w:1,h:1},{id:"d",x:2,y:1,w:1,h:1},{id:"e",x:3,y:1,w:1,h:1},{id:"f",x:2,y:2,w:1,h:1},{id:"g",x:3,y:2,w:1,h:1},{id:"h",x:4,y:2,w:1,h:1},{id:"i",x:1,y:3,w:1,h:1,clue:16},{id:"j",x:2,y:3,w:1,h:1},{id:"k",x:3,y:3,w:1,h:1,clue:1},{id:"l",x:4,y:3,w:1,h:1,clue:4},{id:"m",x:1,y:4,w:1,h:1},{id:"n",x:2,y:4,w:1,h:1},{id:"o",x:3,y:4,w:1,h:1},{id:"p",x:4,y:4,w:1,h:1}]},{id:"2-4",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=15 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F620) \u7A7A\u6D1E=1 \u65E0\u7EBF\u7D22\u8DEF\u5F84=144 \u7EBF\u7D22=1/6/15 \u6B65\u53F7\u5DEE=5/9/0 \u96BE\u5EA6\u5206=85.8\u3002\u4F5C\u8005\u89E3: a \u2192 b \u2192 c \u2192 d \u2192 A \u2192 m \u2192 l \u2192 k \u2192 j \u2192 B \u2192 i \u2192 h \u2192 f \u2192 e \u2192 g",cells:[{id:"a",x:1,y:0,w:1,h:1,clue:1},{id:"b",x:2,y:0,w:1,h:1},{id:"c",x:3,y:0,w:1,h:1},{id:"d",x:4,y:0,w:1,h:1},{id:"e",x:0,y:1,w:1,h:1},{id:"f",x:1,y:1,w:1,h:1},{id:"A",x:2,y:1,w:3,h:3},{id:"g",x:0,y:2,w:1,h:1,clue:15},{id:"h",x:1,y:2,w:1,h:1},{id:"B",x:0,y:3,w:1,h:2},{id:"i",x:1,y:3,w:1,h:1},{id:"j",x:1,y:4,w:1,h:1},{id:"k",x:2,y:4,w:1,h:1},{id:"l",x:3,y:4,w:1,h:1},{id:"m",x:4,y:4,w:1,h:1,clue:6}]},{id:"2-5",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=16 \u591A\u5355\u4F4D\u683C=3(\u5F02\u5F621) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=600+ \u7EBF\u7D22=1/6/15 \u6B65\u53F7\u5DEE=5/9/1 \u96BE\u5EA6\u5206=91.6\u3002\u4F5C\u8005\u89E3: j \u2192 i \u2192 f \u2192 b \u2192 c \u2192 A \u2192 a \u2192 B \u2192 e \u2192 h \u2192 m \u2192 l \u2192 k \u2192 C \u2192 g \u2192 d",cells:[{id:"A",x:0,y:0,w:2,h:2,clue:6},{id:"a",x:2,y:0,w:1,h:1},{id:"B",x:3,y:0,w:2,h:2},{id:"C",x:1,y:1,w:2,h:3,shape:[[1,0],[1,1],[1,2],[0,2]]},{id:"b",x:0,y:2,w:1,h:1},{id:"c",x:1,y:2,w:1,h:1},{id:"d",x:3,y:2,w:1,h:1},{id:"e",x:4,y:2,w:1,h:1},{id:"f",x:0,y:3,w:1,h:1},{id:"g",x:3,y:3,w:1,h:1,clue:15},{id:"h",x:4,y:3,w:1,h:1},{id:"i",x:0,y:4,w:1,h:1},{id:"j",x:1,y:4,w:1,h:1,clue:1},{id:"k",x:2,y:4,w:1,h:1},{id:"l",x:3,y:4,w:1,h:1},{id:"m",x:4,y:4,w:1,h:1}]},{id:"2-6",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=18 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F620) \u7A7A\u6D1E=1 \u65E0\u7EBF\u7D22\u8DEF\u5F84=128 \u7EBF\u7D22=1/4/8 \u6B65\u53F7\u5DEE=3/4/10 \u96BE\u5EA6\u5206=96.2\u3002\u4F5C\u8005\u89E3: e \u2192 d \u2192 c \u2192 g \u2192 A \u2192 j \u2192 k \u2192 l \u2192 m \u2192 p \u2192 o \u2192 n \u2192 B \u2192 h \u2192 i \u2192 f \u2192 b \u2192 a",cells:[{id:"a",x:0,y:0,w:1,h:1},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:4,y:0,w:1,h:1,clue:1},{id:"f",x:1,y:1,w:1,h:1},{id:"g",x:2,y:1,w:1,h:1,clue:4},{id:"A",x:3,y:1,w:2,h:2},{id:"h",x:0,y:2,w:1,h:1},{id:"i",x:1,y:2,w:1,h:1},{id:"j",x:2,y:2,w:1,h:1},{id:"B",x:0,y:3,w:2,h:2},{id:"k",x:2,y:3,w:1,h:1},{id:"l",x:3,y:3,w:1,h:1,clue:8},{id:"m",x:4,y:3,w:1,h:1},{id:"n",x:2,y:4,w:1,h:1},{id:"o",x:3,y:4,w:1,h:1},{id:"p",x:4,y:4,w:1,h:1}]},{id:"2-7",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=21 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F620) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=600+ \u7EBF\u7D22=1/7/17 \u6B65\u53F7\u5DEE=6/10/4 \u96BE\u5EA6\u5206=103.1\u3002\u4F5C\u8005\u89E3: q \u2192 p \u2192 o \u2192 B \u2192 k \u2192 l \u2192 h \u2192 g \u2192 A \u2192 d \u2192 a \u2192 b \u2192 c \u2192 f \u2192 e \u2192 i \u2192 m \u2192 r \u2192 s \u2192 n \u2192 j",cells:[{id:"A",x:0,y:0,w:2,h:2},{id:"a",x:2,y:0,w:1,h:1},{id:"b",x:3,y:0,w:1,h:1},{id:"c",x:4,y:0,w:1,h:1},{id:"d",x:2,y:1,w:1,h:1},{id:"e",x:3,y:1,w:1,h:1},{id:"f",x:4,y:1,w:1,h:1},{id:"B",x:0,y:2,w:1,h:2},{id:"g",x:1,y:2,w:1,h:1},{id:"h",x:2,y:2,w:1,h:1,clue:7},{id:"i",x:3,y:2,w:1,h:1},{id:"j",x:4,y:2,w:1,h:1},{id:"k",x:1,y:3,w:1,h:1},{id:"l",x:2,y:3,w:1,h:1},{id:"m",x:3,y:3,w:1,h:1,clue:17},{id:"n",x:4,y:3,w:1,h:1},{id:"o",x:0,y:4,w:1,h:1},{id:"p",x:1,y:4,w:1,h:1},{id:"q",x:2,y:4,w:1,h:1,clue:1},{id:"r",x:3,y:4,w:1,h:1},{id:"s",x:4,y:4,w:1,h:1}]},{id:"2-8",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=19 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F622) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=600+ \u7EBF\u7D22=3/5/15/17\uFF08\u65E0\u7EBF\u7D221\uFF09 \u6B65\u53F7\u5DEE=2/10/2/2 \u96BE\u5EA6\u5206=109.7\u3002\u4F5C\u8005\u89E3: i \u2192 d \u2192 e \u2192 j \u2192 l \u2192 k \u2192 n \u2192 o \u2192 q \u2192 p \u2192 B \u2192 m \u2192 A \u2192 h \u2192 c \u2192 b \u2192 a \u2192 f \u2192 g",cells:[{id:"a",x:0,y:0,w:1,h:1,clue:17},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1,clue:15},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:4,y:0,w:1,h:1,clue:3},{id:"f",x:0,y:1,w:1,h:1},{id:"g",x:1,y:1,w:1,h:1},{id:"h",x:2,y:1,w:1,h:1},{id:"i",x:3,y:1,w:1,h:1},{id:"j",x:4,y:1,w:1,h:1},{id:"A",x:0,y:2,w:3,h:2,shape:[[0,0],[1,0],[2,0],[2,1]]},{id:"k",x:3,y:2,w:1,h:1},{id:"l",x:4,y:2,w:1,h:1,clue:5},{id:"B",x:0,y:3,w:3,h:2,shape:[[2,1],[1,1],[0,1],[1,0]]},{id:"m",x:0,y:3,w:1,h:1},{id:"n",x:3,y:3,w:1,h:1},{id:"o",x:4,y:3,w:1,h:1},{id:"p",x:3,y:4,w:1,h:1},{id:"q",x:4,y:4,w:1,h:1}]},{id:"2-9",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=21 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F620) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=600+ \u7EBF\u7D22=1/7/20 \u6B65\u53F7\u5DEE=6/13/1 \u96BE\u5EA6\u5206=124.1\u3002\u4F5C\u8005\u89E3: f \u2192 c \u2192 b \u2192 e \u2192 A \u2192 a \u2192 d \u2192 g \u2192 j \u2192 o \u2192 p \u2192 q \u2192 r \u2192 s \u2192 n \u2192 i \u2192 B \u2192 m \u2192 l \u2192 k \u2192 h",cells:[{id:"a",x:0,y:0,w:1,h:1},{id:"A",x:1,y:0,w:2,h:2},{id:"b",x:3,y:0,w:1,h:1},{id:"c",x:4,y:0,w:1,h:1},{id:"d",x:0,y:1,w:1,h:1,clue:7},{id:"e",x:3,y:1,w:1,h:1},{id:"f",x:4,y:1,w:1,h:1,clue:1},{id:"g",x:0,y:2,w:1,h:1},{id:"h",x:1,y:2,w:1,h:1},{id:"B",x:2,y:2,w:2,h:1},{id:"i",x:4,y:2,w:1,h:1},{id:"j",x:0,y:3,w:1,h:1},{id:"k",x:1,y:3,w:1,h:1,clue:20},{id:"l",x:2,y:3,w:1,h:1},{id:"m",x:3,y:3,w:1,h:1},{id:"n",x:4,y:3,w:1,h:1},{id:"o",x:0,y:4,w:1,h:1},{id:"p",x:1,y:4,w:1,h:1},{id:"q",x:2,y:4,w:1,h:1},{id:"r",x:3,y:4,w:1,h:1},{id:"s",x:4,y:4,w:1,h:1}]},{id:"2-10",teach:"\u81EA\u52A8\u751F\u6210 seed=43\u3002N=21 \u591A\u5355\u4F4D\u683C=2(\u5F02\u5F620) \u7A7A\u6D1E=0 \u65E0\u7EBF\u7D22\u8DEF\u5F84=600+ \u7EBF\u7D22=1/5/21 \u6B65\u53F7\u5DEE=4/16/0 \u96BE\u5EA6\u5206=145.1\u3002\u4F5C\u8005\u89E3: q \u2192 l \u2192 m \u2192 r \u2192 B \u2192 s \u2192 p \u2192 k \u2192 h \u2192 e \u2192 d \u2192 c \u2192 b \u2192 a \u2192 A \u2192 f \u2192 g \u2192 j \u2192 o \u2192 n \u2192 i",cells:[{id:"a",x:0,y:0,w:1,h:1},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:4,y:0,w:1,h:1},{id:"A",x:0,y:1,w:2,h:2},{id:"f",x:2,y:1,w:1,h:1},{id:"g",x:3,y:1,w:1,h:1},{id:"h",x:4,y:1,w:1,h:1},{id:"i",x:2,y:2,w:1,h:1,clue:21},{id:"j",x:3,y:2,w:1,h:1},{id:"k",x:4,y:2,w:1,h:1},{id:"l",x:0,y:3,w:1,h:1},{id:"m",x:1,y:3,w:1,h:1},{id:"n",x:2,y:3,w:1,h:1},{id:"o",x:3,y:3,w:1,h:1},{id:"p",x:4,y:3,w:1,h:1},{id:"q",x:0,y:4,w:1,h:1,clue:1},{id:"r",x:1,y:4,w:1,h:1},{id:"B",x:2,y:4,w:2,h:1,clue:5},{id:"s",x:4,y:4,w:1,h:1}]}]};var _={mode:"01-number-stroke",pack:3,title:"\u5947\u4E0E\u5076",notes:"6 \u5173\u4F53\u9A8C\u5305\u3002\u5947/\u5076\u7EA6\u675F\u6574\u5757\u7684\u8DEF\u5F84\u6B65\u53F7\uFF0C\u4E0D\u662F\u9762\u79EF\uFF1B\u6BCF\u6761\u5947\u5076\u7EBF\u7D22\u90FD\u7ECF\u5220\u9664\u6821\u9A8C\u8BC1\u660E\u53C2\u4E0E\u552F\u4E00\u6027\u3002",levels:[{id:"3-1",caption:"\u5076\uFF1A\u8D70\u5230\u8FD9\u91CC\u65F6\uFF0C\u6B65\u6570\u8981\u662F 2\u30014\u30016\u2026",teach:"\u5947\u5076\u4F53\u9A8C\uFF1B\u590D\u7528 1-4 \u7684\u51E0\u4F55\uFF0C\u91CD\u65B0\u914D\u7F6E\u7EBF\u7D22\u3002\u4F5C\u8005\u89E3: start \u2192 a \u2192 big \u2192 b",cells:[{id:"start",x:0,y:0,w:1,h:1,clue:1},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1,parity:"even"},{id:"big",x:1,y:1,w:2,h:2}]},{id:"3-2",caption:"\u5947\uFF1A\u6B65\u6570\u8981\u662F 1\u30013\u30015\u2026\uFF1B\u5927\u5757\u53EA\u7B97\u4E00\u6B65",teach:"\u5947\u5076\u4F53\u9A8C\uFF1B\u539F\u521B 3\xD73 \u6559\u5B66\u76D8\u3002\u4F5C\u8005\u89E3: start \u2192 a \u2192 big \u2192 b \u2192 c \u2192 end",cells:[{id:"start",x:0,y:0,w:1,h:1,clue:1},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1},{id:"c",x:3,y:0,w:1,h:1},{id:"big",x:1,y:1,w:3,h:3,parity:"odd"},{id:"end",x:4,y:0,w:1,h:1}]},{id:"3-3",caption:"\u5148\u6570\u6B65\u6570\uFF0C\u518D\u51B3\u5B9A\u4ECE\u5927\u5757\u54EA\u8FB9\u51FA\u53BB",teach:"\u5947\u5076\u4F53\u9A8C\uFF1B\u590D\u7528 1-8 \u7684\u51E0\u4F55\uFF0C\u91CD\u65B0\u914D\u7F6E\u7EBF\u7D22\u3002\u4F5C\u8005\u89E3: a \u2192 b \u2192 B \u2192 d \u2192 f \u2192 j \u2192 i \u2192 h \u2192 g \u2192 e \u2192 c",cells:[{id:"a",x:1,y:0,w:1,h:1,clue:1},{id:"b",x:1,y:1,w:1,h:1},{id:"c",x:0,y:2,w:1,h:1,parity:"odd"},{id:"B",x:1,y:2,w:2,h:2},{id:"d",x:3,y:2,w:1,h:1},{id:"e",x:0,y:3,w:1,h:1},{id:"f",x:3,y:3,w:1,h:1},{id:"g",x:0,y:4,w:1,h:1},{id:"h",x:1,y:4,w:1,h:1},{id:"i",x:2,y:4,w:1,h:1},{id:"j",x:3,y:4,w:1,h:1}]},{id:"3-4",caption:"\u5947\u5076\u7EBF\u7D22\u548C\u6570\u5B57\u7EBF\u7D22\u8981\u540C\u65F6\u6EE1\u8DB3",teach:"\u5947\u5076\u4F53\u9A8C\uFF1B\u590D\u7528 2-1 \u7684\u51E0\u4F55\uFF0C\u91CD\u65B0\u914D\u7F6E\u7EBF\u7D22\u3002\u4F5C\u8005\u89E3: d \u2192 c \u2192 b \u2192 a \u2192 e \u2192 A \u2192 f \u2192 B \u2192 g \u2192 C \u2192 j \u2192 m \u2192 l \u2192 i \u2192 h \u2192 k",cells:[{id:"A",x:0,y:0,w:2,h:3,shape:[[0,0],[0,1],[0,2],[1,2]],parity:"even"},{id:"a",x:1,y:0,w:1,h:1},{id:"b",x:2,y:0,w:1,h:1},{id:"c",x:3,y:0,w:1,h:1},{id:"d",x:4,y:0,w:1,h:1,clue:1},{id:"e",x:1,y:1,w:1,h:1},{id:"B",x:2,y:1,w:3,h:2,shape:[[2,0],[1,0],[0,0],[1,1]]},{id:"f",x:2,y:2,w:1,h:1},{id:"g",x:4,y:2,w:1,h:1},{id:"h",x:0,y:3,w:1,h:1},{id:"i",x:1,y:3,w:1,h:1,clue:14},{id:"j",x:2,y:3,w:1,h:1,parity:"odd"},{id:"C",x:3,y:3,w:2,h:2},{id:"k",x:0,y:4,w:1,h:1},{id:"l",x:1,y:4,w:1,h:1},{id:"m",x:2,y:4,w:1,h:1}]},{id:"3-5",caption:"\u5148\u770B\u5947\u5076\uFF0C\u518D\u5B89\u6392\u7ED5\u884C\u7684\u987A\u5E8F",teach:"\u5947\u5076\u4F53\u9A8C\uFF1B\u590D\u7528 2-3 \u7684\u51E0\u4F55\uFF0C\u91CD\u65B0\u914D\u7F6E\u7EBF\u7D22\u3002\u4F5C\u8005\u89E3: k \u2192 o \u2192 p \u2192 l \u2192 h \u2192 g \u2192 e \u2192 A \u2192 b \u2192 a \u2192 c \u2192 B \u2192 d \u2192 f \u2192 j \u2192 i \u2192 m \u2192 n",cells:[{id:"a",x:0,y:0,w:1,h:1,parity:"even"},{id:"b",x:1,y:0,w:1,h:1},{id:"A",x:2,y:0,w:3,h:2,shape:[[0,0],[1,0],[2,0],[2,1]]},{id:"B",x:0,y:1,w:2,h:3,shape:[[0,1],[0,2],[1,0],[1,1]]},{id:"c",x:0,y:1,w:1,h:1},{id:"d",x:2,y:1,w:1,h:1},{id:"e",x:3,y:1,w:1,h:1,parity:"odd"},{id:"f",x:2,y:2,w:1,h:1},{id:"g",x:3,y:2,w:1,h:1},{id:"h",x:4,y:2,w:1,h:1},{id:"i",x:1,y:3,w:1,h:1,clue:16},{id:"j",x:2,y:3,w:1,h:1},{id:"k",x:3,y:3,w:1,h:1,clue:1},{id:"l",x:4,y:3,w:1,h:1},{id:"m",x:1,y:4,w:1,h:1},{id:"n",x:2,y:4,w:1,h:1},{id:"o",x:3,y:4,w:1,h:1},{id:"p",x:4,y:4,w:1,h:1}]},{id:"3-6",caption:"\u4E24\u4E2A\u5947\u6570\u683C\uFF0C\u4E2D\u95F4\u8981\u9694\u51E0\u6B65\uFF1F",teach:"\u5947\u5076\u4F53\u9A8C\uFF1B\u590D\u7528 2-6 \u7684\u51E0\u4F55\uFF0C\u91CD\u65B0\u914D\u7F6E\u7EBF\u7D22\u3002\u4F5C\u8005\u89E3: e \u2192 d \u2192 c \u2192 g \u2192 A \u2192 j \u2192 k \u2192 l \u2192 m \u2192 p \u2192 o \u2192 n \u2192 B \u2192 h \u2192 i \u2192 f \u2192 b \u2192 a",cells:[{id:"a",x:0,y:0,w:1,h:1},{id:"b",x:1,y:0,w:1,h:1},{id:"c",x:2,y:0,w:1,h:1,parity:"odd"},{id:"d",x:3,y:0,w:1,h:1},{id:"e",x:4,y:0,w:1,h:1,clue:1},{id:"f",x:1,y:1,w:1,h:1},{id:"g",x:2,y:1,w:1,h:1},{id:"A",x:3,y:1,w:2,h:2,parity:"odd"},{id:"h",x:0,y:2,w:1,h:1},{id:"i",x:1,y:2,w:1,h:1},{id:"j",x:2,y:2,w:1,h:1},{id:"B",x:0,y:3,w:2,h:2},{id:"k",x:2,y:3,w:1,h:1},{id:"l",x:3,y:3,w:1,h:1},{id:"m",x:4,y:3,w:1,h:1},{id:"n",x:2,y:4,w:1,h:1},{id:"o",x:3,y:4,w:1,h:1},{id:"p",x:4,y:4,w:1,h:1}]}]};function O(o){return o.clue!==null||o.parity!==null}function I(o,e){return!(o.clue!==null&&e!==o.clue||o.parity!==null&&e%2!==(o.parity==="odd"?1:0))}function L(o){return o.clue!==null?String(o.clue):o.parity==="odd"?"\u5947":o.parity==="even"?"\u5076":""}var j=class{constructor(e){this.path=[];this.status="empty";this.extraClues=new Map;this.board=e,this.stepOfCell=new Int16Array(e.n)}get n(){return this.board.n}get last(){return this.path.length?this.path[this.path.length-1]:-1}get remaining(){return this.board.n-this.path.length}get isCleared(){return this.status==="cleared"}stepOf(e){return this.stepOfCell[e]}isVisited(e){return this.stepOfCell[e]!==0}clueAt(e){let t=this.board.cells[e];return{clue:this.extraClues.get(e)??t.clue,parity:t.parity}}get revealedClues(){return this.extraClues}get startClueCell(){return this.clueCellAtStep(1)}clueCellAtStep(e){let t=this.board.clueCellOfStep.get(e);if(t!==void 0)return t;for(let[i,n]of this.extraClues)if(n===e)return i;return-1}isConflict(e){let t=this.stepOfCell[e];if(t===0)return!1;let i=this.clueCellAtStep(t);return!I(this.clueAt(e),t)||i!==-1&&i!==e}hasConflict(){for(let e of this.path)if(this.isConflict(e))return!0;return!1}isLegalStart(e){let t=this.startClueCell;return t===-1||t===e}canAppend(e){let t=this.last;return t===-1||this.status==="cleared"?!1:!this.isVisited(e)&&this.board.areAdjacent(t,e)}legalMoves(){let e=this.last;return e===-1?[]:this.board.adj[e].filter(t=>!this.isVisited(t))}isSolved(){return this.path.length===this.board.n&&!this.hasConflict()}apply(e){switch(e.type){case"start":return this.start(e.cell);case"append":return this.append(e.cell);case"undo":return this.undo();case"rewind":return this.rewind(e.cell);case"reveal":return this.reveal(e.cell,e.step);case"release":return this.status==="drawing"&&(this.status="idle"),[];case"resume":return this.status==="idle"&&(this.status="drawing"),[];case"reset":return this.reset()}}start(e){return this.status==="cleared"||this.path.length!==0?[]:this.isLegalStart(e)?(this.status="drawing",this.push(e)):[{type:"rejectStart",cell:e,clueCell:this.startClueCell}]}append(e){return this.canAppend(e)?(this.status="drawing",this.push(e)):[]}push(e){this.path.push(e);let t=this.path.length;this.stepOfCell[e]=t;let i=this.clueAt(e),n=this.isConflict(e),s=[{type:"step",cell:e,step:t,conflict:n,clueHit:O(i)&&!n}];return this.isSolved()?(this.status="cleared",s.push({type:"cleared"})):this.legalMoves().length===0&&s.push({type:"deadEnd",cell:e}),s}undo(){if(this.status==="cleared"||this.path.length===0)return[];let e=this.path.pop(),t=this.stepOfCell[e];return this.stepOfCell[e]=0,this.path.length===0&&(this.status="empty"),[{type:"unstep",cell:e,step:t}]}rewind(e){let t=this.path.indexOf(e);if(this.isCleared||t<0||t===this.path.length-1)return[];let i=this.path.length-t-1,n=[];for(;this.path.length>t+1;)n.push(...this.undo());return n.push({type:"rewound",cell:e,removed:i}),n}reveal(e,t){let i=this.board.cells[e];return this.isCleared||!Number.isInteger(e)||!i||!Number.isInteger(t)||t<1||t>this.n?[]:this.clueAt(e).clue!==null||!I(i,t)?[]:this.board.clueCellOfStep.has(t)||[...this.extraClues.values()].includes(t)?[]:(this.extraClues.set(e,t),[{type:"clueRevealed",cell:e,step:t}])}reset(){return this.path.length===0&&this.status==="empty"?[]:(this.path.length=0,this.stepOfCell.fill(0),this.status="empty",[{type:"reset"}])}};function W(o,e){if(o.isCleared||e.length!==o.n)return null;let t=0;for(;t<o.path.length&&o.path[t]===e[t];)t++;let i=[0,o.n+1];for(let n of o.board.cells){let s=o.clueAt(n.index).clue;s!==null&&i.push(s)}i.sort((n,s)=>n-s);for(let n=0;n<i.length-1;n++){let s=Math.max(i[n],t),r=i[n+1],h=(Math.max(1,s)+Math.min(o.n,r))/2,a=null;for(let c=s+1;c<r;c++){let l=e[c-1];o.clueAt(l).clue!==null||o.stepOf(l)===c||(!a||Math.abs(c-h)<Math.abs(a.step-h))&&(a={cell:l,step:c})}if(a)return a}return null}var D=class{constructor(e){this.drawing=!1;this.hoverCell=-1;this.game=e}get isDrawing(){return this.drawing}down(e){this.drawing=!1,this.hoverCell=e;let t=this.game;if(t.isCleared||e<0)return[];if(t.path.length===0){let n=this.run({type:"start",cell:e});return this.drawing=t.status==="drawing",n}let i=t.last;if(e===i)return this.drawing=!0,this.run({type:"resume"});if(t.isVisited(e)){let n=this.run({type:"rewind",cell:e});return this.drawing=!0,this.run({type:"resume"}),n}if(t.canAppend(e)){let n=this.run({type:"append",cell:e});return this.drawing=t.status==="drawing",n}return[]}move(e){if(e===this.hoverCell)return[];if(this.hoverCell=e,!this.drawing||e<0)return[];let t=this.game;if(t.isCleared)return this.drawing=!1,[];if(e!==t.last&&t.isVisited(e))return this.run({type:"rewind",cell:e});if(t.canAppend(e)){let i=this.run({type:"append",cell:e});return t.isCleared&&(this.drawing=!1),i}return[]}up(){return this.hoverCell=-1,this.drawing?(this.drawing=!1,this.run({type:"release"})):[]}cancel(){this.drawing=!1,this.hoverCell=-1}run(e){return this.game.apply(e)}};function J(o,e,t,i={}){let n=i.padding??16,s=i.maxUnit??104,r=Math.max(0,e-n*2),h=Math.max(0,t-n*2),a=Math.max(8,Math.min(s,r/o.cols,h/o.rows)),c=a*o.cols,l=a*o.rows;return{unit:a,originX:(e-c)/2,originY:(t-l)/2,gap:a*(i.gapRatio??.1),radius:a*(i.radiusRatio??.18),width:c,height:l}}function Z(o,e,t){let i=o.cells[e],n=t.gap/2;return{x:t.originX+i.x*t.unit+n,y:t.originY+i.y*t.unit+n,w:i.w*t.unit-t.gap,h:i.h*t.unit-t.gap}}function pe(o,e,t){let i=o.cells[e];return{x:t.originX+i.x*t.unit,y:t.originY+i.y*t.unit,w:i.w*t.unit,h:i.h*t.unit}}function Q(o,e,t,i=t.radius){let n=o.cells[e],s=t.gap/2,r=(l,d)=>({x:t.originX+l*t.unit+s,y:t.originY+d*t.unit+s,w:t.unit-t.gap,h:t.unit-t.gap}),h=new Set(n.units.map(([l,d])=>`${l},${d}`)),a=[],c=[];for(let[l,d]of n.units)a.push(r(l,d)),h.has(`${l+1},${d}`)&&c.push({x:t.originX+(l+1)*t.unit-s-i,y:t.originY+d*t.unit+s,w:t.gap+i*2,h:t.unit-t.gap}),h.has(`${l},${d+1}`)&&c.push({x:t.originX+l*t.unit+s,y:t.originY+(d+1)*t.unit-s-i,w:t.unit-t.gap,h:t.gap+i*2});return{units:a,seams:c}}function ee(o,e,t,i,n=.46){let s=o.sharedEdge(e,t);if(!s)return null;let r=i.unit*n,h=i.gap+2;if(s.dir==="v"){let l=i.originX+s.x1*i.unit,d=i.originY+(s.y1+s.y2)/2*i.unit;return{x:l-h/2,y:d-r/2,w:h,h:r}}let a=i.originY+s.y1*i.unit;return{x:i.originX+(s.x1+s.x2)/2*i.unit-r/2,y:a-h/2,w:r,h}}function te(o,e,t,i,n=.14){let s=Math.floor((t-e.originX)/e.unit),r=Math.floor((i-e.originY)/e.unit),h=o.cellAtUnit(s,r);if(h<0)return-1;let a=pe(o,h,e),c=e.unit*n;return t<a.x+c||t>a.x+a.w-c||i<a.y+c||i>a.y+a.h-c?-1:h}function ie(o,e){let t=o.x+o.w/2,i=o.y+o.h/2;return{x:t-o.w*e/2,y:i-o.h*e/2,w:o.w*e,h:o.h*e}}var fe=[[1,1],[2,1],[1,2],[2,2],[3,3]],ye=me();function ne(o){let e=1/0,t=1/0;for(let[i,n]of o)e=Math.min(e,i),t=Math.min(t,n);return o.map(([i,n])=>`${i-e},${n-t}`).sort().join(";")}function me(){let o=[[[0,0],[1,0]],[[0,0],[1,0],[2,0]],[[0,0],[0,1],[1,1]],[[0,0],[1,0],[2,0],[3,0]],[[0,0],[1,0],[0,1],[1,1]],[[0,0],[0,1],[0,2],[1,2]],[[1,0],[2,0],[0,1],[1,1]],[[0,0],[1,0],[2,0],[1,1]]],e=new Set;for(let t of o){let i=t;for(let n=0;n<2;n++){let s=i;for(let r=0;r<4;r++)e.add(ne(s)),s=s.map(([h,a])=>[a,-h]);i=i.map(([r,h])=>[-r,h])}}return e}var H=class o{constructor(e){this.cells=e,this.n=e.length;let t=0,i=0;for(let h of e)t=Math.max(t,h.x+h.w),i=Math.max(i,h.y+h.h);this.cols=t,this.rows=i;let n=new Int16Array(t*i).fill(-1);for(let h of e)for(let[a,c]of h.units){let l=c*t+a;if(n[l]!==-1)throw new Error(`\u683C\u91CD\u53E0: ${e[n[l]].id} \u4E0E ${h.id} \u4E8E (${a},${c})`);n[l]=h.index}this.unitMap=n;let s=e.map(()=>[]);for(let h=0;h<e.length;h++)for(let a=h+1;a<e.length;a++)we(e[h],e[a])&&(s[h].push(a),s[a].push(h));this.adj=s;let r=new Map;for(let h of e)if(h.clue!==null){if(r.has(h.clue))throw new Error(`\u7EBF\u7D22\u91CD\u590D: ${h.clue}`);r.set(h.clue,h.index)}this.clueCellOfStep=r,this.startClueCell=r.get(1)??-1}static fromLevel(e){return o.fromCells(e.cells)}static fromCells(e){if(e.length===0)throw new Error("\u76D8\u9762\u4E3A\u7A7A");let t=1/0,i=1/0;for(let r of e){if(r.shape)xe(r);else if(!fe.some(([h,a])=>h===r.w&&a===r.h))throw new Error(`\u683C ${r.id} \u5C3A\u5BF8 ${r.w}\xD7${r.h} \u4E0D\u5728 V1 \u5141\u8BB8\u8303\u56F4`);t=Math.min(t,r.x),i=Math.min(i,r.y)}let n=new Set,s=e.map((r,h)=>{if(n.has(r.id))throw new Error(`\u683C id \u91CD\u590D: ${r.id}`);n.add(r.id);let a=r.clue??null;if(r.parity!==void 0&&r.parity!=="odd"&&r.parity!=="even")throw new Error(`\u683C ${r.id} parity \u5FC5\u987B\u4E3A odd \u6216 even`);let c=r.parity??null;if(a!==null&&c!==null)throw new Error(`\u683C ${r.id} \u6570\u5B57\u7EBF\u7D22\u4E0E\u5947\u5076\u7EBF\u7D22\u4E0D\u80FD\u540C\u65F6\u586B\u5199`);if(a!==null&&(!Number.isInteger(a)||a<1||a>e.length))throw new Error(`\u683C ${r.id} \u7EBF\u7D22 ${a} \u8D85\u51FA 1..${e.length}`);let l=r.x-t,d=r.y-i,p=[];if(r.shape)for(let[y,u]of r.shape)p.push([l+y,d+u]);else for(let y=d;y<d+r.h;y++)for(let u=l;u<l+r.w;u++)p.push([u,y]);return{index:h,id:r.id,x:l,y:d,w:r.w,h:r.h,clue:a,parity:c,units:p,isRect:p.length===r.w*r.h}});return new o(s)}cellAtUnit(e,t){return e<0||t<0||e>=this.cols||t>=this.rows?-1:this.unitMap[t*this.cols+e]}areAdjacent(e,t){return this.adj[e].includes(t)}cellById(e){let t=this.cells.find(i=>i.id===e);if(!t)throw new Error(`\u6CA1\u6709\u683C ${e}`);return t}anchorUnit(e){let t=this.cells[e];if(t.isRect)return[t.x,t.y];let i=0,n=0;for(let[h,a]of t.units)i+=h+.5,n+=a+.5;i/=t.units.length,n/=t.units.length;let s=t.units[0],r=1/0;for(let h of t.units){let a=(h[0]+.5-i)**2+(h[1]+.5-n)**2;a<r&&(r=a,s=h)}return s}anchorCenter(e){let t=this.cells[e];if(t.isRect)return[t.x+t.w/2,t.y+t.h/2];let[i,n]=this.anchorUnit(e);return[i+.5,n+.5]}sharedEdge(e,t){if(e===t)return null;let i=this.cells[e],n=this.cells[t],s=[],r=[];for(let[d,p]of i.units)for(let[y,u]of n.units)u===p&&y-d===1?s.push([d+1,p]):u===p&&d-y===1?s.push([y+1,u]):y===d&&u-p===1?r.push([d,p+1]):y===d&&p-u===1&&r.push([y,u+1]);let h=(d,p)=>{let y=new Map;for(let[x,f]of d){let k=p?x:f;y.has(k)||y.set(k,[]),y.get(k).push(p?f:x)}let u=null;for(let[x,f]of y){f.sort((b,C)=>b-C);let k=f[0],R=f[0],m=()=>{let b=R-k+1,C=p?{x1:x,y1:k,x2:x,y2:R+1,dir:"v"}:{x1:k,y1:x,x2:R+1,y2:x,dir:"h"};(!u||b>u.x2-u.x1+(u.y2-u.y1))&&(u=C)};for(let b=1;b<=f.length;b++)b<f.length&&f[b]===R+1?R=f[b]:(m(),b<f.length&&(k=f[b],R=f[b]))}return u},a=h(s,!0),c=h(r,!1);if(!a)return c;if(!c)return a;let l=d=>d.x2-d.x1+(d.y2-d.y1);return l(a)>=l(c)?a:c}isConnected(){let e=new Uint8Array(this.n),t=[0];e[0]=1;let i=1;for(;t.length;){let n=t.pop();for(let s of this.adj[n])e[s]||(e[s]=1,i++,t.push(s))}return i===this.n}};function xe(o){let e=o.shape,t=a=>{throw new Error(`\u683C ${o.id} shape \u975E\u6CD5: ${a}`)};(e.length<2||e.length>4)&&t(`\u5355\u4F4D\u6570 ${e.length} \u4E0D\u5728 2..4`);let i=new Set,n=-1,s=-1;for(let[a,c]of e){(a<0||c<0)&&t(`\u504F\u79FB (${a},${c}) \u4E3A\u8D1F\uFF08\u951A\u70B9\u5FC5\u987B\u662F bbox \u5DE6\u4E0A\uFF09`);let l=`${a},${c}`;i.has(l)&&t(`\u5355\u4F4D (${a},${c}) \u91CD\u590D`),i.add(l),n=Math.max(n,a),s=Math.max(s,c)}(n+1!==o.w||s+1!==o.h)&&t(`bbox ${n+1}\xD7${s+1} \u4E0E w/h ${o.w}\xD7${o.h} \u4E0D\u7B26`);let r=new Set([e[0].join(",")]),h=[e[0]];for(;h.length;){let[a,c]=h.pop();for(let[l,d]of[[a+1,c],[a-1,c],[a,c+1],[a,c-1]]){let p=`${l},${d}`;i.has(p)&&!r.has(p)&&(r.add(p),h.push([l,d]))}}r.size!==e.length&&t("\u4E0D\u8FDE\u901A"),ye.has(ne(e))||t("\u4E0D\u5728\u5F62\u72B6\u76EE\u5F55\uFF08I/L/S/T/O\uFF0C2~4 \u683C\uFF09")}function we(o,e){for(let[t,i]of o.units)for(let[n,s]of e.units)if(Math.abs(t-n)+Math.abs(i-s)===1)return!0;return!1}function se(o){if(!o||typeof o!="object")throw new Error("\u5173\u5361\u5305\u4E0D\u662F\u5BF9\u8C61");let e=o;if(typeof e.pack!="number"||!Array.isArray(e.levels))throw new Error("\u5173\u5361\u5305\u7F3A\u5C11 pack / levels");for(let t of e.levels)if(typeof t.id!="string"||!Array.isArray(t.cells))throw new Error(`\u5173\u5361\u683C\u5F0F\u9519\u8BEF: ${JSON.stringify(t).slice(0,60)}`);return{mode:String(e.mode??"01-number-stroke"),pack:e.pack,title:String(e.title??`\u5305 ${e.pack}`),notes:e.notes,levels:e.levels}}function re(o){return o.levels.map((e,t)=>({def:e,board:H.fromLevel(e),pack:o.pack,index:t+1}))}var be="mode:01-number-stroke",G=class{constructor(e,t=be){this.cleared=new Set;this.currentId=null;this.prefs={sound:!0,haptics:!0};this.store=e,this.key=t,this.load()}isCleared(e){return this.cleared.has(e)}clearedCount(){return this.cleared.size}markCleared(e){this.cleared.add(e),this.save()}setCurrent(e){this.currentId=e,this.save()}setPrefs(e){this.prefs={...this.prefs,...e},this.save()}isUnlocked(e,t){return t===0||this.cleared.has(e[t-1])}firstUncleared(e){for(let t of e)if(!this.cleared.has(t))return t;return e[e.length-1]}resetAll(){this.cleared.clear(),this.currentId=null,this.save()}load(){try{let e=this.store.get(this.key);if(!e)return;let t=JSON.parse(e);Array.isArray(t.cleared)&&(this.cleared=new Set(t.cleared.filter(i=>typeof i=="string"))),typeof t.currentId=="string"&&(this.currentId=t.currentId),t.prefs&&(this.prefs={...this.prefs,...t.prefs})}catch{}}save(){let e={cleared:[...this.cleared],currentId:this.currentId,prefs:this.prefs};try{this.store.set(this.key,JSON.stringify(e))}catch{}}};function ge(o,e={}){let t=e.limit??1/0,i=o.n,n=o.adj,s=new Int16Array(i).fill(0),r=new Int16Array(i+2).fill(-1);if(!e.ignoreClues)for(let m of o.cells)m.clue!==null&&(s[m.index]=m.clue,r[m.clue]=m.index);let h=[];for(let m=1;m<=i;m++)r[m]!==-1&&h.push(m);let a=[],c=new Uint8Array(i),l=[],d=new Int16Array(i),p=new Int16Array(i);function y(m){d.fill(-1),d[m]=0;let b=0,C=0;p[C++]=m;let g=0;for(;b<C;){let S=p[b++];for(let E of n[S])!c[E]&&d[E]===-1&&(d[E]=d[S]+1,g++,p[C++]=E)}return g}function u(m,b){let C=i-b;if(C===0)return!1;if(y(m)<C)return!0;for(let g of h){if(g<=b)continue;let S=r[g];if(c[S])return!0;let E=d[S];if(E===-1||E>g-b)return!0}return!1}function x(m,b){if(b===i)return a.push(l.slice()),a.length>=t;if(u(m,b))return!1;let C=b+1,g=r[C];if(g!==-1)return c[g]||!n[m].includes(g)?!1:k(g,C);let S=n[m].filter(E=>!c[E]&&s[E]===0);S.length>1&&S.sort((E,B)=>f(E)-f(B));for(let E of S)if(k(E,C))return!0;return!1}function f(m){let b=0;for(let C of n[m])c[C]||b++;return b}function k(m,b){if(!e.ignoreClues&&!I(o.cells[m],b))return!1;c[m]=1,l.push(m);let C=x(m,b);return l.pop(),c[m]=0,C}let R;e.starts?R=e.starts:r[1]!==-1?R=[r[1]]:R=o.cells.map(m=>m.index);for(let m of R)if(!(s[m]!==0&&s[m]!==1)&&k(m,1))break;return a}function ae(o){let e=ge(o,{limit:2});return e.length===1?e[0]:null}function oe(o,e){if(e.length===0)return{kind:"start",cell:o[0]};let t=0;for(;t<e.length&&t<o.length&&e[t]===o[t];)t++;return t===e.length?t===o.length?{kind:"none"}:{kind:"next",cell:o[t]}:t===0?{kind:"restart",cell:o[0]}:{kind:"backtrack",cell:e[t-1],undoCount:e.length-t}}var A={bg:"#FFFFFF",cell:"#E6E7EC",clueInk:"#23243A",clueRing:"#23243A",activeClueRing:"#DFE1EC",visited:"#6558F5",visitedBright:"#7D72FF",visitedInk:"#FFFFFF",conflict:"#E5484D",conflictInk:"#FFFFFF",hint:"#F5A524",flash:"#FFFFFF"},T={start:.6,single:.52,double:.46,parity:.44,paritySub:.19,badge:.15,badgeText:1.25,ring:.05,hintRing:.08},v={fast:.12,base:.2,slow:.32,hold:.5,popImpulse:2.4,springK:260,springDamp:18,flashTime:.32,shakeTime:.28,numberFade:.12,bridgeGrow:.12,hintTime:2.4,hintPulse:7,clearedSweep:.32,clearedSweepCell:.25,clearedHold:.5,boardExit:.16,boardEnter:.2,boardEnterStagger:.014,boardEnterMaxDelay:.2};function le(o){let e=1-Math.max(0,Math.min(1,o));return 1-e*e*e*e}function N(o,e,t){if(o.cells[e].isRect)return{units:[Z(o,e,t)],seams:[],radius:t.radius};let{units:n,seams:s}=Q(o,e,t);return{units:n,seams:s,radius:t.radius}}var F=class{constructor(e,t={}){this.layout=null;this.bridges=[];this.hintState=null;this.cleared=!1;this.clearedT=0;this.exit=0;this.exiting=!1;this.animating=!0;this.game=e,this.reduced=t.reducedMotion===!0;let i=e.board.cells.map(s=>({i:s.index,key:s.y*1e3+s.x})).sort((s,r)=>s.key-r.key).map(s=>s.i),n=new Array(i.length);i.forEach((s,r)=>{n[s]=Math.min(v.boardEnterMaxDelay,r*v.boardEnterStagger)}),this.cells=e.board.cells.map(s=>({scale:1,scaleVel:0,flash:0,shake:0,numberAlpha:0,sweep:0,enter:this.reduced?1:0,enterDelay:this.reduced?0:n[s.index]}))}get isAnimating(){return this.animating}get clearedDuration(){return v.clearedSweep+v.clearedHold+v.boardExit}get clearedHoldEnd(){return v.clearedSweep+v.clearedHold}invalidate(){this.animating=!0}beginExit(){this.reduced?this.exit=1:this.exiting=!0,this.animating=!0}onEvent(e){switch(this.animating=!0,this.hintState=null,e.type){case"step":{let t=this.cells[e.cell];t.scaleVel=this.reduced||e.conflict?0:v.popImpulse,t.shake=!this.reduced&&e.conflict?v.shakeTime:0,t.numberAlpha=this.reduced?1:0,e.clueHit&&(t.flash=1),this.bridges.length=Math.max(0,e.step-1),e.step>=2&&(this.bridges[e.step-2]=this.reduced?1:0);break}case"unstep":{let t=this.cells[e.cell];t.numberAlpha=0,t.flash=0,t.scale=1,t.scaleVel=0,t.shake=0,this.bridges.length=Math.max(0,e.step-2);break}case"rewound":this.cells[e.cell].scaleVel=this.reduced?0:v.popImpulse;break;case"clueRevealed":{this.cells[e.cell].scaleVel=this.reduced?0:v.popImpulse;for(let t of[e.cell,this.game.path[e.step-1]]){if(t===void 0||!this.game.isConflict(t))continue;let i=this.cells[t];i.scale=1,i.scaleVel=0,i.shake=this.reduced?0:v.shakeTime}this.hintState={hint:{kind:"clue",cell:e.cell},t:v.hintTime};break}case"reset":for(let t of this.cells)t.flash=0,t.numberAlpha=0,t.scale=1,t.scaleVel=0,t.shake=0,t.sweep=0;this.bridges.length=0,this.cleared=!1,this.clearedT=0;break;case"rejectStart":e.clueCell>=0&&(this.cells[e.clueCell].shake=this.reduced?0:v.shakeTime);break;case"deadEnd":this.cells[e.cell].shake=this.reduced?0:v.shakeTime;break;case"cleared":this.cleared=!0,this.clearedT=0;break}}showHint(e){this.hintState=e.kind==="none"?null:{hint:e,t:v.hintTime},this.animating=!0}update(e){if(e<=0)return;e=Math.min(e,.05);let t=!1;for(let i of this.cells){if(i.enter<1&&(i.enterDelay>0?i.enterDelay=Math.max(0,i.enterDelay-e):i.enter=Math.min(1,i.enter+e/v.boardEnter),t=!0),i.scaleVel!==0||Math.abs(i.scale-1)>5e-4){let n=-v.springK*(i.scale-1)-v.springDamp*i.scaleVel;i.scaleVel+=n*e,i.scale+=i.scaleVel*e,Math.abs(i.scale-1)<5e-4&&Math.abs(i.scaleVel)<.01?(i.scale=1,i.scaleVel=0):t=!0}i.flash>0&&(i.flash=Math.max(0,i.flash-e/v.flashTime),t=!0),i.shake>0&&(i.shake=Math.max(0,i.shake-e),t=!0),i.numberAlpha<1&&(i.numberAlpha=Math.min(1,i.numberAlpha+e/v.numberFade),t=!0)}for(let i=0;i<this.bridges.length;i++)this.bridges[i]<1&&(this.bridges[i]=Math.min(1,this.bridges[i]+e/v.bridgeGrow),t=!0);if(this.hintState&&(this.hintState.t-=e,this.hintState.t<=0&&(this.hintState=null),t=!0),this.cleared){this.clearedT+=e;let i=this.game.path;for(let n=0;n<i.length;n++){let s=n/i.length*v.clearedSweep,r=this.reduced?1:(this.clearedT-s)/v.clearedSweepCell;this.cells[i[n]].sweep=Math.max(0,Math.min(1,r))}this.clearedT<this.clearedDuration&&(t=!0)}this.exiting&&this.exit<1&&(this.exit=Math.min(1,this.exit+e/v.boardExit),t=!0),this.animating=t}cellDraw(e){let t=this.layout,i=this.game.board,n=i.cells[e],s=this.cells[e],r=N(i,e,t),h=s.shake/v.shakeTime,a=s.shake>0?Math.sin(h*Math.PI*6)*t.unit*.06*h:0,c=le(s.enter),l=s.scale*(.92+.08*c),[d,p]=i.anchorCenter(e),y={x:t.originX+d*t.unit,y:t.originY+p*t.unit},u=C=>{let g=C;return a&&(g={...g,x:g.x+a}),l!==1&&(g=n.isRect?ie(g,l):{x:y.x+(g.x-y.x)*l,y:y.y+(g.y-y.y)*l,w:g.w*l,h:g.h*l}),g},x=r.units.map(u),f=r.seams.map(u),[k,R]=i.anchorUnit(e),m=n.units.findIndex(([C,g])=>C===k&&g===R),b=0;return n.units.forEach(([C,g],S)=>{let[E,B]=n.units[b];(g<B||g===B&&C>E)&&(b=S)}),{units:x,seams:f,radius:r.radius,anchor:x[n.isRect?0:m],badge:x[n.isRect?0:b],alpha:c*(1-this.exit)}}draw(e){let t=this.layout;if(!t)return;let i=this.game,n=i.board,s=i.path,r=1-this.exit;if(r<=0)return;let h=this.cleared?A.visitedBright:A.visited;for(let a of n.cells){let c=this.cells[a.index],l=this.cellDraw(a.index),p=i.stepOf(a.index)!==0,y=i.isConflict(a.index),u=A.cell;y?u=A.conflict:(p||i.clueAt(a.index).clue===1)&&(u=h);for(let x of l.units)e.fillRoundRect(x,l.radius,u,l.alpha);for(let x of l.seams)e.fillRoundRect(x,0,u,l.alpha);if(p&&c.sweep>0&&c.sweep<1){let x=.55*Math.sin(c.sweep*Math.PI)*l.alpha;for(let f of l.units)e.fillRoundRect(f,l.radius,A.flash,x);for(let f of l.seams)e.fillRoundRect(f,0,A.flash,x)}}for(let a=0;a<s.length-1;a++){let c=le(this.bridges[a]??1);if(c<=0)continue;let l=ee(n,s[a],s[a+1],t);if(!l)continue;let p=l.w<l.h?{x:l.x,y:l.y+l.h*(1-c)/2,w:l.w,h:l.h*c}:{x:l.x+l.w*(1-c)/2,y:l.y,w:l.w*c,h:l.h};e.fillRoundRect(p,0,h,r)}for(let a of n.cells){let c=this.cells[a.index],l=this.cellDraw(a.index),d=l.anchor.x+l.anchor.w/2,p=l.anchor.y+l.anchor.h/2,y=i.stepOf(a.index),u=y!==0,x=i.isConflict(a.index),f=i.clueAt(a.index),k=O(f),R=f.clue===1||y===1,m=u?String(y):L(f),b=R&&!x?T.start:!u&&f.clue===null&&a.parity!==null?T.parity:m.length>1?T.double:T.single,C=t.unit*b;if(k){let S=Math.max(2,t.unit*T.ring),E=u||f.clue===1?A.activeClueRing:A.clueRing,B=($,P,z=1)=>{for(let M of l.units)e.fillRoundRect({x:M.x+P,y:M.y+P,w:M.w-2*P,h:M.h-2*P},Math.max(0,l.radius-P),$,z*l.alpha);for(let M of l.seams){let he=M.w<M.h;e.fillRoundRect(he?{x:M.x,y:M.y+P,w:M.w,h:M.h-2*P}:{x:M.x+P,y:M.y,w:M.w-2*P,h:M.h},0,$,z*l.alpha)}};B(E,0),c.flash>0&&B(A.flash,0,c.flash),B(x?A.conflict:u||f.clue===1?h:A.cell,S),u&&c.sweep>0&&c.sweep<1&&B(A.flash,S,.55*Math.sin(c.sweep*Math.PI))}let g=a.parity!==null&&!x&&(u||f.clue!==null);if(u){let S=x?A.conflictInk:A.visitedInk;if(e.text(String(y),d,p-(g?t.unit*.09:0),C,S,!0,c.numberAlpha*l.alpha),g&&e.text(L(a),d,p+t.unit*.23,t.unit*T.paritySub,S,!0,l.alpha),x&&!I(f,y)){let E=Math.max(7,t.unit*T.badge),B=l.badge.x+l.badge.w-E-t.unit*.08,$=l.badge.y+E+t.unit*.08;e.fillCircle(B,$,E,A.clueInk,l.alpha),e.text(L(f),B,$+E*.03,E*T.badgeText,A.conflictInk,!0,l.alpha)}}else if(k){let S=f.clue===1?A.visitedInk:A.clueInk;e.text(m,d,p-(g?t.unit*.09:0),C,S,!0,l.alpha),g&&e.text(L(a),d,p+t.unit*.23,t.unit*T.paritySub,S,!0,l.alpha)}}if(this.hintState){let{hint:a,t:c}=this.hintState,l=this.reduced?1:.55+.45*Math.sin((v.hintTime-c)*v.hintPulse),d=Math.min(1,c/.4)*l*r,p=a.kind==="none"?-1:a.cell;if(p>=0){let y=N(n,p,t),u=Math.max(3,t.unit*T.hintRing);for(let x of y.units){let f={x:x.x-u,y:x.y-u,w:x.w+u*2,h:x.h+u*2};e.strokeRoundRect(f,y.radius+u,A.hint,u,d)}}if(a.kind==="backtrack"){let y=s.indexOf(a.cell)+1;for(let u=y;u<s.length;u++){let x=N(n,s[u],t);for(let f of x.units)e.fillRoundRect(f,x.radius,A.bg,.45*l*r);for(let f of x.seams)e.fillRoundRect(f,0,A.bg,.45*l*r)}}}}};var V=class{constructor(){this.enabled=!0;this.ctx=null}unlock(){if(!this.ctx){let e=window.AudioContext??window.webkitAudioContext;if(!e)return;this.ctx=new e}this.ctx.state==="suspended"&&this.ctx.resume()}tone(e,t,i,n,s=0){if(!this.enabled||!this.ctx)return;let r=this.ctx,h=r.currentTime+s,a=r.createOscillator(),c=r.createGain();a.type=i,a.frequency.setValueAtTime(e,h),c.gain.setValueAtTime(1e-4,h),c.gain.exponentialRampToValueAtTime(n,h+.008),c.gain.exponentialRampToValueAtTime(1e-4,h+t),a.connect(c).connect(r.destination),a.start(h),a.stop(h+t+.02)}step(e){let t=(e-1)%12,i=523.25*Math.pow(2,t/12);this.tone(i,.09,"sine",.18)}conflict(){this.tone(130,.16,"square",.08)}cleared(){[0,4,7,12].forEach((t,i)=>this.tone(523.25*Math.pow(2,t/12),.22,"triangle",.16,i*.07))}reject(){this.tone(220,.06,"triangle",.06)}};var ve='ui-rounded, "SF Pro Rounded", "PingFang SC", "Hiragino Sans GB", "Noto Sans SC", system-ui, -apple-system, "Segoe UI", sans-serif',U=class{constructor(e){this.ctx=e}path(e,t){let i=this.ctx,n=Math.max(0,Math.min(t,e.w/2,e.h/2));if(i.beginPath(),typeof i.roundRect=="function")i.roundRect(e.x,e.y,e.w,e.h,n);else{let{x:s,y:r,w:h,h:a}=e;i.moveTo(s+n,r),i.arcTo(s+h,r,s+h,r+a,n),i.arcTo(s+h,r+a,s,r+a,n),i.arcTo(s,r+a,s,r,n),i.arcTo(s,r,s+h,r,n),i.closePath()}}fillRoundRect(e,t,i,n=1){if(n<=0||e.w<=0||e.h<=0)return;let s=this.ctx;s.globalAlpha=Math.min(1,n),s.fillStyle=i,this.path(e,t),s.fill(),s.globalAlpha=1}strokeRoundRect(e,t,i,n,s=1){if(s<=0)return;let r=this.ctx;r.globalAlpha=Math.min(1,s),r.strokeStyle=i,r.lineWidth=n,this.path(e,t),r.stroke(),r.globalAlpha=1}fillCircle(e,t,i,n,s=1){if(s<=0)return;let r=this.ctx;r.globalAlpha=Math.min(1,s),r.fillStyle=n,r.beginPath(),r.arc(e,t,i,0,Math.PI*2),r.fill(),r.globalAlpha=1}text(e,t,i,n,s,r=!1,h=1){if(h<=0)return;let a=this.ctx;a.globalAlpha=Math.min(1,h),a.fillStyle=s,a.font=`${r?/^\d+$/.test(e)?"800":"700":"500"} ${n}px ${ve}`,a.textAlign="center",a.textBaseline="middle",a.fillText(e,t,i+n*.04),a.globalAlpha=1}};var w=o=>{let e=document.getElementById(o);if(!e)throw new Error(`#${o} \u4E0D\u5B58\u5728`);return e},Y=class{get(e){try{return localStorage.getItem(e)}catch{return null}}set(e,t){try{localStorage.setItem(e,t)}catch{}}remove(e){try{localStorage.removeItem(e)}catch{}}},q=class{constructor(){this.packs=[X,K,_].map(e=>se(e));this.packLevels=this.packs.map(e=>re(e));this.levels=this.packLevels.flat();this.ids=this.levels.map(e=>e.def.id);this.progress=new G(new Y);this.sfx=new V;this.devUnlock=/[?&]dev\b/.test(location.search);this.unlockAll=this.devUnlock||document.documentElement.dataset.unlockAll==="true";this.reducedMotion=typeof matchMedia=="function"&&matchMedia("(prefers-reduced-motion: reduce)").matches;this.canvas=w("board");this.ctx=this.canvas.getContext("2d");this.painter=new U(this.ctx);this.boardWrap=w("board-wrap");this.session=null;this.rafId=0;this.lastT=0;this.activePointer=null;this.touchPointer=!1;this.lastPos={x:0,y:0};this.advanceTimer=0;this.exitTimer=0;this.toastTimer=0;this.cssSize={w:0,h:0};this.lastRemaining=-1;this.onPointerDown=e=>{if(!e.isPrimary||this.activePointer!==null||!this.session||this.session.game.isCleared)return;this.sfx.unlock(),this.activePointer=e.pointerId,this.touchPointer=e.pointerType==="touch";try{this.canvas.setPointerCapture(e.pointerId)}catch{}let t=this.pointerPos(e);this.lastPos=t,this.handleEvents(this.session.input.down(this.cellAt(t))),e.preventDefault()};this.onPointerMove=e=>{if(e.pointerId!==this.activePointer||!this.session||!this.session.layout)return;let t=this.pointerPos(e),i=this.cellAt(t);if(i>=0&&this.session.game.isVisited(i)){this.lastPos=t,this.handleEvents(this.session.input.move(i)),e.preventDefault();return}let n=this.session.layout.unit*.25,s=t.x-this.lastPos.x,r=t.y-this.lastPos.y,h=Math.max(1,Math.ceil(Math.hypot(s,r)/n)),a=[];for(let c=1;c<=h;c++){let l={x:this.lastPos.x+s*c/h,y:this.lastPos.y+r*c/h};a.push(...this.session.input.move(this.cellAt(l)))}this.lastPos=t,this.handleEvents(a),e.preventDefault()};this.onPointerUp=e=>{e.pointerId===this.activePointer&&(this.activePointer=null,this.session&&this.handleEvents(this.session.input.up()))};if(this.sfx.enabled=this.progress.prefs.sound,this.bindUI(),new ResizeObserver(()=>this.resize()).observe(this.boardWrap),this.renderSelect(),this.showSelect(),this.devUnlock){window.__numberStroke=this;let e=new URLSearchParams(location.search).get("level"),t=e===null?-1:this.ids.indexOf(e);t>=0&&this.startLevel(t)}}debugCellCenter(e){let t=this.session;if(!t||!t.layout)return null;let i=t.level.board.cellById(e),[n,s]=t.level.board.anchorCenter(i.index),r=this.canvas.getBoundingClientRect();return{x:r.left+t.layout.originX+n*t.layout.unit,y:r.top+t.layout.originY+s*t.layout.unit}}debugState(){let e=this.session;if(!e)return null;let t=i=>i.map(n=>e.level.board.cells[n].id);return{id:e.level.def.id,path:t(e.game.path),status:e.game.status,remaining:e.game.remaining,solution:e.solution?t(e.solution):null,conflicts:t(e.game.path.filter(i=>e.game.isConflict(i))),revealed:[...e.game.revealedClues].map(([i,n])=>({cell:e.level.board.cells[i].id,step:n}))}}showSelect(){this.cancelGesture(),this.stopLoop(),window.clearTimeout(this.exitTimer),w("screen-play").classList.add("hidden"),this.renderSelect(),this.enterScreen(w("screen-select"))}showPlay(){w("screen-select").classList.add("hidden");let e=w("screen-play");e.classList.contains("hidden")&&this.enterScreen(e),this.resize(),this.startLoop()}enterScreen(e){e.classList.remove("hidden"),e.classList.remove("enter"),e.offsetWidth,e.classList.add("enter"),e.addEventListener("animationend",()=>e.classList.remove("enter"),{once:!0})}renderSelect(){let e=w("pack-list");e.innerHTML="";let t=this.progress.firstUncleared(this.ids),i=this.progress.clearedCount(),n=i>=this.levels.length;w("overall-fill").style.width=`${100*i/this.levels.length}%`,w("overall-text").textContent=`${i} / ${this.levels.length}`;let s=0;this.packs.forEach((h,a)=>{let c=this.packLevels[a],l=document.createElement("div");l.className="pack";let d=c.filter(u=>this.progress.isCleared(u.def.id)).length;d===c.length&&l.classList.add("done");let p=document.createElement("div");p.className="pack-title",p.innerHTML=`<span></span><span class="pack-progress">${d} / ${c.length}</span>`,p.firstElementChild.textContent=h.title;let y=document.createElement("div");y.className="level-grid";for(let u of c){let x=s++,f=u.def.id,k=document.createElement("button");k.className="level-tile",k.innerHTML=`<span>${u.index}</span>`;let R=this.unlockAll||this.progress.isUnlocked(this.ids,x);this.progress.isCleared(f)?k.classList.add("cleared"):R||k.classList.add("locked"),f===t&&!n&&k.classList.add("current"),k.addEventListener("click",()=>{if(this.sfx.unlock(),!R){k.classList.remove("shake"),k.offsetWidth,k.classList.add("shake");return}this.startLevel(x)}),y.appendChild(k)}l.appendChild(p),l.appendChild(y),e.appendChild(l)});let r=w("btn-continue");r.textContent=n?`\u5168\u90E8\u901A\u5173 \xB7 \u91CD\u73A9 ${this.ids[0]}`:`\u7EE7\u7EED \xB7 ${t}`,this.syncPrefChips()}syncPrefChips(){w("btn-sound").classList.toggle("on",this.progress.prefs.sound),w("btn-haptic").classList.toggle("on",this.progress.prefs.haptics)}startLevel(e){this.cancelGesture(),window.clearTimeout(this.advanceTimer),window.clearTimeout(this.exitTimer);let t=this.levels[e],i=new j(t.board),n=new F(i,{reducedMotion:this.reducedMotion});this.session={level:t,game:i,view:n,input:new D(i),solution:ae(t.board),layout:null},this.progress.setCurrent(t.def.id);let s=this.packLevels.findIndex(r=>r.includes(t));w("level-title").textContent=t.def.id,w("level-sub").textContent=`${this.packs[s].title} \xB7 \u7B2C ${t.index} \u5173`,this.renderProgressStrip(s,t.def.id),w("caption").textContent=t.def.caption??"",w("btn-hint").classList.remove("pulse"),w("btn-restart").classList.remove("pulse"),w("remaining").classList.remove("done","bump"),this.lastRemaining=-1,this.setButtonsEnabled(!0),this.updateHud(),this.showPlay()}renderProgressStrip(e,t){let i=w("level-progress");i.innerHTML="";for(let n of this.packLevels[e]){let s=document.createElement("i");n.def.id===t?s.className="current":this.progress.isCleared(n.def.id)&&(s.className="cleared"),i.appendChild(s)}}currentIndex(){return this.session?this.levels.indexOf(this.session.level):-1}nextLevel(){let e=this.currentIndex();e>=0&&e+1<this.levels.length?this.startLevel(e+1):(this.showSelect(),this.toast(this.ids.every(t=>this.progress.isCleared(t))?"\u5DF2\u901A\u5173\u5168\u90E8 "+this.levels.length+" \u5173":"\u672C\u5305\u5DF2\u5B8C\u6210"))}updateHud(){if(!this.session)return;let e=this.session.game.remaining;if(e===this.lastRemaining)return;let t=w("remaining");this.session.game.isCleared?(w("remaining-n").textContent="\u5B8C\u6210",t.classList.add("done")):w("remaining-n").textContent=String(e),this.lastRemaining>=0&&(t.classList.remove("bump"),t.offsetWidth,t.classList.add("bump")),this.lastRemaining=e}setButtonsEnabled(e){w("btn-hint").disabled=!e,w("btn-route-hint").disabled=!e,w("btn-restart").disabled=!e}handleEvents(e){let t=this.session;if(t){for(let i of e)switch(t.view.onEvent(i),i.type){case"step":i.conflict?(this.sfx.conflict(),this.vibrate(40)):(this.sfx.step(i.step),this.vibrate(i.clueHit?18:8));break;case"rejectStart":this.sfx.reject(),this.vibrate(15);break;case"deadEnd":this.vibrate([10,30,10]);break;case"rewound":i.removed>1&&(this.vibrate(12),this.toast(`\u5DF2\u56DE\u5230\u7B2C ${t.game.stepOf(i.cell)} \u6B65\uFF0C\u53EF\u7EE7\u7EED\u6ED1\u52A8`));break;case"clueRevealed":this.vibrate(18);break;case"cleared":this.onCleared();break;default:break}e.length&&this.updateHud()}}onCleared(){let e=this.session;e&&(this.sfx.cleared(),this.vibrate([20,40,30]),this.progress.markCleared(e.level.def.id),this.setButtonsEnabled(!1),this.activePointer=null,window.clearTimeout(this.advanceTimer),window.clearTimeout(this.exitTimer),this.exitTimer=window.setTimeout(()=>e.view.beginExit(),e.view.clearedHoldEnd*1e3),this.advanceTimer=window.setTimeout(()=>this.nextLevel(),e.view.clearedDuration*1e3))}restart(){let e=this.session;!e||e.game.isCleared||(this.cancelGesture(),this.handleEvents(e.game.apply({type:"reset"})),w("btn-restart").classList.remove("pulse"))}hint(){let e=this.session;if(!e||e.game.isCleared)return;if(this.cancelGesture(),!e.solution){this.toast("\u672C\u5173\u6682\u65F6\u65E0\u6CD5\u8865\u5145\u6570\u5B57");return}let t=W(e.game,e.solution);if(!t){this.toast("\u53EF\u8865\u7684\u6570\u5B57\u5DF2\u7ED9\u51FA\uFF0C\u8BD5\u8BD5\u300C\u6307\u8DEF\u300D");return}this.handleEvents(e.game.apply({type:"reveal",...t})),w("btn-restart").classList.remove("pulse"),this.toast(`\u8865\u4E0A\u4E86 ${t.step}\uFF0C\u7B2C ${t.step} \u6B65\u8981\u5230\u8FD9\u91CC`)}routeHint(){let e=this.session;if(!e||e.game.isCleared)return;if(this.cancelGesture(),!e.solution){this.toast("\u672C\u5173\u6CA1\u6709\u552F\u4E00\u89E3\uFF08\u5173\u5361\u6570\u636E\u6709\u8BEF\uFF09");return}let t=oe(e.solution,e.game.path);switch(e.view.showHint(t),w("btn-restart").classList.remove("pulse"),t.kind){case"start":this.toast("\u4ECE\u8FD9\u91CC\u5F00\u59CB");break;case"next":this.toast("\u4E0B\u4E00\u6B65\u5728\u8FD9\u91CC");break;case"backtrack":this.toast(`\u70B9\u9AD8\u4EAE\u683C\uFF0C\u76F4\u63A5\u9000\u56DE ${t.undoCount} \u6B65`);break;case"restart":this.toast("\u8D77\u624B\u4F4D\u7F6E\u4E0D\u5BF9\uFF0C\u91CD\u5F00\u8BD5\u8BD5"),w("btn-restart").classList.add("pulse");break;case"none":break}}resize(){let e=this.session,t=this.boardWrap.getBoundingClientRect();if(t.width<10||t.height<10)return;let i=Math.min(3,window.devicePixelRatio||1);if(this.cssSize={w:t.width,h:t.height},this.canvas.width=Math.round(t.width*i),this.canvas.height=Math.round(t.height*i),this.ctx.setTransform(i,0,0,i,0,0),e){let n=e.level.board.cols,s=e.level.board.rows,r=n*s<=6?96:110;e.layout=J(e.level.board,t.width,t.height,{padding:10,maxUnit:r}),e.layout.originY=Math.max(10,e.layout.originY-t.height*.03),e.view.layout=e.layout,e.view.invalidate()}this.render()}startLoop(){if(this.rafId)return;this.lastT=performance.now();let e=t=>{let i=(t-this.lastT)/1e3;this.lastT=t;let n=this.session;n&&(n.view.update(i),n.view.isAnimating&&this.render()),this.rafId=requestAnimationFrame(e)};this.rafId=requestAnimationFrame(e)}stopLoop(){this.rafId&&cancelAnimationFrame(this.rafId),this.rafId=0}render(){let e=this.session;this.ctx.clearRect(0,0,this.cssSize.w,this.cssSize.h),!(!e||!e.layout)&&e.view.draw(this.painter)}pointerPos(e){let t=this.canvas.getBoundingClientRect();return{x:e.clientX-t.left,y:e.clientY-t.top}}cellAt(e){let t=this.session;return!t||!t.layout?-1:te(t.level.board,t.layout,e.x,e.y,this.touchPointer?.08:.14)}cancelGesture(){this.session?.input.up(),this.session?.input.cancel();let e=this.activePointer;this.activePointer=null,e!==null&&this.canvas.hasPointerCapture(e)&&this.canvas.releasePointerCapture(e)}vibrate(e){if(this.progress.prefs.haptics)try{navigator.vibrate?.(e)}catch{}}toast(e){let t=w("toast");t.textContent=e,t.classList.add("show"),window.clearTimeout(this.toastTimer),this.toastTimer=window.setTimeout(()=>t.classList.remove("show"),1800)}bindUI(){this.canvas.addEventListener("pointerdown",this.onPointerDown),this.canvas.addEventListener("pointermove",this.onPointerMove),this.canvas.addEventListener("pointerup",this.onPointerUp),this.canvas.addEventListener("pointercancel",this.onPointerUp),this.canvas.addEventListener("lostpointercapture",this.onPointerUp),this.canvas.addEventListener("contextmenu",e=>e.preventDefault()),w("btn-back").addEventListener("click",()=>{window.clearTimeout(this.advanceTimer),this.showSelect()}),w("btn-restart").addEventListener("click",()=>this.restart()),w("btn-hint").addEventListener("click",()=>this.hint()),w("btn-route-hint").addEventListener("click",()=>this.routeHint()),w("btn-continue").addEventListener("click",()=>{this.sfx.unlock();let e=this.progress.clearedCount()>=this.levels.length?this.ids[0]:this.progress.firstUncleared(this.ids);this.startLevel(this.ids.indexOf(e))}),w("btn-sound").addEventListener("click",()=>{this.progress.setPrefs({sound:!this.progress.prefs.sound}),this.sfx.enabled=this.progress.prefs.sound,this.sfx.enabled&&(this.sfx.unlock(),this.sfx.step(1)),this.syncPrefChips()}),w("btn-haptic").addEventListener("click",()=>{this.progress.setPrefs({haptics:!this.progress.prefs.haptics}),this.progress.prefs.haptics&&this.vibrate(15),this.syncPrefChips()}),w("btn-reset-progress").addEventListener("click",()=>{window.confirm("\u6E05\u7A7A\u672C\u73A9\u6CD5\u7684\u901A\u5173\u8BB0\u5F55\uFF1F")&&(this.progress.resetAll(),this.renderSelect())}),window.addEventListener("resize",()=>this.resize())}};new q;})();
|
|
</script>
|
|
</body>
|
|
</html>
|