Knowledge篇(四),让AI玩狼人杀
前言
终于,我们来玩狼人杀了,完整代码见 https://github.com/zong4/AILearning。
游戏规则
规则的话,因为人越多越复杂,所以我这边就只弄了一个丐版的,五个人:三村民,一狼人,一预言,先给大家看一眼初始化游戏的代码。
1 | ROLES = ['citizen', 'werewolf', 'prophet'] |
其中,knowledge_base 是每个人都有的基础知识,相信大家看过上一篇之后,一定懂为什么 knowledge_base 长这样。
然后是游戏流程,天黑 -> 狼人刀人 -> 预言查人 -> 各自发言 -> 各自投票 -> 下一天,代码如下。
1 | def run(self): |
角色实现
主要给大家讲一下基类 Player 吧,剩下的大家可以自行实现,代码如下,完整代码见 https://github.com/zong4/AILearning。
1 | class Player: |
其中最重要的就是这个 get_probabilities 了,它主要是根据当前玩家所有的 knowledge,通过 model_check 来判断其余每个玩家为 target 的概率,然后返回概率最低的和最高的两个。
如果你还不了解 model_check,可以先阅读这一篇。
那基于这个函数我们就能让好人去投票最像狼人的人,也能让预言家去查最像狼人的人,同时也可以让狼人去杀最像预言家的人。
游戏结果
这里给大家随便看一局。
1 | Day 1 |
可以看到这里是狼人(player1)第一晚杀了 player2,是个村民。
然后各自发言,预言家(player0)给 player4 发了个金水。
最后大家各自投票,将 player1 投出,因为 player1 是狼人,所以游戏结束,好人获胜。
后记
优化
如果大家实现完会发现,AI 很呆板,举个例子,我们甚至无法让预言家自由选择何时自曝身份,何时再苟一轮,而这在实际游玩中很重要。
但是大家一定要知道,实现不了不是说 AI 的能力有限,而是我们的能力有限,我们没法给他穷尽这个决策树,我们最多能做到的就是给他一个概率,比如50%去自曝身份,50%去再苟一轮。
而如果想让 AI 更进一步,我们就得进入深度学习的世界(这会放在以后再讲),只有深度学习,才能让 AI 自己通过不断的训练,理解这些变量之间的复杂关系,从而找到最优解。
困惑
最后的话还有我自己的一个困惑,再第一轮中,明明大家对除了被发金水以外的两个人没有任何信息,但却会给他们不同的狼人概率,按理说第一天这两个应该都是0%!!!,应该是弃票的。
下面这六条,第一条是狼人眼中每个人是预言家的概率,第二条是预言家眼中每个人是狼人的概率,第三四六条是每个好人投票时每个人是狼人的概率,第五条是狼人的就不用看了,按理说这里面五条所有的概率都应该是0!!!但是实际结果却不是,这让我感觉非常的困惑。
1 | INFO:__main__:[(<__main__.Prophet object at 0x1035b9f70>, 0.0), (<__main__.Werewolf object at 0x1035bb160>, 0.0), (<__main__.Citizen object at 0x1035bb2e0>, 0.95), (<__main__.Citizen object at 0x1035bb460>, 0.0), (<__main__.Citizen object at 0x1035bb5e0>, 0.0)] |
里面最大的可能是 KB 不完整,也有可能在所有的可能情况下,排除了某些情况后算出来的概率就是这样,不知道有没有概率好的能解释解释。