潇大

Jul 07, 2025

游戏科技—通往GGP的道路

用纯粹图像识别的方式,捕捉玩家动作对状态的影响,建模这种关联并采用蒙特卡洛树搜索,寻找那个当下最优的解。
 

控制器主循环框架

自2025年1月中完成了对《砖》的 GGP 过程以后,我就转向到了对《羊》的 GGP 研究。好在之前写《砖》时的识别框架能够复用,让项目的启动曲线变得平缓了些。
这就是被我称之为控制器主循环,它由“感知-识别-响应-执行”各个模块组合而成,可以看成是GGP的通项公式。
感知模块负责从屏幕上找到感兴趣的窗口位置,并获取截图信息。之后识别模块会根据预先训练好的视觉模型,调用模型预测得到结果,这里视觉识别用的 Yolo。
响应模块在接收到结构化的输入之后,调用规划算法得到下一步的动作内容。执行模块则控制鼠标、键盘等,直接与游戏环境做出交互动作。
下图展示了整个控制器主循环的示意图:
notion image
 

非完美信息

然而,事情到了《羊》这里就变得复杂起来。从分类上讲,《羊》属于不完美信息,翻牌之后的内容对于玩家而言是概率性的。因此一些 BFS, DFS 等依赖于完全信息的规划算法就变得不适用了。
针对于每个状态的价值函数,只能求一个期望值。硬算期望是困难的,退而求其次可以用多次采样而后逼近,这里借鉴了 AlphaGo 实现中的一个 rollout 做法。即设计一个规则写的还算可以的策略,然后多次采样,采样过程中同时考虑翻牌的随机性,我称这个过程为 fast_rollout。
在 fast_rollout 过程中,目的是模拟对当前盘面好坏的直觉判断。算法为了追求运行效率,在模拟过程中完全忽略被压住的牌,而将其换成一个等概率函数。这样做牺牲了一点准确性。
 
这就反过来对识别模块提出了更高的要求,即不仅要能识别出当前的牌面,还要能识别出部分被压在下面的牌面信息。
 

牌面识别的迭代

在引入牌面识别前,我先做一个铺垫,讲一下在《砖》中的识别模块是如何做的。在这个例子中,所有待识别的 tile 已经排列成了 10 x 14 的格点形状。因此只需要提取固定坐标偏移量 + 切分,就可以把这个问题转换成一个分类问题。
notion image
唯一的挑战是这个类别并非是固定的,可能随着游戏的进行而逐渐增加。在 Yolo 的分类训练模式下,只需要把素材数据集分门别类建好文件夹,训练就完事了,这对于模型来说简直是小菜一碟的事情。
notion image
 
铺垫结束,聪明的你应该也发现了,这一套在《羊》中行不通,其每天关卡中牌面的位置都是随机变化的,更无法去做固定坐标切分。
这时候,就需要转换思路,将分类任务改为识别任务,找到所有满足要求的牌,就和行人识别差不多。至于怎么样算作“满足要求”,那其实就是需要自己定义,并将其处理为训练样本的东西。
 

Copyright © 2025 潇大

logo