我一直在尝试为流行的纸牌游戏Dominion(http://www.boardgamegeek.com/boardgame/36218/dominion)制作一个AI玩家。
如果你不熟悉这个游戏,它基本上是万智牌的一个非常简化的近亲,其中有一个大型的卡牌库,每张卡牌都有不同的规则。在游戏过程中,玩家购买这些卡牌并将它们融入到他们的牌组中。
我从机器学习的角度对这款游戏感兴趣 – 我想让机器人相互对抗,进行数百万局游戏,并尝试挖掘数据,以帮助他们玩得更好。
我不确定如何将游戏规则(每张卡牌上印着的原话说明)与核心的AI决策逻辑分开。
我开始尝试的明显路径是为每张卡牌创建一个类,并将规则和AI代码都放在同一个地方。这有点粗糙——但它似乎是最容易实现的路径。但也许最好让每张卡牌支持某种接口,然后让AI组件针对这些接口进行编码?
对于这个问题,是否存在“正确”的OOP设计?或者说,是否存在几种合理的可能性?
回答:
我倾向于将卡牌的行为封装为它自己的类,这样可以很容易地处理具有多种行为(即选择)的卡牌。它还允许你编写可参数化的行为,并将它们与卡牌混合搭配。
所以卡牌应该包含卡牌的成本、何时可以打出、它的名称等等。它还应该包含卡牌可以执行的行为列表。
AI行动者将这些行为视为卡牌的一部分。只是卡牌的另一个属性,可以与成本一起衡量。
实际使用卡牌行为的AI行动者需要能够解释这些行为,因此行为类可能需要包含一些提示,以便AI理解它,但不应包含任何实际的AI逻辑。如果AI需要特定卡牌的特定行为,请将这类东西写入AI行动者,而不是卡牌行为。
如果AI行动者需要知道,例如,这种行为的预期胜利点回报是每轮0.2点,这可能是行为的一部分,作为AI选择购买/打出哪些卡牌时的提示。
但实际上我不知道你如何设计你的AI行动者,所以也许这没有意义。但我认为将行为视为卡牌的属性,而不是卡牌的基本组成部分可能会有所帮助。
它给你带来了封装AI行动者默认行为的优势(行动者无需卡牌即可执行的操作),因此你可以权衡这些操作与卡牌操作,而无需任何特殊情况的代码。