【问题标题】:Writing an AI for a turn-based board game为回合制棋盘游戏编写 AI
【发布时间】:2023-04-03 12:49:01
【问题描述】:

我目前正在编写一个棋盘游戏 (8x8),我需要在其中开发一个 AI。

我已经阅读了很多关于棋盘游戏中 AI 的文章,minmax 有或没有字母修剪,但我真的不知道如何实现这一点,我不知道从哪里开始......

关于我的游戏,这是一个回合制游戏,每个玩家在棋盘上都有棋子,他们必须选择一个并选择移动棋子(最多 1 或 2 个单元格)或克隆棋子(最多 1 个单元格) .

目前,我有一个非常愚蠢的 AI,它会随机选择一个棋子,然后选择一个随机动作来玩......

你能否给我一些线索,如何实现这个功能?

最好的问候

【问题讨论】:

标签: iphone objective-c


【解决方案1】:

(编辑:2013 年 8 月 8 日)- 我编写了一些示例代码:Ultimate Tic-Tac-Toe,其中我有一个最小/最大游戏搜索的通用实现。代码是用 C++ 的愚蠢变体编写的,称为 prepp


最好的资源是大学水平的人工智能课程。经典教材是"Artificial Intelligence: A Modern Approach" by Russel & Norvig

我将尝试对关键概念进行分解。

游戏状态 - 这是一组可用于确定的变量:

  • 当前状态的估计“价值”
  • 游戏结束了吗?

Value - 特定状态的“值”是当前玩家评估的该状态的函数,我们称之为 f(x)。此函数的另一个名称是“启发式”函数。在给定棋盘状态 x 的情况下,它确定当前玩家可以达到的最佳值。如何建模 x 取决于您,但 x 应该包含游戏自然流程中使用的所有内容。因此,在您的情况下,x 可能是一个 8x8 矩阵的值映射到棋盘上的棋子。而且,f 将是一个函数,它为红色玩家(或类似的)提供该棋盘配置的“价值”。

在 2 人回合制游戏中考虑的一种可能的简化是将“当前玩家”编码为状态的一部分。这将状态添加到启发式函数的输入。所以,我们用 f(x, player) 代替 f(x)。但是,这可以通过将 player 滚动到 x 来简化。无论哪种方式,f 将始终为同一玩家返回“值”,但根据下一个轮到谁。

通过(简化的)示例进行说明,如果白棋可以杀死黑棋的皇后,则国际象棋中的 f 几乎总是会返回非常高的分数。但是如果黑方有可能在下一步中杀死白方的后,那么 f 应该返回一个非常低的数字。

请注意,到目前为止还没有提到 minmax 的树搜索部分。 f 总是基于当前状态 定义的。所以,当我说“黑色有可能......”时,我的意思是你的启发式函数可以确定,例如,给定 x,有一条视线(对角线,水平或垂直)在黑主教或白车与白皇后之间。国际象棋的启发式算法应该足够复杂,以知道仅此一项就会造成威胁,因此在计算 f 的总价值时应该对它进行相应的评分。

在我讨论 minmax 之前,请注意 A* 是一种用于搜索可能的 x 值空间的优化。但是,在您完全理解并实现 minmax 之前,您不必担心优化问题。

因此,minmax 算法是一种组织 AI 决策过程的方法。为了实现 minmax,您需要做的事情:

  • 从现有游戏状态x生成有效游戏状态。
  • 在达到特定深度后停止循环或递归。
  • 通过将每个级别递归的“值”传递回调用方来记住它。

基本流程从理解开始,轮到谁了?正如我之前提到的,f 总是返回高值表示玩家 1 成功,低值表示玩家 2 成功。在每个更深层次的递归中,玩家将使您了解是选择通过递归发现的潜在值的最小值还是最大值。

让我换个方式说。实际评估 f(x) 有两个原因。

  1. 您想知道游戏是否在状态 x 结束。
  2. 您已达到最深的递归级别,并且您想评估如果游戏进行到此为止的分数。

所以,你的代码会做这样的事情:

函数minmax(x, player) 返回

  • 我的当前状态是 x,下一个要移动的 玩家 是已知的。我知道这是因为
    • function choose-move 告诉我的。 (见下文)
    • 我被自己递归调用。 (见下文)
  • 游戏结束了吗?问 f(x)。如果它返回正无穷大,那么白色就赢了。如果它返回负无穷大,那么黑色赢了。如果您的游戏有僵局选项,或者有一个结束得分(可能是更大游戏的一部分),那么您只需想出一种方法来表示获胜 + 得分作为返回值 f。或者,如果您想将其分开,只需创建一个新函数 g(x) 即可。如果游戏结束,则将该值返回给调用者。如果游戏还没有结束,请继续。
  • x 我将枚举所有可能的 x'。在 8x8 游戏中,任何单个游戏状态都可能有几个、几十个或几百个可能的有效移动。这取决于您的游戏规则。
  • 如果已达到所需递归的最深级别,
    • 对于每个 x',调用 f(x', player)。对于每个调用,我们将其返回值与我们传入的特定 x' 相关联。
  • 其他
    • 对于每个 x',递归调用 minmax(x', other-player)。 (请注意,此时 other-playerplayer 相反。)对于每个调用,我们将其返回值与特定的 x' 我们已经过去了。

此时,所有可能的下一步行动都应该有一个与之关联的“价值”。

  • 如果 player 是玩家 1,则从与所有 x' 关联的所有值中选择 ma​​ximum 值,然后返回该值。这是玩家 1 在此游戏状态下能够做到的最好的事情。
  • 如果 player 是玩家 2,请从与所有 x' 关联的所有值中选择 minimum 值,然后返回该值。这是玩家 2 在此游戏状态下能够做到的最好的事情。

结束函数minmax

function choose-move(x, player) return *next_state*

  • 我目前的状态是x,我们正试图弄清楚玩家的下一步应该是什么。
  • 如上所述,检查游戏是否结束。
  • x 我将枚举所有可能的 x'。 (您应该能够在 minmax 中重用您必须执行此操作的任何代码。
    • 对于每个 x',调用 minmax(x', player)。对于每个调用,我们将其返回值与我们传入的特定 x' 相关联。
  • 如果 player 是玩家 1,则从与所有 x' 关联的所有值中选择 ma​​ximum 值,然后返回该值。这是玩家 1 在此游戏状态下能够做到的最好的事情。
  • 如果 player 是玩家 2,请从与所有 x' 关联的所有值中选择 minimum 值,然后返回该值。这是玩家 2 在此游戏状态下能够做到的最好的事情。

结束函数选择移动

您的驱动程序代码只需要调用 choose-move,它应该返回下一个游戏板。显然,您还可以将返回值编码为“移动”而不是状态,以获得不同的表示。

希望这会有所帮助。很抱歉解释冗长,我刚喝了点咖啡。

【讨论】:

  • 这很有趣,我现在不确定我的游戏是否可以很好地实现这一点,我会努力的!非常感谢。
【解决方案2】:

通常,您需要提前决定您希望 AI 计算多少步(深度)。根据您的游戏,最大深度可能会有很大差异。想想井字游戏与跳棋与国际象棋。

您还希望以一种可以比较各种棋盘状态的方式量化棋盘位置(价值)。

在最极端的情况下,您需要获取当前板并计算其值。然后考虑你可以采取的每一个可能的举动。然后考虑,对于每一个,你的对手可能做出的每一个可能的动作。迭代到最大深度。您将构建一个树形结构(广度优先)。

修剪你的树。可以修剪任何保证您降低董事会价值的分支。

然后,以某种方式比较剩余的分支。我不知道如何最好地做到这一点 - 但它似乎相当简单。您要么乐观地权衡可能的最佳结果并选择那些分支。或者根据最坏结果的可能性继续修剪。

希望这会有所帮助。

【讨论】:

  • 这很有趣,所以我需要提供一种方法来从原来的棋盘创建一个新棋盘,进行移动并递归评估棋盘到最大深度?
  • 基本上,是的。我自己已经很多年没有这样做了。作为本科生,必须为 AI 课做这件事。我什至不记得我玩过哪款两人游戏。我确实记得首先对 15 谜题做了类似的方法来比较广度优先、深度优先和爬山……或类似的东西。
【解决方案3】:

首先,您只需要考虑 2 个函数:

  • 根据给定的游戏状态生成有效移动列表
  • 评估当前游戏状态对于给定玩家的“好”程度

如果您想保持简单,可以将第一项分解为 2 个单独的函数:

  • 生成所有动作的列表
  • 根据给定的游戏状态检查给定的动作是否有效

如果您已实现此功能,则可以使用现有 AI 算法之一(例如 minmax 或 alpha-beta)来构建和修剪搜索树并返回最佳可用移动。

请记住,构建有效动作列表的速度越快,评估游戏状态的速度越快,搜索树的深度就越深。

我曾经写过一篇关于这个主题(棋盘游戏 AI)的文章,你可能会觉得有趣:http://proghammer.wordpress.com/2010/11/30/chess08-implementing-an-ai-artificial-intelligence-player/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2012-04-22
    相关资源
    最近更新 更多