【译】在纸牌游戏中教人工智能说谎

175 阅读14分钟

在本文中,我将探讨我是如何做到这一点的,以及在设计人工智能来玩基于社交推理的纸牌游戏时我必须考虑哪些因素。我还将讨论该项目的发展方向,以及您作为 AI 开发人员可能会考虑构建游戏系统的潜在方法。

我选择建模的游戏是 Bezier GamesOne Night Ultimate Werewolf。这是一款以流行的狼人和黑手党派对游戏为蓝本的社交推理游戏。对于那些不熟悉的人,我将在下一节中简要概述规则。

我选择使用 C# 和 dotnet 将此系统实现为类库。还使用 Windows Presentation Foundation (WPF) 构建了一个桌面应用程序来显示游戏的状态,尽管这主要用于演示目的和捕获我的单元测试未发现的问题。

显示一夜终极狼人游戏的应用程序

该项目的代码可在其GitHub 存储库中免费获得。

让我们来谈谈这个游戏是什么,我在为它构建早期 AI 时做出的决定,概率因素如何影响它,以及项目从这里开始的方向。

一夜终极狼人简介

如果您已经熟悉 ONUW 及其规则,请随意跳过本节。

与 Werewolf / Mafia 不同,One Night Ultimate Werewolf (ONUW) 旨在在不到 15 分钟的时间内快速解决。

该游戏可以与 3 名或更多玩家一起玩,并且您玩的牌总数要大于实际玩家。

游戏结构

游戏本身分为几个关键阶段:

  1. 设置- 每个玩家发一张牌面朝下,其余 3 张牌放在中间,如下所示:

游戏设置

  1. 夜晚- 每个玩家都闭上眼睛,然后播音员(通过官方AndroidApple应用程序提供)指示玩家醒来并根据他们的初始角色轮到他们
  2. 白天- 所有玩家都睁开眼睛讨论他们认为晚上发生的事情,他们声称自己是谁,以及谁可能是狼人
  3. 投票——经过足够长的时间后,解说员会提示玩家指向他们想要投票的玩家。
  4. Endgame - 得票最多的玩家被视为死亡。他们的牌被翻过来。如果至少有一个是狼人,则好队获胜。否则,邪恶的团队获胜。

注意:如果没有分配给玩家的狼人,所有玩家仍然可以通过确保没有玩家获得超过 1 票来获胜。

角色

每张卡片都是游戏中的一个角色,它控制着你在哪个团队以及你在夜间阶段可能执行的操作。

一些示例角色包括:

  • 狼人- 邪恶角色之一。你试图在游戏结束时不被票出
  • 先知- 可以查看中心的 2 张牌或 1 名玩家的牌
  • 梅森- 好人(总是包括 2 名梅森),他们可以看看另一个球员是否也是梅森
  • 捣蛋鬼 - 好人,可以在不看的情况下交换 2 张其他玩家的卡片
  • 强盗- 好人,可以在夜间阶段与另一个玩家交换他们的牌,并在此过程中查看他们的新牌
  • 村民- 没有特殊能力的好人

在 ONUW 的不同扩展之间列出的角色要多得多,但这些传达了游戏的一些复杂性。

新玩家错过的一个关键因素是,你不仅要弄清楚其他玩家是谁开始游戏的,你还要弄清楚你是否仍然是你开始时的角色,因为你可能已经被调换了在那个阶段进入不同的团队。

如果您想查看一夜终极狼人的示例游戏,请查看发明者的 YouTube 频道中的示例游戏视频:

如您所见,真实版本的狼人杀中有很多角色互换、虚假声明和指控。

如果你想看到更多的游戏攻略,我强烈推荐优秀的Bouncin Mouncin YouTube 频道,该频道多年来制作了 200 多部高质量的游戏游戏攻略视频。我们想你。

项目目标

我在这个 AI 项目中的目标是看看我是否可以创建一组 AI 来互相玩游戏并模仿人类策略(并调整它们自己的策略)以一种引人入胜且类似人类的方式玩游戏。

但由于其复杂性,这是一个具有挑战性的项目。在狼人杀游戏中,每个玩家必须记录:

  • 他们开始时扮演什么角色
  • 他们在夜间采取了什么行动
  • 他们认为自己现在是什么角色
  • 他们自称对他人扮演什么角色
  • 他们声称他们在夜间采取了哪些行动
  • 他们对彼此球员的信任程度

限制范围

一次承担太多,所以我选择显着限制我的范围。

首先,我决定避免一开始就添加像捣蛋鬼这样可以在夜间移动卡牌的角色。这简化了为 AI 提供动力的概率引擎的第一个版本。

其次,我决定限制 AI之间的交互方式。 我决定每个 AI 都应该声明一个角色,声明他们采取的行动,然后表达对其他人以及他们计划投票给谁的怀疑。之后,投票阶段将开始。

将社交互动限制在更正式的过程中可以使任务易于管理,尽管它确实引入了比 ONUW 游戏中通常存在的更多的顺序和结构。

第三,对于初始版本,村队中的AI玩家总是说实话。这确实让邪恶的团队更容易获得不在游戏中的角色,但它也使确定玩家是否值得信赖的初始任务变得容易得多,因为在 ONUW 的真实游戏中,村队中的玩家经常会撒谎试图用糟糕的谎言诱骗邪恶的玩家。

所有这些战略决策使得构建 AI 可以玩的 ONUW 模拟的初始版本变得更加容易,但确实使游戏与项目的真实版本相去甚远。随着时间的推移,我想推翻其中一些决定,但限制任何游戏项目的范围通常是一个非常健康的决定,尤其是在早期。

最后,在撰写本文时,我尚未完成AI 的初始阶段 1 。AI 现在声称角色并说出一些令人信服的谎言,但在投票中没有协调,也没有指责其他玩家。

候选方法

在设计人工智能时,有很多不同的候选方法。由于 AI 是一个非常广泛的领域,即使只是游戏 AI 内部也有很多变化,因此没有一种解决方案适用于每个项目。

对于这个 AI 项目,我考虑了许多不同的方法。

传统的基于树的方法,例如最小-最大树, 通常被考虑用于井字游戏、国际象棋、西洋跳棋、四连子和其他游戏。这些树往往在寻找最佳移动方面表现良好,但它们并不适用于所有情况。特别是,它们不适用于具有隐藏信息的游戏,这对 ONUW 至关重要。

相反,因为我的目标是对 AI 行为感到惊讶,所以我认为强化学习会很合适。在强化学习中,您对游戏世界进行建模以及如何与之交互,然后让代理尝试随机的事情,直到它看到什么效果最好,什么效果最差。简而言之,它通过将科学扔到墙上并查看粘住的东西来学习。

这样做的主要问题是 ONUW 中的每个角色的行为彼此完全不同,因此 AI 很难获得关于其在每个角色中的表现的有意义的反馈,或者我需要为每个角色训练单独的 AI。这两种方法看起来都存在规模和玩家角色在夜间变化方面的潜在问题。

我还考虑了一种蛮力方法,其中游戏世界的所有可能状态都保存在内存中,玩家将比较他们观察到的状态以确定哪些状态是可能的。基于此,玩家然后可以以最大化他们的投票将是好的投票的游戏百分比的方式进行投票。

这是一种有效的方法,一旦引入卡片移动角色,它就会表现得特别好,但它确实需要将许多不同的可能游戏状态同时存储在内存中,而且解释起来有点困难,所以我决定不这样做作为初始方法。

初始方法:概率模型

相反,我决定为每个玩家创建一个游戏板的概率模型。

在概率模型中,每个玩家的牌都有可能是一张特定的牌。

例如,想象一个有 3 个玩家的示例游戏(圣诞老人、鲁道夫和彗星,给定一年中的时间)。

所有玩家都知道游戏包括以下卡牌:

  • 1x 村民
  • 2x 泥瓦匠
  • 2x 狼人
  • 1x 先知

现在想象圣诞老人得到了一个石匠。

圣诞老人的起始知识

圣诞老人知道游戏中还有另一个泥瓦匠,所以如果圣诞老人正在考虑鲁道夫是泥瓦匠的可能性,他会用一副牌中剩下的泥瓦匠总数除以一副牌中剩下的未知牌总数。

在这种情况下,剩下的 1 张泥瓦匠除以 5 张剩余的牌,导致任何其他牌也是泥瓦匠的可能性为 20%。

如果将其应用于每个可能的角色和每张未知的卡片,您将得到一个如下所示的概率模型:

圣诞老人的出发概率模型

注意:在上图中,卡片上的每个百分比是该卡片是相关特定角色的百分比,而不是该角色是该特定卡片的概率百分比。

这也突出了一个有趣的事实:对于其他两个玩家,圣诞老人目前认为他们每个人都有 60% 的可能性是村民,40% 的可能性是狼人。

让我们在游戏中快进一点。夜间阶段发生,游戏中的所有石匠都醒了。在这种情况下,圣诞老人是游戏中唯一的泥瓦匠,所以他独自醒来。

他现在明确地知道鲁道夫和彗星不可能是共济会会员。这改变了他对这两张牌的概率模型,但没有改变三张中心牌的概率模型。

没有观察到其他共济会成员后圣诞老人的概率模型

现在,每个玩家都可以掷 50 / 50 来决定他们是在他的团队中还是在邪恶的团队中。更糟糕的是:除了了解其他两个玩家声称的内容之外,圣诞老人不会获得任何新信息。

概率和索赔

夜间阶段现在结束,所有玩家醒来并提出要求并分享他们在夜间学到的东西。

鲁道夫声称自己是先知,他看到了中间的两张牌,看到了村民和泥瓦匠。这与概率模型兼容,因为这两张卡片都可能位于中心,但圣诞老人不会自动调整他在游戏世界中的概率心智模型来反映这一点。

圣诞老人索赔后的概率模型

接下来,Comet 提出他们的要求并声明他们是村民。

呃哦。虽然鲁道夫和彗星都提供了与圣诞老人的心智模型不冲突的信息,但他们的信息相互矛盾。村民卡不能既是 Comet 的卡又是中心的卡。

一般来说,村民玩家会投票选出他们认为最有可能加入狼人队的玩家。如果两个或更多玩家具有相同的最高概率水平,将随机选择一个。

然而,由于鲁道夫提供的信息比彗星多,而且这些信息与圣诞老人所知道的(梅森在中间)兼容,这被用作决胜局,所以圣诞老人投票支持鲁道夫处决彗星。

对圣诞老人来说不幸的是,当角色被揭露时,圣诞老人意识到鲁道夫本应该出现在他的顽皮名单上。

狼人鲁道夫和村民彗星

狼人的概率

让我们来看看相同的概率引擎如何帮助鲁道夫声称安全角色来欺骗圣诞老人。

从鲁道夫的角度来看,他在游戏开始时画了狼人,醒来时是唯一的狼人。

因为鲁道夫是唯一允许他从中间看牌的狼人玩家。

在这种情况下,鲁道夫看到先知在中间,所以他知道其他两个玩家都不会扮演这个角色。

狼人鲁道夫和村民彗星

因此,鲁道夫现在知道担任先知角色是安全的。

然而,鲁道夫仍然需要描述他作为先知时发生的事情,他需要以一种尽可能具有说服力和可信度的方式来描述。

为实现这一点,我为玩家可以拥有的每个角色都定制了代码。当玩家试图撒谎并声称自己扮演该角色时,此自定义代码会运行以根据该玩家所知道的内容生成可信的声明。

在这种情况下,鲁道夫声称看到了一张狼人牌(他自己的真实牌)和一张村民牌。这里的村民卡是从谎言生成时最有可能的可用角色中随机挑选的。

不幸的是,鲁道夫不是万能的,也不知道彗星才是真正的村民,所以这个谎言最终是不完美的。

然而,真实的 One Night Ultimate Werewolf 游戏中的谎言通常是在信息不完善的情况下制作的,并且会分崩离析,而这正是这款游戏引人入胜和有趣的部分原因。

充满事件的世界

在技​​术层面上,模拟主要集中在卡槽和游戏事件上。

卡槽是有卡的东西。这些要么是实际玩家,要么是游戏板中间的位置。这些很简单,可以跟踪初始和当前角色以及与其关联的玩家或位置的名称。

另一方面,事件代表游戏世界中可能发生的任何事情。一些示例事件包括:

  • 一名球员醒来
  • 看卡片的先知
  • 自称是村民的玩家
  • 一个泥瓦匠醒来时看到另一个泥瓦匠
  • 狼人看到他们是唯一的狼人
  • 玩家投票

有些事件是众所周知的,例如投票或声明角色。其他事件仅对特定玩家可见。

概率引擎在为棋盘生成概率时查看特定玩家可见的所有事件。

有些事件会告诉概率系统,某张牌的角色是确定的。这些事件包括在游戏开始时查看自己的牌或在夜间阶段看到另一个石匠。

其他事件告诉概率引擎一张卡不能是特定角色。例如,当一个狼人玩家在晚上醒来而其他人没有醒来时,他们知道所有其他玩家都不可能是狼人。这并没有告诉他们这些玩家实际上是什么,但它确实调整了各种牌的概率。

结果是一个系统为 AI 提供了一个基线启发式,用于确定正在玩的牌以及给定的邻居可能是顽皮还是友善。

结果和未来

目前形式的模拟仍然非常有限——尤其是在 AI 将如何投票方面。玩家尚未协调投票或试图影响其他玩家投票给他们认为不好的玩家。结果感觉就像一个 AI 差不多,但是会犯一些愚蠢的错误。

真正的人类玩家往往会打得更加激进和混乱,并且会犯下明显的战术错误和前后矛盾。人类玩家也会撒谎,并且不计后果地撒谎,即使是村民角色。

在某些时候,我会从村民 AI 上取下“训练轮”,让他们最初随机撒谎,以欺骗狼人自己出去玩。

现在系统在策略和角色虚张声势方面过于依赖随机性,我不喜欢这样。我想构建一个神经网络或遗传算法,可以针对何时声称扮演什么角色以及表现出多大的侵略性来进化出一组最佳偏好。