from pathlib import Path import json,html,csv,hashlib root=Path(r'G:\项目\NumberSwipe-Variants');out=root/'design/demo-50';plan=json.loads((out/'demo-design.json').read_text(encoding='utf-8'));levels=plan['levels'];names={'big':'大格/异形','walls':'墙','direction':'方向','alternation':'双色','parity':'奇偶','rhythm-door':'步进门'} def mech(l):return '+'.join(names[f] for f in l['features']) or '数字基础' intro='''# NumberSwipe 50关DEMO设计与难度曲线 版本:2026-10-14 v1。面向首次接触的新玩家,目标是验证趣味性、规则理解与章节节奏。当前交付是关卡制作任务与目标曲线,没有具体坐标、作者解或50关可玩包。 ## 研究如何适配本项目 研究正文来源:G:/下载/NumberSwipe_Research_H5.html。源文件SHA-256记录在demo-design.json;报告中的外部Zip统计未在本项目复算。采用有效分叉、区域风险、错误发现延迟、目标跨度、逻辑依赖和视觉操作负担的分层思路。公式权重、章节8/9/10节拍及报告首通指标均是待测假设。 本项目数字表示绝对访问步号,不能将Zip的编号升序直接迁移。每个拼块一步、每格恰好一次、共边移动、完整有序解唯一。按节点数量使用5–19格,不迁移研究报告6×6/7×7的面积规模。普通方格固定起点下目标格奇偶由天然二分图固定,奇偶优先放在大格或无双色的六边盘。双色严格交替时不叠加奇偶。方向通道仅用于单位方格整盘。步进门空盘关、起点也切换,出发前判门位、撤销恢复。单位方格门题主要判断通过方向;通过大格或含三角邻接的六边图才强调不同路线的到达状态。 保留当前五个原型及已认可的40关作为参考,不恢复相对步差、先后链、窗口或开关格。当前Variants没有奇偶判定,双色启用仍依赖mode名称:组合主线落地需独立增加features开关、奇偶判定/提示/求解器/必要性检查,并限制图示与实际规则一致。本轮不修改这些运行代码,不调整手机体验。 ## 节拍选择 默认A:每10关第8关峰值、第9关释放、第10关收束。新机制采用演示→练习→变化→组合→巩固的五关单元;不要求每个10关章都新增规则。 B为对照:同一套题,把各章第8关移到第10关,9/10关前移为8/9。A/B拥有完全相同关卡ID和内容,只改变顺序。首次制作先校验A,再与B比较。不是随机动态调难。 前两关完成操作教学;大格与墙在1–10关;方向与双色在11–20关;奇偶与门在21–30关;六边迁移在31–40关;最后10关只深化组合。保留两次起点未知(37、38),不把起点未知作为所有关卡的固定难度旋钮。 目标分0–100是策划标尺,不是搜索节点数、通过概率或玩家实测难度。各章目标峰值40/46/50/58/72,最后一关54分收束,不在50关耗尽难度上限。释放题也必须有可解释的选择,避免机械蛇形或连续闭眼画。 ## 五章目标 | 关卡 | 阶段 | 新内容 | 峰值关/目标分 | |---|---|---|---| | 1–10 | 覆盖、大格与墙 | 大格一步、永久墙 | 8/40 | | 11–20 | 方向与双色 | 六种明确通道、换颜色 | 18/46 | | 21–30 | 奇偶与步进门 | 步号奇偶、每步切换门 | 28/50 | | 31–40 | 六边迁移与起点推理 | 六向邻接、未知起点 | 38/58 | | 41–50 | 组合应用与收束 | 不新增规则 | 48/72 | ## 最新项目研究补充与桥接验证 已纳入原项目docs/一笔画竞品调研与关卡编排方案.md、2026-10-14补充的《一笔画深度调研-制作与难度证据.md》及45关结构审计JSON。该审计针对原项目26数字关+19六边关;本次另行读取Variants的40关,二者不能混为同一题库的验收。 技能依赖:覆盖/纠错→大格计步→枢纽出口→异形共边;基本共边→横竖端口→明确拐角→方向联合;精确步号与实际拼块图→单奇偶→双奇偶;步号与撤销→起步切换→通过方向→大格到达状态;熟悉墙→六向共边→旧规则迁移。未知起点依赖端点和步号推理,先小盘专项。 先制作并测试6道桥接样题,均计入50关: |设计号|验证任务|控制变量| |---|---|---| |05|异形共边|只增加L形读盘,不叠奇偶或未知起点| |13|拐角端口|只增加一种明确拐角,能解释反向通过| |18|双色与墙联合|先掌握16/17,再测试异色出口保留| |21|单奇偶|按节点计步,条件必要,不靠天然属性| |24|双奇偶与区域|先掌握21–23,每条条件各自有效| |28|大格与门位|先掌握26/27,检查实际步数关系| 教学测试按课程顺序。难度校准先让玩家学会对应规则,再交错代表题,避免把学习熟练或记忆同盘答案误判为题更容易。四层去重分别检查外观几何、真实邻接、约束配置、关键解法;几何相同且推理不同可以少量保留,四层等价仅限明确强化用途。 ## 逐关制作任务 表中格数、约束预算与曲线为候选制作目标;盘面通过验证与试玩之前都不能标记为完成。格式是设计任务数据,不是游戏可直接读取的关卡JSON。 ''' md=intro for ch in plan['chapters']: md+=f"\n### 第{ch['id']}章 · {ch['title']}\n\n{ch['focus']}。\n\n|关|标题/功能|格数|机制|目标分|核心任务|\n|---:|---|---:|---|---:|---|\n" for l in levels[(ch['id']-1)*10:ch['id']*10]:md+=f"|{l['displayOrder']}|{l['title']} · {l['role']}|{l['nodeCountTarget']}|{mech(l)}|{l['targetDifficulty']}|{l['teachingGoal']}|\n" for l in levels[(ch['id']-1)*10:ch['id']*10]: md+=f"\n#### {l['displayOrder']:02d} · {l['title']}\n\n- 盘面:{l['layoutIntent']}。\n- 条件预算:{l['constraintsBudget']}。\n- 顿悟:{l['teachingGoal']}。\n- 诱惑路线:{l['temptingRouteIntent']}。\n- 排除依据:{l['rejectionReason']}。\n- 目标:分值{l['targetDifficultyBand'][0]}–{l['targetDifficultyBand'][1]};有效关键选择{l['targetDecisionCount'][0]}–{l['targetDecisionCount'][1]}处;最长依赖约{l['targetDependencyDepth']}层;思考时间P50候选目标{l['thinkingSecondsP50Target'][0]}–{l['thinkingSecondsP50Target'][1]}秒。\n" if l['sourceCandidates']:md+='- 原型参考:'+', '.join(l['sourceCandidates'])+';仅作构造参考,不能视为可直接复用。\n' md+=''' ## 51–100关及正式版衔接 50关验证后,先依据真人数据修改题与关序,再扩展51–100。优先用区域拓扑、空洞、对称/破对称、枢纽先后和线索位置开发新题,不要求增加规则或继续扩大盘面。每个新章先安排熟悉规则的热身,再形成局部峰谷;不规定第51关必须难于第50关。 优质DEMO题作为内容资产复用,正式首发前统一筛选重排。过难题可移入挑战包。上线后新增章节与主题包,旧内容只进行有依据的局部修正。levelId首次分配后保留;显示顺序由章节manifest决定。规则实质变化增加contentRevision,完全替换题目分配新ID。保存通关进度和分析记录时绑定ID与修订,不能只绑定第几关。 ## 交付与状态 - index.html:离线规划页,筛选逐关任务、切换A/B曲线、查看详细设计。 - demo-design.json:50关任务、稳定ID、章节与A/B关序,所有任务标记design-only。 - difficulty-curve.csv:目标曲线与A/B位置;实测难度列留空。 - VALIDATION_PLAN.md:难度定义、机器人策略、机制必要性与真人测试标准。 - project-snapshot.json:现有40关的结构快照,只是几何指标,不是人类难度。 - plan-check.json:设计表一致性检查,不是50关唯一解验收。 本轮没有制作50个坐标盘面,没有给出真实作者解,没有完成真人难度或手机测试。 ''' (out/'DEMO_DESIGN.md').write_text(md,encoding='utf-8') (out/'VALIDATION_PLAN.md').write_text('''# 制作与难度验证规划 ## 1. 三类难度分开保存 - targetDifficulty:策划目标分,当前有值。 - staticFeatures / simulatedFeatures:盘面完成后采集,当前为空。 - humanDifficulty:真人数据校准后填写,当前为空。 报告权重0.25B+0.25C+0.20R+0.15S+0.10U+0.05V是候选,不直接作为排序真值;本轮不实现未经校准的综合评分器。所有指标保存规则/模型版本。不同机制的搜索节点数不可未经校准直接比较。 ## 2. 指标的操作定义 |指标|测量办法|限制| |---|---|---| |有效决策数B|在固定策略机器人遇到至少两种未被其已掌握规则排除的移动时,记录一次决策|不是原始邻接度>=3的节点数量;不能用完整求解器提前认出唯一解再计数| |强制比例F|固定策略机器人独立通过局部移动、固定步号及已掌握规则确定的追加数/总追加数|不能把唯一解中的所有步当成强制步;不能将度2比例视为F| |封闭风险C|每个诱惑移动是否会切断剩余潜在图;记录局部可见或需跨区推断|门的潜在连通图保留未来可开的边,双色和永久墙按各自静态限制处理| |错误发现延迟R|按约定诱惑策略,从首次偏离到出现可解释矛盾之间的追加数|分别记录自动冲突、局部死路、区域矛盾;不是撤销次数| |数字跨度S|固定数字按步号排序的相邻差和最后尾段;同时保存最长未确定段|不使用空间距离;奇偶不等同固定数字| |推理依赖U|人工说明中为确认关键选择需要连续使用的前提层数|先由策划标注,真人口述核对,不由机制数量替代| |视觉操作V|路径转向、标记密度、边界歧义、触点与跨块连线可读性|与逻辑难度分开,手机优化留到玩法验证后| ## 3. 机器人方案(待实施) A局部策略:固定数字与基本操作约束优先,倾向较近线索、少出口及边缘;不访问完整答案,记录诱惑选择与回退。策略、候选排序和随机种子固定,便于复现。 B规则策略:在A基础上使用端点/剩余区域连通/通道配对/拼块计步/奇偶/颜色/门位推理;逐项记录所用规则与推理次数。只评估定义范围内的推理,不能宣称等价人类。 C完整搜索:确认完整有序解唯一,解除约束生成反例,记录搜索规模与耗时。C的节点数只作计算诊断,不等于真人难度。 ## 4. 盘面发布门槛 每关结构合法、完整解唯一;无1时搜所有起点;每条奇偶、每个方向通道、每堵墙、门、全局交替要求逐项解除后至少两解;辅助数字逐项删减,教学保留需写理由。约束预算是候选目标,不能为了凑墙数或标记数保留冗余。 主线支持features显式启用,必须由规则、操作、求解、提示共用判定。禁止把当前mode名称判双色的逻辑直接复制到组合主线。奇偶原始格不与数字同格;不可依靠天然方格或双色奇偶做无效装饰。方向只适用单位方格整盘;大格和六边不继承lr/du等端口判断。 步进门最多一道,空盘关,起点也切换;出发前判位、落格后切换;回退和重开恢复。单位方格固定起点的天然奇偶不因绕路改变,门题不写成任意绕一圈就能补拍;需要可变到达步号关系时用大格或三角邻接六边盘。 组合必须有明确的跨机制推理,并记录解除每一项后的完整反例;唯一解通过但主要靠枚举、长段机械填满的题仍须重做。 ## 5. 玩家测试(待实施) 先找3–5名新玩家定性测试规则解释与明显枯燥点,再组织更大样本进行50关分会话测试。每关20–30人可暴露明显问题,不用于精确估计低频退出或A/B显著性;A/B需要根据实际方差和所需效应另算样本量。 记录实际开始、首次落格、首次偏离、冲突被发现、回退、重开、提示、完成、离开、下一关启动和下一会话返回。仅本地导出记录,不在本轮加入自动网络上传。 第一次尝试:从首次起手到首次重开、提示或结束;分别记录是否含回退。首次无提示且无回退完成、允许回退的无提示完成、最终完成分开统计,避免成功率口径混乱。 思考时间:从盘面可读到首次落格,加上绘制途中思考停顿的候选口径,后台时间剔除;另存开始到完成总耗时。暂停阈值需在原型事件采集前固定,当前设计时间目标不与总耗时混用。 单关统计P50/P75/P90时间、错误发现延迟、回退、提示、开始后退出、完成后下一关启动。退出分为卡关、无聊、正常结束会话、操作/显示问题,结合短口述或选择项;不能把退出全部解释成难度。 先以实际测量修正排序,不用本方案的秒数直接判定成败。教学关目标是理解规则;挑战关目标是可解释推理;释放关目标是减少负担并保持兴趣。重点检查8/18/28/38/48峰值,以及其后两关是否让玩家愿意继续。 A/B关序保持完全相同题库:A第8峰值、9/10释放;B把峰值移至章末。用户首次参与时固定分组,不在同一玩家每章切换,避免学习效应。比较完成后下一关启动和后续会话返回,同时检查新规则理解、提示与卡关退出;未达样本前只作定性观察,不宣布最优。 ## 6. 数据契约(规划,不是运行关卡) 设计任务记录levelId、designKey、教学任务、候选几何/机制、目标分/目标带、目标关键选择与依赖、制作状态。具体cells/walls/doors及作者解只有制作完成才填写到独立关卡包。 关序manifest维护ID数组,A/B互为同集合排列。已发题重排不清空已通关进度;实质规则改变有revision;替换为新谜题分配新ID。 当前交付不承诺平台、网络、广告或周期上线日期。先做玩法曲线验证,再安排手机体验和release内容生产。 ''',encoding='utf-8') # Minimal static SVG: target scores only, no inference that it is a measured curve. def curve(ids): lookup={l['levelId']:l for l in levels};seq=[lookup[i]['targetDifficulty'] for i in ids];W,H=1060,320;L,T=50,20;pw,ph=990,245 parts=[f''] for v in (0,20,40,60,80,100):y=T+ph*(1-v/100);parts+=[f'{v}'] for pos in (1,10,20,30,40,50):x=L+pw*(pos-1)/49;parts+=[f'{pos}'] for c in range(5):x=L+pw*(c*10)/49;parts+=[f''] points=' '.join(f'{L+pw*i/49:.2f},{T+ph*(1-v/100):.2f}' for i,v in enumerate(seq));parts+=[f''] parts+=['目标分 · 非实测 · 关序位置'];return ''.join(parts) (out/'curve-a.svg').write_text(curve(plan['orders']['A']['levelIds']),encoding='utf-8');(out/'curve-b.svg').write_text(curve(plan['orders']['B']['levelIds']),encoding='utf-8') print('Markdown specification, validation plan and A/B SVG curves written.')