tylearymf
5 月 26 日
可以,接着你可以这样讲,语气偏“技术分享”,但不至于太论文味:
---
接下来我就把坦克拆成了一个真正的 agent 系统。
它不是每一帧简单判断“敌人在不在前面,在就开火”。如果这么写,前期确实能赢一些弱对手,但很快就会遇到问题:敌人在草丛里看不见、子弹 1 帧飞两格、星星比击杀更重要、地图边缘看起来能走但下一帧必死。
所以我把它拆成三层。
第一层是**感知层**。
每一帧开始时,我先把游戏状态整理成一个 `ctx`。这个 `ctx` 里面有我的位置、方向、敌人的位置、敌人的方向、星星位置、比分、地图、子弹、技能状态。
同时还有一个跨帧记忆 `AG_MEM`。
这个东西很重要,因为游戏里敌人可能会隐身,子弹也可能没有完整方向信息。如果只看当前帧,很容易误判。所以我会记住:
```text
敌人上一次出现在哪里
敌人上一次朝向哪里
子弹上一帧在哪里
我最近走过哪些位置
我是不是刚开过隐身
我是不是在原地绕圈
我刚才有没有开火
```
这一步其实就是把“游戏画面”变成“可计算的战场状态”。
---
第二层是**风险评估层**。
这个阶段我不是马上决定动作,而是先问几个问题:
```text
我现在会不会被子弹打到?
我下一步会不会踩进炮线?
敌人一转头能不能打我?
我走到边缘后还能不能脱离?
我开隐身之后有没有离开暴露点?
我去吃星会不会被草丛反杀?
```
这个地方是后期变强的关键。
比如有一局我以为代码里已经判断了“死路”,但还是跑到了地图边缘被打死。后来复盘发现,那一格从地图几何上看不是死路,因为它还有好几个出口;但从战术上看,它是死路,因为敌人下一步一移动,就能跟我同线,然后一转头开火,而我从那个格子逃走需要两帧。
所以后来我加的就不是简单的 `safeExits <= 1`,而是类似:
```text
如果我走到这个位置
敌人下一步能不能移动到同线?
敌人转头需要几帧?
子弹飞到我这里需要几帧?
我从这个位置脱离炮线需要几帧?
```
如果敌人开火比我脱离更快,那这个格子就算不是墙,也应该判成危险格。
这就是从“地图判断”升级成了“战术预测”。
---
第三层是**优先级仲裁层**。
也就是 `choose()`。
我后来发现,很多坦克代码的问题不是没有策略,而是策略之间会互相抢优先级。
比如:
```text
我想隐身绕后
但现在有子弹飞过来
我想草丛反击
但星星马上要被敌人吃掉
我想追杀敌人
但我已经领先,拖时间就能赢
```
所以我把整个决策链排成了优先级:
```text
先躲弹
再看有没有必杀
再看能不能安全开火
再处理贴星封锁
再处理近星争夺
再处理草丛反击
再处理隐身刺杀
再处理普通追星和移动
```
这里有个很重要的思想:
> 最强的 agent 不是每次都选最激进动作,而是每一帧都知道当前最不能犯的错是什么。
比如子弹来了,那就不要想击杀。
星星马上要决定胜负,那就不要为了绕后丢星。
敌人已经在近距离炮线里,那就不要原地隐身装聪明,要么开火,要么脱线。
---
然后我会讲一个具体例子。
比如草丛反击那一版,最开始的问题是:敌人藏起来后,我的坦克会进入一种“反伏击”逻辑,试图横向脱离或者预判敌人位置。但有时候星星就在附近,这时候最重要的不是躲草丛,而是抢星线。
所以后面我加了一个 `nearStarContestAct`。
它的作用不是“无脑吃星”,而是判断:
```text
星星离我近不近?
敌人有没有可能抢?
我有没有一个安全格可以缩短到星星的距离?
这个格子会不会进敌人炮线?
这个动作会不会被 hidden ambush 逻辑抢掉?
```
如果满足条件,就优先抢星位。
这就是一个很典型的迭代:
不是把草丛逻辑删掉,而是让它在更高优先级的控星逻辑面前退让。
---
然后再讲隐身。
我这辆坦克是 cloak 技能,但我后来发现,隐身不能当万能保命按钮。
很多时候原地隐身其实没用,因为敌人已经知道你上一帧在哪里。你如果隐身后不移动,子弹照样打到你。
所以现在隐身逻辑里面有几个不同模块:
```text
能不能隐身接近
隐身后要不要先换位
有没有机会绕到背线
同线时能不能直接开火
敌人是否已经瞄准我
我是不是为了隐身丢掉星星
```
也就是说,隐身不是一个动作,而是一段战术流程:
```text
开隐身
离开暴露点
绕到安全线
确认敌人炮口风险
再决定开火或继续换位
```
这个也是后面从失败里磨出来的。
---
最后我会讲整个训练闭环。
我每次不是凭感觉调参数,而是这样做:
```text
拉最近比赛
筛失败局
看死亡前几帧
判断是哪类失败
复现那个局面
加一个很窄的规则
跑回归测试
跑模拟
再发布
```
比如一次失败可能最后变成一个新规则:
```text
不要走进边缘同步炮线陷阱
不要让草丛反击抢掉近星争夺
隐身后必须离开暴露点
同线近距离时必须在开火和脱线之间二选一
星星被土堆挡住时,先找破土位
```
这些规则单独看都不大,但叠起来之后,坦克就从“会打架”变成了“会做战术决策”。
---
最后收束可以这样说:
> 所以我觉得这件事最有意思的地方,不是 AI 一次性帮我写出了最强坦克,而是 AI 帮我搭了一个 agent 的思考框架。后面真正变强,是我不断用真实对局去撞这个系统,把每一次输局都转成一个更精确的判断。
>
> 到最后,这辆坦克其实不是靠某个神奇招式赢,而是靠一套越来越完整的决策系统赢:它知道什么时候活命,什么时候控星,什么时候开火,什么时候隐身,什么时候宁可不动也不能犯错。