花火

../../../_images/classic_hanabi.gif

此环境是经典环境的一部分。请先阅读该页面以获取一般信息。

导入

from pettingzoo.classic import hanabi_v5

动作

离散

并行 API

手动控制

智能体

agents= ['player_0', 'player_1']

智能体

2

动作形状

Discrete(20)

动作值

Discrete(20)

观察形状

(658,)

观察值

[0,1]

花火(Hanabi)是一个2-5人的合作游戏,玩家需要协同合作,组成不同颜色的烟花。烟花是一组同色、从1到5按顺序排列的牌。游戏中的牌既有颜色也有数字;每个玩家可以看到其他玩家手中的牌,但看不到自己的牌。玩家不能直接互相交流,而是必须移除一个信息标记来提供信息。玩家可以告诉其他玩家其手中的牌是特定颜色或特定数字。游戏开始时有8个信息标记,玩家可以通过弃掉手中的牌来返还一个信息标记到场上。玩家也可以打出手中的牌:这张牌必须要么开启一个新的烟花,要么按顺序追加到现有的烟花上。但是,两组烟花不能有相同的颜色,并且同一组烟花不能重复数字。如果打出的牌不满足这些条件,则会放置一个生命标记。当放置了3个生命标记、所有5组烟花都已完成或牌堆中的所有牌都已抽完时,游戏结束。得分基于每组已完成烟花中最大牌面的数值。

环境参数

花火接受多个参数来定义游戏的大小和复杂度。默认为完整的2人花火游戏。

hanabi_v5.env(colors=5, ranks=5, players=2, hand_size=5, max_information_tokens=8,
max_life_tokens=3, observation_type='minimal')

colors: 牌可以具有的颜色数量(影响牌堆大小)

ranks: 牌可以具有的数字数量(影响牌堆大小)

hand_size: 玩家手牌大小。标准游戏为 (玩家数 >= 4 时为 4,否则为 5)

max_information_tokens: 信息标记的最大数量(标记越多,可以透露的信息越多,游戏越容易)

max_life_tokens: 生命标记的最大数量(标记越多,可以容忍的错误越多,游戏越容易)

observation_type: “minimal”:最小观察(人类玩家所见)。“card_knowledge”:包含对过去提示的每张牌的了解,以及简单的推断知识,形式为“这张牌不是红色,因为之前没有被提示为红色”。“seer”:显示所有牌,包括玩家自己的牌,无论是否给出过提示。

观察空间

观察是一个字典,其中包含一个'observation'元素,即下方描述的通常的强化学习观察,以及一个'action_mask'元素,用于保存合法动作,如合法动作掩码部分所述。

智能体的主要观察空间是一个大小为 658 的向量,代表剩余的生命和信息标记、当前构建的烟花、所有其他智能体的手牌、当前牌堆大小以及弃牌堆。观察向量包含以下特征:生命标记、信息标记、玩家数量、牌堆大小、已组成的烟花、合法动作、观察到的手牌、弃牌堆、从其他玩家那里收到的提示,这些特征被序列化为一个比特串。

每张牌都用一个 25 位独热向量编码,其中牌的编码等于其颜色*T + 数字,T 是最大可能的数字。默认情况下,此值为 5。最大牌堆大小为 50。剩余牌堆大小用一元编码表示。每种颜色烟花的状态用独热编码表示。剩余信息标记用一元编码表示。剩余生命标记用一元编码表示。弃牌堆用弃牌的数字的热力图编码表示。也就是说,最低有效位设为 1 表示该颜色中数字最小的牌已被弃掉。

当玩家透露有关他们牌的信息时,每张牌透露的信息也会被观察到。前 25 位表示该特定牌是否可能是特定颜色。例如,如果牌只能是红色,则观察到的透露信息的前 25 位将是 11111,后跟 20 个零。接下来的 5 位存储该牌的颜色是否被明确透露,因此如果牌被透露为红色,则接下来的 5 位将是 10000。最后 5 位是该牌被透露的数字。因此,如果牌被透露为数字 1,则接下来的 5 位将是 10000。这些 25 位信息会针对每个玩家手上的所有牌进行跟踪和观察。

索引

描述

0 - 24

其他玩家手牌中卡牌 1 的向量

[0, 1]

25 - 49

其他玩家手牌中卡牌 2 的向量

[0, 1]

50 - 74

其他玩家手牌中卡牌 3 的向量

[0, 1]

75 -100

其他玩家手牌中卡牌 4 的向量

[0, 1]

100-124

其他玩家手牌中卡牌 5 的向量

[0, 1]

125-174

剩余牌堆大小的一元编码

[0, 1]

175-179

红色烟花的向量

[0, 1]

180-184

黄色烟花的向量

[0, 1]

185-189

绿色烟花的向量

[0, 1]

190-195

白色烟花的向量

[0, 1]

195-199

蓝色烟花的向量

[0, 1]

200-207

剩余信息标记的一元编码

[0, 1]

208-210

剩余生命标记的一元编码

[0, 1]

211-260

弃牌堆的热力图编码

[0, 1]

261-262

上一玩家 ID 的独热编码

[0, 1]

263-266

上一玩家动作类型的向量

[0, 1]

267-268

上一动作目标的向量

[0, 1]

269-273

上一动作中透露颜色的向量

[0, 1]

274-278

上一动作中透露数字的向量

[0, 1]

279-280

手牌中哪些牌被透露的向量

[0, 1]

281-282

打出或弃掉的牌的位置

[0, 1]

283-307

代表上一张打出的牌的向量

[0, 1]

308-342

本玩家第 0 张牌的透露信息

[0, 1]

343-377

本玩家第 1 张牌的透露信息

[0, 1]

378-412

本玩家第 2 张牌的透露信息

[0, 1]

413-447

本玩家第 3 张牌的透露信息

[0, 1]

445-482

本玩家第 4 张牌的透露信息

[0, 1]

483-517

其他玩家第 0 张牌的透露信息

[0, 1]

518-552

其他玩家第 1 张牌的透露信息

[0, 1]

553-587

其他玩家第 2 张牌的透露信息

[0, 1]

588-622

其他玩家第 3 张牌的透露信息

[0, 1]

663-657

其他玩家第 4 张牌的透露信息

[0, 1]

动作空间

动作空间是一个标量值,范围从 0 到最大动作数。这些值代表玩家可以执行的所有可能动作,无论是否合法。环境中的每个可能动作都映射到一个 UUID,范围从 0 到最大动作数。默认情况下,最大动作数为 20。第一组动作是弃掉智能体手中的牌。如果玩家手中有 k 张牌,则前 k 个动作值是弃掉其中一张牌。接下来的 k 个动作是打出玩家手中的一张牌。最后,剩余的动作是透露其他玩家手牌中的颜色或数字。第一组透露动作是按顺序透露下一位玩家所有牌的颜色或数字,并为环境中所有其他玩家重复此过程。

动作 ID

动作

0

弃掉位置 0 的牌

1

弃掉位置 1 的牌

2

弃掉位置 2 的牌

3

弃掉位置 3 的牌

4

弃掉位置 4 的牌

5

打出位置 0 的牌

6

打出位置 1 的牌

7

打出位置 2 的牌

8

打出位置 3 的牌

9

打出位置 4 的牌

10

透露玩家 1 的红色牌

11

透露玩家 1 的黄色牌

12

透露玩家 1 的绿色牌

13

透露玩家 1 的白色牌

14

透露玩家 1 的蓝色牌

15

透露玩家 1 的数字 1 牌

16

透露玩家 1 的数字 2 牌

17

透露玩家 1 的数字 3 牌

18

透露玩家 1 的数字 4 牌

19

透露玩家 1 的数字 5 牌

奖励

每一步的奖励计算为相对于上一步的游戏得分变化。游戏得分计算为每组已构建烟花中数值的总和。如果游戏失败,得分设为零,因此最终奖励将是目前为止收到所有奖励的负值。

例如,如果烟花按以下方式创建

蓝色 1, 蓝色 2, 红色 1, 绿色 1, 绿色 2, 绿色 3

游戏结束时,总得分为 2 + 1 + 3 = 6

如果执行了非法动作,游戏终止,执行非法动作的玩家失败。与普通失败一样,他们的最终奖励将是目前为止收到所有奖励的负值。其他玩家的奖励不受非法动作的影响。

版本历史

  • v5:为未来兼容性将环境切换到依赖 OpenSpiel(使用 Shimmy)(1.23.0)

  • v4:修复了任意调用 observe() 的错误 (1.8.0)

  • v3:观察中的合法动作掩码取代了 infos 中的非法动作列表 (1.5.0)

  • v2:修复了默认参数 (1.4.2)

  • v1:由于采用了新的智能体迭代方案,即所有智能体完成后才进行迭代,因此提高了所有环境的版本 (1.4.0)

  • v0:初始版本发布 (1.0.0)

用法

AEC

from pettingzoo.classic import hanabi_v5

env = hanabi_v5.env(render_mode="human")
env.reset(seed=42)

for agent in env.agent_iter():
    observation, reward, termination, truncation, info = env.last()

    if termination or truncation:
        action = None
    else:
        mask = observation["action_mask"]
        # this is where you would insert your policy
        action = env.action_space(agent).sample(mask)

    env.step(action)
env.close()

API

class pettingzoo.classic.hanabi.hanabi.env(**kwargs)[source]
class pettingzoo.classic.hanabi.hanabi.raw_env(colors: int = 5, ranks: int = 5, players: int = 2, hand_size: int = 5, max_information_tokens: int = 8, max_life_tokens: int = 3, observation_type: str = 'card_knowledge', random_start_player: bool = False, render_mode: str | None = None)[source]

初始化raw_env类。

参数说明
  • colors: int, 颜色数量,范围 [2,5]。

  • ranks: int, 数字数量,范围 [2,5]。

  • players: int, 玩家数量,范围 [2,5]。

  • hand_size: int, 手牌大小,范围 [2,5]。

  • max_information_tokens: int, 信息标记数量 (>=0)。

  • max_life_tokens: int, 生命标记数量 (>=1)。

  • observation_type: str。

    “minimal”:最小观察。“card_knowledge”:一阶共同知识观察。“seer”:所有牌的完整信息。

  • random_start_player: bool, 布尔值,随机开始玩家。

常见游戏配置
Hanabi-Full (默认){

“colors”: 5, “ranks”: 5, “players”: 2, “max_information_tokens”: 8, “max_life_tokens”: 3, “hand_size”: (玩家数 >= 4 时为 4,否则为 5) “observation_type”: “card_knowledge”, “hand_size”: 2, }

Hanabi-Small{

“colors”: 2, “ranks”: 5, “players”: 2, “max_information_tokens”: 3, “hand_size”: 2, “max_life_tokens”: 1, “observation_type”: “card_knowledge”, }

Hanabi-Very-Small{

“colors”: 1, “ranks”: 5, “players”: 2, “max_information_tokens”: 3, “hand_size”: 2, “max_life_tokens”: 1, “observation_type”: “card_knowledge”, }

action_space(agent)[source]

接收智能体并返回该智能体的动作空间。

对于同一个智能体名称,必须返回相同的值

默认实现是返回action_spaces字典

close()[source]

关闭所有应释放的资源。

关闭渲染窗口、子进程、网络连接或任何其他应释放的资源。

observation_space(agent)[source]

接收智能体并返回该智能体的观察空间。

对于同一个智能体名称,必须返回相同的值

默认实现是返回observation_spaces字典

observe(agent_name: str)[source]

返回智能体当前可以进行的观察。

last()调用此函数。

render()[source]

打印玩家数据。

仅支持控制台打印。

reset(seed=None, options=None)[source]

重置环境以开始新游戏,并以整数列表形式返回当前玩家的观察。

返回值:
  • observation – 可选的整数列表,长度为 self.observation_vector_dim,描述

  • 当前智能体 (agent_selection) 的观察

step(action: int, observe: bool = True, as_vector: bool = True) ndarray | List[List[dict]] | None[source]

环境向前推进一步。动作必须在 self.legal_moves 内,否则会抛出错误。

返回值:
  • observation – 可选列表,包含执行动作步骤后轮到行动的智能体的新观察。

  • 默认情况下,是一个整数列表,从智能体的视角描述游戏的逻辑状态。

  • 如果 as_vector=False,也可以返回为一个描述性字典。