摘要
状态估计(SE)要根据玩家能看到的公开历史,反推“对手可能是什么构筑、当前隐藏状态可能是什么”。Simulator 提供一个“条件化”服务:在候选世界里按确定的随机数顺序重演公开历史,最多尝试 256 次,找一个与所有观察一致的世界。问题是:一旦某个版本耗尽 256 次预算失败,之后每个新版本都会把同样失败的搜索再跑一遍,每次约 24–30 秒却到不了新证据。本次私下记住“在已验证前缀上的失败”,满足严格条件时直接复用。四条观察序列的额外试验次数从 14448 降到 1648,总耗时从 1629.232 秒降到 189.025 秒;报告内容除计时和本次调用的工作量外完全相同。没有增加任何推断覆盖。
要回答的问题
在不改变任何对外结果的前提下,能否跳过注定重复的失败搜索?
方法
- 每次调用仍先做完整的前缀与菜单校验(这部分成本保留)。
- 只有当新的输入与上次失败时的前缀逐项相同(包括 JSON 数值类型、每个历史合法动作菜单),只是可能更长时,才复用失败;结果仍然是抛出“覆盖不足”,从不返回世界,也不排除候选。
- 为什么安全:当前搜索是前向深度优先,没有向前看的剪枝,所以超出“从未完成的前缀”之外的新约束不会改变它更早的尝试顺序。但新增、删除或修改旧菜单会改变有限预算内的剪枝,必须重新搜索;修正过的事件或观察也会重试。成功一次就清除失败记忆。若将来搜索加入前瞻,这个论证必须重新检查。
- 第二个小优化:同一次调用内,若多次随机试验来自完全相同的父状态和引擎,就不重复投影菜单和检查同一动作合法性;不同父状态照常检查,结果不跨调用保留。
设置与结果
两局完整构筑对局、红蓝两个观察方,共四条序列、130 个前缀。
| 观察序列 | 前缀 | 额外试验 前→后 | 秒 前→后 |
|---|---|---|---|
| case01 蓝 | 35 | 4243→403 | 548.000→48.840 |
| case01 红 | 35 | 4253→413 | 391.129→45.831 |
| case02 蓝 | 30 | 2981→421 | 312.152→43.439 |
| case02 红 | 30 | 2971→411 | 377.951→50.915 |
| 合计 | 130 | 14448→1648 | 1629.232→189.025 |
第一条序列失败之后的重复调用平均从 27.555 秒降到 0.460 秒。加上同父状态复用后,总耗时 189.025→147.407 秒,额外试验仍为 1648,支持的前缀数仍为 76/130(对照基线为 20/130),四条序列都在第 19 个版本失去支持。
测试:新增回归共 11 项(同父状态那一项在改动前实际失败:同一父状态被投影 5 次);与公开条件化及 SE 恢复测试合计 104 项通过。SE 全套 2004 通过/20 跳过;Simulator 全套 11111 通过、68 失败、257 错误、2 跳过,325 个失败/错误 ID 与改动前完全相同;Game AI 全套 6336 通过。
局限
- 计时是本机并发运行,不是受控 CPU 基准。
- 比较的是报告语义,没有把可执行世界状态序列化逐字节比对。
- 这是实现成本的降低,不是推断覆盖的增加,也不上线新默认。
- 扩大审计另发现普通反击中“奈拉之吻”状态在第二击前被覆盖的执行缺陷,这项缓存既不修复也不掩盖它,已单独提出修正建议。
结论与下一步
确定性失败不再重复计算,条件化路径快了约一个数量级,结果不变。覆盖不足(130 个前缀只支持 76 个)仍是主要问题,需要其它手段解决。
Comments