国际象棋

../../../_images/classic_chess.gif

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

导入

from pettingzoo.classic import chess_v6

动作

离散

并行 API

手动控制

智能体

agents= ['player_0', 'player_1']

智能体

2

动作形状

离散(4672)

动作值

离散(4672)

观测形状

(8,8,111)

观测值

[0,1]

国际象棋是人工智能中研究历史最悠久的游戏之一。我们对国际象棋观测和动作空间的实现采用了 AlphaZero 方法,并做了两个小改动。

观测空间

观测是一个字典,包含一个 'observation' 元素(如下所述的常规 RL 观测)和一个 'action_mask' 元素,该元素包含合法动作,详情见合法动作掩码部分。

与 AlphaZero 类似,主要观测空间是一个代表棋盘的 8x8 图像。它有 111 个通道,分别代表

  • 通道 0 - 3:王车易位权

    • 通道 0:如果白方可以王车易位(后翼),则全为 1

    • 通道 1:如果白方可以王车易位(王翼),则全为 1

    • 通道 2:如果黑方可以王车易位(后翼),则全为 1

    • 通道 3:如果黑方可以王车易位(王翼),则全为 1

  • 通道 4:是黑方还是白方

  • 通道 5:一个计算 50 步规则的回合计时器。用一个单通道表示,如果已经走了 n 步,则扁平化通道中的第 n 个元素被设为 1

  • 通道 6:全为 1,用于帮助神经网络在填充卷积中找到棋盘边缘

  • 通道 7 - 18:每种棋子类型和玩家颜色组合对应一个通道。例如,有一个特定通道表示黑方骑士。如果游戏棋盘上相应位置有一个黑方骑士,则此通道的对应索引被设为 1,否则设为 0。与 LeelaChessZero 类似,吃过路兵的可能性通过在第 8 行而不是第 5 行显示易受攻击的兵来表示。

  • 通道 19:表示一个局面之前是否出现过(即是否是两步重复)

  • 通道 20 - 111 代表前 7 个棋盘,每个棋盘由 13 个通道表示。最新的棋盘占据前 13 个通道,然后是倒数第二个棋盘,依此类推。这 13 个通道对应于通道 7 - 20。

与 AlphaZero 类似,我们的观测空间采用堆叠方法,累积前 8 个棋盘观测。

与 AlphaZero 棋盘方向可能不同不同,在我们的系统中,env.board_history 始终保持面向白方智能体,白方智能体的王始终位于第一行。简单来说,两位玩家观察的是相同的棋盘布局。

尽管如此,我们仍然加入了一个便捷的功能,env.observe(‘player_1’) 函数,专门用于黑方智能体的视角。这有助于训练能够熟练地同时扮演黑方和白方的智能体。

动作空间

摘自 AlphaZero 国际象棋论文

[在 AlphaChessZero 中,] 动作空间是一个 8x8x73 维数组。每个 8×8 位置标识从哪个格子“拿起”一个棋子。前 56 个平面编码任何棋子的可能的“后行棋”:棋子将移动的格子数量 [1..7],沿着八个相对方向 {N, NE, E, SE, S, SW, W, NW} 中的一个。接下来的 8 个平面编码该棋子的可能的马跳棋。最后 9 个平面编码兵在两个可能对角线上移动或吃子时可能的次升级,分别升级为马、象或车。从第七行的其他兵移动或吃子则升级为后。

我们将其扁平化为 8×8×73 = 4672 个离散动作空间。

你可以使用以下表达式从整数动作 a 计算回原始的 (x,y,c) 坐标:(a // (8*73), (a // 73) % 8, a % (8*73) % 73)

示例:>>> x = 6 >>> y = 0 >>> c = 12 >>> a = x*(8*73) + y*73 + c >>> print(a // (8*73), a % (8*73) // 73, a % (8*73) % 73) 6 0 12

注意:坐标 (6, 0, 12) 对应于第 6 列,第 0 行,第 12 平面。在国际象棋记法中,这表示 G1 格子

0

1

2

3

4

5

6

7

A

B

C

D

E

F

G

H

奖励

赢家

输家

平局

+1

-1

0

版本历史

  • v6:修复了玩家开局错误的问题,增加了无子可杀/50步规则/三次重复局面的检查 (1.23.2)

  • v5:将 python-chess 版本更改为 1.7 (1.13.1)

  • v4:将观测空间更改为适当的 AlphaZero 风格帧堆叠 (1.11.0)

  • v3:修复了任意调用 observe() 函数中的错误 (1.8.0)

  • v2:观测中的合法动作掩码取代了 info 中的非法动作列表 (1.5.0)

  • v1:由于采用了新的智能体迭代方案(所有智能体在完成行动后都会被迭代),所有环境的版本号上移 (1.4.0)

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

用法

AEC

from pettingzoo.classic import chess_v6

env = chess_v6.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.chess.chess.env(**kwargs)[source]
class pettingzoo.classic.chess.chess.raw_env(render_mode: str | None = None, screen_height: int | None = 800)[source]
action_space(agent)[source]

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

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

默认实现是返回 action_spaces 字典

close()[source]

关闭应该释放的任何资源。

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

observation_space(agent)[source]

接受智能体并返回该智能体的观测空间。

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

默认实现是返回 observation_spaces 字典

observe(agent)[source]

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

last() 调用此函数。

render()[source]

按照 self.render_mode 指定的方式渲染环境。

渲染模式可以是 human 以显示窗口。默认环境中的其他渲染模式包括返回 numpy 数组且经典环境之外的所有环境都支持的 ‘rgb_array’,以及返回打印字符串(仅限于经典环境)的 ‘ansi’

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

将环境重置到初始状态。

step(action)[source]

接受并执行环境中当前 agent_selection 的动作。

自动将控制权切换到下一个智能体。