如何建模能力奖金,以便使用Z3动态添加/删除选项

如何建模能力奖金,以便使用Z3动态添加/删除选项,z3,Z3,我想用Z3来模拟游戏中的角色统计。为了简单起见,我们将关注一个属性:装甲等级(AC) 在这个游戏中,角色可以穿戴多种类型的护甲,每种护甲都有不同的基础护甲等级。此外,还有许多其他的加成可以添加到护甲上。为了简单起见,请考虑下面的 Armor Type | Base armor class -----------|----------------- Chain Mail | 16 Plate Mail | 18 Shield Type | Armor Bonus ---------------

我想用Z3来模拟游戏中的角色统计。为了简单起见,我们将关注一个属性:装甲等级(AC)

在这个游戏中,角色可以穿戴多种类型的护甲,每种护甲都有不同的基础护甲等级。此外,还有许多其他的加成可以添加到护甲上。为了简单起见,请考虑下面的

Armor Type | Base armor class
-----------|-----------------
Chain Mail | 16
Plate Mail | 18

Shield Type  | Armor Bonus
------------------------
Kite Shield  | +2
Magic Shield | +4

Defense Training | Bonus
-------------------------
Without          | +0
With             | +1
角色只能从每种奖励中受益,例如,一个角色一次只能装备一个盾牌

角色必须有盾牌才能装备它,所以他们可以装备的盾牌可能会动态变化

此外,角色可能在游戏中的某个时间点(例如升级时)获得防御训练,因此奖励类型也可能会动态变化

玩家通常希望为他们的角色获得最高的AC,因此角色AC是他们可以获得的最佳基础AC,加上他们可以访问的所有类别的每个类别中的最佳奖金

在命令式/OO编程语言中,我可以这样对系统建模

class Character():
    base_armor_bonuses = [16, 18]
    shield_armor_bonuses = [2, 4]
    armor_class_bonuses: List[List[Int]] = [base_armor_bonuses, shield_armor_bonuses]

    def armor_class(armor_class_bonus_options):
        sum([max(bonus_kind) for bonus_kind in armor_class bonuses])

    def add_bonus_kind(new_bonus_options):
        armor_class_bonuses.append(new_bonus_options)

    def add_new_armor_type(new_armor_bonus):
        base_armor_bonuses.append(new_armor_bonus)
命令式方法可以很好地编码这些简单的规则,但是我对快速迭代规则更改和新效果感兴趣,因此我希望Z3能够以更灵活的方式编码这些规则

此外,我想使用Z3来探索一下设计空间,例如,找到最大化装甲等级的角色构建,这是命令式方法很难做到的

编辑: 我希望能够使用系统实时回答诸如“这是什么角色当前的装甲等级?”之类的问题。然后,为了响应游戏中发生的事件,例如角色获得新盾牌、在墙后行走或脱下盔甲,请更新世界状态,以便下次我查询“这个角色的盔甲等级是什么?”时更新他们的盔甲等级

我也希望能够回答,不一定是实时的。在你所能塑造的所有角色中,哪一个角色拥有最高的护甲等级。这在简化的例子中很容易,但是一旦你引入了很多种类的角色,所有这些角色都可以从他们可以选择的不同选项中获得不同种类的护甲类奖励,那么枚举所有可能的角色以找到护甲等级最高的角色就变得不可行了

对于备选方案,我在prolog上做了一些研究,虽然我不确定性能差异可能是什么,但prolog可能也能够回答查询。我还考虑了一个典型的命令式程序,如下面包含的python代码片段。这将很好地处理实时查询。但是,它会有与维护正确支持所有不同选项的命令式程序相关的开销。此外,很难从该程序中确定具有最高装甲等级的角色或其他角色。我希望像z3这样的声明性逻辑语言可以克服这两个限制

目前,这是我和我的朋友在玩现有游戏(实时查询)和设计新游戏(非实时查询)时的一个爱好项目

编辑2 对于基本版本,没有自由变量,基本上只是计算特定角色的装甲等级和其他属性。我想这样做的原因是因为我不想维护两个独立的系统,一个用于游戏,一个用于设计

对于更复杂的示例,自由变量是构建角色时所做的选择。这里有一个简单的例子

角色有一个基本等级的战士、弓箭手或巫师。每次升级时,你都可以在任何一个课程中获得一个级别,获得你尚未拥有的该课程最低级别的能力。例如,战士2/弓箭手1将拥有战士的一级和二级能力以及弓箭手的一级能力。下面是一些示例能力

level | fighter ability
----------------------
1     | Proficiency with Chain mail and the Kite Shield
2     | Defense Training or Proficiency with plate (players choice, i.e. a free variable)
3     | Defense Training or Proficiency with plate (whichever one they didn't get before)

level | wizard ability
-----------------------
1     | proficiency with Magic Shields
2     | proficiency with chain
因此,我想以声明的方式定义每个角色可以使用的奖励/选项,然后询问Z3哪种构建在3级拥有最高的护甲等级。战斗机2(用于平板)/精灵1是我能为这个小例子想出的最好的,总装甲为18+4=22

例如,如果有12个角色类,每个类都有1到20个级别,比如第五版D&D。那么可能会有12^20或大约2^71个20级角色构建。通过列举所有选项来回答20级角色拥有最高护甲等级的问题可能需要比我活得更长的时间。这就是我希望Z3能够提供帮助的地方

编辑3 我不确定我应该使用什么数据结构/类型来表示特定角色可用的装甲。我曾考虑过使用数组,但在定义fighter class选项时,我不知道如何表达“armor type array contains plate”这样的语句,然后还表示数组中没有其他未指定的元素

换句话说,我不知道如何定义数组的内容,使其依赖于自由变量的赋值(字符类级别的选择),然后说数组中没有其他内容


此外,我对Z3还不够熟悉,甚至不知道这是否是一种很好的系统建模方法。

不清楚您在这里提出的问题。你能通过编辑你的问题来澄清这一点吗?您希望使用Z3编码什么样的灵活性(即约束)?你能举个具体的例子吗?--你的意思是在生产中使用这个软件吗?您的项目数据库有多大?你希望得到实时的答案吗?您考虑过哪些具体的替代方案来实现您的目标?基本版本中的自由变量是什么