这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
7.1 三消的机制解剖
把三消的五个机制字段——棋盘、交换、消除、掉落、连锁——各绑到 core/genre/match3.ts 里一段确定性代码,用一张字段表把机制名词与可断言实现对齐:规格骨架与 play_spec.json 同构、只覆盖 rules / params 两段,W 层把字段画进单文件 HTML 并真玩,P 层逐字段断言,两处 digest 与基线逐字一致。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
把三消的五个机制字段——棋盘、交换、消除、掉落、连锁——各绑到 core/genre/match3.ts 里一段确定性代码,用一张字段表把机制名词与可断言实现对齐:规格骨架与 play_spec.json 同构、只覆盖 rules / params 两段,W 层把字段画进单文件 HTML 并真玩,P 层逐字段断言,两处 digest 与基线逐字一致。
把波次强度 waveHpStep 从 0 往上推,用粗扫 + 二分找「防守被解开」的临界点:临界点是 14,两侧胜率 13→937‰、14→343‰、15→0‰,临界宽度只有 1;粗扫 + 二分只用 7 格 224 run 就钉到,占步长 1 全网格的 114‰,并给出二维网格超预算时退回采样的判据。胜率是代理指标,只做相对比较。
把塔防的「塔位 × 塔种 × 升级次序」枚举成策略空间:忽略花费剪枝的上界 271453 经剪枝压到 529 条可达布防,空间熵 9046、结果分布熵 2293、支配缺失度 331‰;全配置上界 469070941 远超枚举上限,只能按索引采样 512 次,并给出「何时改用采样」的判据。熵与支配度是代理指标,只做相对比较。
把塔防的五个机制字段——路径、波次、索敌、塔位、升级——各绑到 core/genre/towerdefense.ts 里一段确定性代码,用一张字段表把机制名词与可断言实现对齐:规格骨架与 play_spec.json 同构、只覆盖 rules / params 两段,W 层把字段画进单文件 HTML 并真玩,P 层逐字段断言,两处 digest 与基线逐字一致。
把牌组规模当成被扫的构筑参数:往《灰烬牌库》里加废牌,牌组从 12 张膨胀到 32 张,128 个种子上的胜率从 1000‰ 掉到 46‰。粗扫步长 4 框住跨越 500‰ 的区间 [20, 24],二分 2 轮钉出临界牌组规模 22,与步长 1 的全网格逐个一致;相变带宽 13,2688 次 run 实跑约 28 毫秒。
把构筑的方差量成整数:精确枚举 C(12,5)=792 种起手,三副牌组的起手强度方差相差 5.8 倍;「均匀」与「起伏」两副牌起手期望完全相同(均值 30),方差却是 12727 对 57272,胜率一样而结束回合的方差相差 2.3 倍——方差不是坏东西,它是节奏的来源。
把《灰烬牌库》的五个机制字段——洗牌袋、抽牌、出牌、能量、弃牌——各绑到确定性内核里的一段代码,用一张字段表把机制名词与可断言的实现对齐:W 层把五个字段画进单文件 HTML 并真玩,P 层逐字段断言,两处 digest 与基线逐字一致,W 层 3 断言、P 层 7 断言全绿。
区间要变成决策,判据必须是三态而不是两态。本节用整数判据输出通过 / 不通过 / 样本不足:先看半宽之和能否分辨 Δ,再看点差够不够。实跑三个案例恰好各出一态,其中小样本案例点差高达 375‰ 却被诚实地判为「样本不足」,而参数微调案例点差为 0 判不通过。
样本量决定「看得见的最小差别」。本节把样本量落到整数 Wilson 区间上:对占比类可解率用 z=2 的整数近似(isqrt,非 1.96),对非占比类用块极差;六档种子数实跑显示半宽之和从 n=8 的 545‰ 收到 n=256 的 117‰,刚好跨过 Δ=150‰。
「我想验证难度会不会太高」不是假设,是愿望——它没法被判伪。本节把测试目标写成可机检的五元组:指标、方向、阈值、样本量与一对互斥命题;先做可证伪性自检,再用 32 个种子的试点反推所需样本量,实跑得 nRequired=256,与设计门槛 Δ=150‰ 对齐。
把「种子 + 整段策略序列」编码成可回放的链接片段 #s=301&seq=...,页面读取 location.hash 后逐字重现同一局。本节给出编解码契约、页面侧 replay() 的三步、以及回放一致性的断言:Python 侧重跑与 Node 构建期 digest 逐字相同,再编码必须无损。
在无头浏览器里真的玩一局:注入的是整段 25 条策略序列,不是逐帧点按;断言的是胜负与状态(won / over / enemyHp / dealt 与不变量),而不只是一条摘要。页面 digest 必须与 Node 侧 digestSnap(runSpec(...)) 逐字相同——同一段源码的两个宿主本就该给出同一个答案。
把 config/play_spec.json 与 core/src/ashdeck/ 的五个确定性内核模块塞进一个自包含 HTML:无构建工具、无网络、无外部 script,拷走一个文件就能玩。本节给出构建脚本与产物级断言——页面里内联的规格必须与磁盘上的规格逐字段相等,任何外部引用都会让「可离线、可分享」失效。
原型最大的风险不是做不出来,而是做不完:范围一旦失控,迭代就变成无限拉锯。本节给「该停了」两条可算的判据——连续 3 轮代理指标无变化即停、总轮数上限兜底——并真跑到触发为止:主循环停在第 5 轮,抽掉唯一让指标动过的那轮后 control 停在第 3 轮。
迭代循环只有三步:改一个参数、跑一次内核、重跑一次原型。一轮的代价是可数的——规格里改 1 行、内核跑几微秒、代理指标重采样几百微秒。本节用 5 轮真实迭代给出这个代价,并用一个负例(energyMax 改成 -1)演示不变量断言如何拦住坏参数。
数字原型的最小内核不是「写得少」,而是「可数的少」:一份 config 进、一条 digest 出,5 个模块、4 条不变量、本版 134 行运行时逻辑;单局 4 微秒是原机历史记录。本节把「最小」换成三条可数判据——多少行、几个不变量、跑多久,并用 P 层断言与 S 层实测把它钉死。
三卷本收官清点:150 节正文加一条跨语言工具链(config / sim / core / web / out 七个目录),三卷各留一份交接产物;说明三条使用入口——照着读、照着复现、换成自己的规格当模板;划清边界——机制侧可算,主观体验只能用代理指标做相对比较,美术 / 性能 / 网络 / 商业化需真实业务环境(X 档);最后交代三个后续方向,并让三卷的三个问题在此闭合。
把 16.1 检查表里最硬的一条展开成全链路回放:从 config/play_spec.json 出发,在 S 层 Python、P 层 TypeScript、W 层浏览器与第 13 章六个品类变体上各取一次 digest,证明逐字相同;再给出 B 层稳健性证明——只改一个规则参数 energyMax,链上三处宿主同步改变且仍逐字一致。附四个节点的 digest 对照表与六个变体的结果摘要。
把三卷 150 节的产物汇成一张可勾选的检查表:三卷各回答一个问题,每项给出证据路径、真命令、通过判据与档位(S/P/W/D/X/B)。检查表本体是数据文件,执行器逐项核对产物是否存在、档位是否合法;X 档一律显式标注「需真实业务环境,命令行不可复现」。19 项全部 ok、fail=0,本节也说明检查表为什么不能写成许愿池。
把 13.3 如实记下的三处保留逐条分类并给出处置:平台跳跃种子轴惰性是设计使然、不是缺陷;塔防种子轴只有 10 桶是真实区分度不足、可改进但不是 bug;「胜率不得为 0‰ 或 1000‰」这条直觉判据被实测证伪、是判据本身错。同时划清闸门的诚实边界:它只覆盖机制侧,玩家体验、美术、性能、网络、商业化需真实业务环境。