摘要
一场战斗里有左右两方,分别是红方和蓝方。状态估计(SE,把截图观察累积成对局状态和对手构筑推断的程序)需要知道“左边是什么颜色、右边是什么颜色”,才能把行动条上带颜色的部队卡片归到我方或敌方。
颜色有两个来源:一是屏幕顶部角落的玩家头像环(真人对局时有一个带计时器的圆形头像,外环是阵营色);二是 HUD(战场顶部显示双方英雄属性的条)上英雄旗帜的颜色。旧代码让头像环颜色逐帧覆盖,最后一帧说了算;英雄旗帜颜色只在头像环从未读到时才用。
一段和官方 AI 对战的录像(10 月 9 日 08:38)没有玩家头像,固定的头像框里只是偏红的战场背景,于是两侧都被读成红色,红方部队全部被记成敌方。本实验把 SE 的判定改为按“左右颜色配对”投票、要求明确多数,经过两轮外部审阅修正。修好后该局结算画面 14 行由 5 MISSING_END / 9 UNMATCHED 变为 11 MATCH / 1 MISSING_END / 2 UNMATCHED;另外三段录像结果逐字节不变。
要回答的问题
- 08:38 录像为什么把红方部队记成敌方?是视觉识别读错了还是 SE 用错了?
- 怎样决定左右颜色,才能既修好这一局,又不在其它情况下给出错色?
数据与来源
四段已存会话的最新 SE 请求(只读,没有改会话、没有读冻结数据):
| 会话 | 帧数 |
|---|---|
| 训练录像(10 月 10 日 16:57) | 261 |
| 训练录像(10 月 10 日 01:39) | 554 |
| 实时对局(10 月 14 日 23:58) | 268 |
| 官方 AI 对局(10 月 9 日 08:38) | 242;插回 3 张恢复的准备页后 245 |
起因是此前一个准备页修复实验:3 张准备页恢复后 SE 定出我方在左(红方),却把红方部队记成敌方。
方法
先查视觉识别是否读错
用 3 张原始截图裁出头像环框,按生产代码的红蓝像素统计重算:
| 截图 | 左环 红/蓝 像素 | 右环 红/蓝 像素 |
|---|---|---|
| 08:38 截图一 | 796 / 0 | 902 / 0 |
| 08:38 截图二 | 770 / 0 | 1153 / 0 |
| 08:38 截图三 | 698 / 0 | 1145 / 0 |
| 16:57 对照 | 704 / 0 | 4 / 620 |
目视顶部区域:08:38 两侧框里根本没有头像环,是红色调的战场;16:57 两侧各有带计时器的圆形头像。所以右侧读成红色不是颜色阈值错,而是这段录像里没有可读的对象。
视觉识别其实已经正确拒绝了:这些帧的头像状态全是“未知 / 战斗布局未确认”(它要求两环恰好一红一蓝才算确认),只是按合同仍把原始观察值保留下来。改视觉识别会改变所有会话的输入,不是安全的小修,所以没动。问题在 SE 把未确认布局下的观察当成了定论。
在 08:38 全部帧里,头像环两侧都读成红色;而 HUD 英雄旗帜颜色是左红 191 帧、右蓝 191 帧。旧代码用环覆盖后得到“左红、右红”,最后红色被归到敌方。
改动:按配对投票(只改 SE)
最终做法(第三轮):
- 配对票:一帧里两侧读成两种不同颜色,就为这个(左色, 右色)配对投一票,每帧一票。来源有两种,同权:HUD 上两个英雄都有颜色(有没有识别出英雄身份都算);头像环帧,且视觉识别确认了布局。
- 明确多数:票数最多的配对至少是其它配对票数总和的两倍才定;否则两侧都记为未知。
- 单侧读数(一帧只读到一侧颜色)只在完全没有配对票时才使用,同样要明确多数;两侧得出同一颜色则两侧都未知。单侧读数从不推翻已定的配对。
- 两侧同色的帧、布局未确认的环帧、出错的帧都不计票。
- 某侧最终未知、有计票读数和最终结果相反、或出现两侧同色帧时,在结果里写一条“阵营颜色冲突”说明,列出全部票数和原因。
颜色映射之后的用法(行动条部队、战场部队、减员时间线)不变;结果格式的字段不变。
为什么改了三轮
- 第一轮:按来源优先级(有身份的 HUD → 环 → 无身份的 HUD)每侧取第一个有颜色的来源。外部审阅用合成场景指出:一帧有身份的 HUD 误读就能压过 40 帧确认的环;未确认的单侧环仍在计票;两侧同色时直接丢掉一侧,可能把红方当敌方。
- 第二轮:每侧分两级各自按明确多数定。第二次审阅又指出:10 帧 HUD 左红右蓝 + 40 帧只读到右旗且读成红色时,右侧红色 40:10 胜出,两侧同红,又把我方红军当成敌方——而旧代码在这个场景反而是对的;另外 191 帧无身份 HUD 对 3 帧颜色互换的确认环时会判错;某侧唯一证据是未确认单侧环时被置未知却没有说明。
- 第三轮:改成按配对投票,即上面的做法。四段真实录像里没有一帧是无身份的 HUD 英雄,没有数据支持给它不同的权重,所以同权。
设置
改前用当前提交导出的 SE 源码,改后用修改后的源码,同一份输入、同一环境,限 4 核运行;比较完整 SE 结果。合成场景脚本分别用旧代码、第二轮和第三轮源码运行。
结果
真实会话
| 会话 | 改前 vs 第三轮 |
|---|---|
| 16:57 | 文件逐字节相同 |
| 01:39 | 文件逐字节相同 |
| 23:58 | 文件逐字节相同 |
| 08:38 原请求(无准备页) | 只多 1 条冲突说明;我方所在侧仍未知 |
| 08:38 插回 3 页 | 1558 个路径不同,全部来自颜色映射 |
三段一致的会话里,环颜色和 HUD 颜色从不矛盾,所以映射不变、也不加说明。
08:38 插回 3 页后:
| 改前 | 改后 | |
|---|---|---|
| 颜色映射 | 左红、右红 | 左红、右蓝(配对红/蓝 191 票,全部来自有身份的 HUD) |
| 敌方行动条部队 | 9 种,全是红方 | 7 种,全是蓝方 |
| 减员时间线 | 我方 8 堆、敌方 18 堆 | 我方 16 堆、敌方 16 堆 |
| 结算画面 14 行 | 5 MISSING_END、9 UNMATCHED | 11 MATCH、1 MISSING_END、2 UNMATCHED |
(结算画面是战斗结束时列出双方部队开局与剩余数量的界面;MATCH 指 SE 的部队与结算行对上,MISSING_END 指缺结尾数量,UNMATCHED 指对不上。)剩下 2 行 UNMATCHED 是两种开局都是 52 的兵种按数量无法唯一对应,属于预期的保守;1 行 MISSING_END 是敌方刺客 95。之前准备页实验报告里写的“12 MATCH”是笔误,诊断输出实为 11 MATCH。
合成场景(部分)
每个场景的真相都是左红右蓝。“对”= 敌方部队为蓝方;“未知”= 敌方颜色未知、部队为空;“错”= 把红方当敌方。
| 场景 | 旧代码 | 第二轮 | 第三轮 |
|---|---|---|---|
| 无身份 HUD 左红右蓝 + 右侧单环背景红 | 错 | 对 | 对 |
| 同一兵种两种颜色 | 错 | 对 | 对 |
| 40 帧确认环 + 1 帧单侧 HUD 左蓝 | 对 | 对 | 对 |
| 10 帧 HUD 左红右蓝 + 40 帧只右旗红 | 对 | 错 | 对 |
| 191 帧无身份 HUD + 3 帧确认环互换 | 错 | 错 | 对 |
| 两局颜色互换 3+5 / 5+3 帧 | 对 | 未知 | 未知 |
| 3 帧只左红 + 40 帧只右红 | 错 | 错 | 未知 |
| 191 帧左红右蓝 + 100 帧确认环互换 | 错 | 未知 | 未知 |
| 5 帧带红蓝观察的出错帧 | 对 | 未知 | 未知 |
完整场景表(22 行、23 个场景,含上表未列的)里第三轮都不给出错色。相对旧代码由“对”变“未知”的场景,要么是旧代码碰巧取对(例如取了先见的那一局),要么只有未确认或出错的环读数,要么票数够不上明确多数(如 8:5);它们都带说明。
软件测试
| 轮次 | 结果 |
|---|---|
| 第一轮 | 新文件 8/8;相关 99 通过;扩大 1024 通过、12 跳过;App 重算 15 通过 |
| 第二轮 | 新文件 17/17;相关 85 通过;扩大 1043 通过、12 跳过 |
| 第三轮 | 新文件 21/21;扩大(50 个 SE 测试文件 + 1 个集成文件)1047 通过、12 跳过 |
12 个跳过是本机没有符号链接权限。第一轮有 3 个 App 测试在独立工作副本里因找不到运行环境失败,与改动无关,未计入。
失败与负结果
- 第一、二轮的做法都被审阅用合成场景推翻,第二轮甚至在两个场景里比旧代码更差;两轮记录都保留。
- 08:38 插回准备页后,有 21 个路径的差异来自一个限时 0.5 秒的英雄升级组合搜索没搜完,属于计时相关,与本改动无关。
局限
- “至少两倍”的明确多数阈值是人为选择。同一请求里真的混了两局且颜色互换时,两侧都会变未知,比猜一边保守。
- 如果 HUD 旗帜颜色本身系统性地读反,而确认的环帧又不到 HUD 帧的一半,本改动会跟着错;目前四段录像的 HUD 颜色全部一致。
- 只靠未确认环或出错帧才有颜色的一侧现在是未知;真实会话里每段都有 191–442 帧的 HUD 配对,不受影响。
- 冲突说明只在结果数据里,App 界面目前不显示。
- 已存会话不追溯;需在 App 里“仅重算 SE”(08:38 还需先重读那 3 张准备页)。
- 08:38 的对手类型仍被判成“玩家”(日志里敌方名读成“英雄”),属日志名读取问题,未处理。
结论与下一步
阵营颜色现在由左右配对的多数票决定,没有玩家头像的录像不再把背景色当成阵营色;三段真实录像结果不变,官方 AI 对局的部队归属和结算对照得到恢复。后续可以考虑在 App 的推断说明里展示颜色冲突说明,以及修正官方 AI 对局的对手类型识别。
Comments