【问题标题】:Python Chess ImplementationPython国际象棋实现
【发布时间】:2018-03-25 22:55:59
【问题描述】:

我正在着手实施国际象棋,在深入兔子洞之前,如果您不介意的话,我想征求社区的意见,因为我已经走入了死胡同哈。我正在努力找出将碎片与坐标相关联的最佳方法。

现在,我有一个包含各个部分的列表列表,其中每个列表代表一个板。

对于坐标,我使用了这个列表理解

coordinates = [[(i,j) for i in range(0,8)] for j in range(0,8)]

这给了我一张这样的桌子

[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0)]
[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]
[(0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2), (7, 2)]
[(0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (5, 3), (6, 3), (7, 3)]
[(0, 4), (1, 4), (2, 4), (3, 4), (4, 4), (5, 4), (6, 4), (7, 4)]
[(0, 5), (1, 5), (2, 5), (3, 5), (4, 5), (5, 5), (6, 5), (7, 5)]
[(0, 6), (1, 6), (2, 6), (3, 6), (4, 6), (5, 6), (6, 6), (7, 6)]
[(0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7)]

关于如何将棋子与其坐标联系起来以找到潜在的移动,有什么强烈的想法吗?起初我在考虑字典,但你有多个相同类型的棋子(例如两个骑士),并且随着棋盘的发展,这并不理想。

一如既往的感谢。

【问题讨论】:

  • 您可以创建字典。每对都与某个部分相关联,或者什么都没有。您如何表示一块或什么都不表示:例如,您可以使用另一个元组,例如 (color/piece)
  • 但是,我发现创建二维数组更简单。数组的每个值都是一个片段(例如我描述的元组)。恕我直言,使用元组来表示网格的协调似乎不太实用。见stackoverflow.com/questions/4878881/…
  • 将依靠您的专业知识并接受您的建议,因为我大部分时间都是盲目的。我只是在考虑你的评论。如果我理解正确,您的建议是有一个 2d 数组,其中它只是游戏板,并且可以用各种字母来描述各个字母,大写和小写描述侧面(即忽略坐标并在列表中操作列表,因此它被视为二维数组)?
  • 是的,关于使用数组索引作为棋盘的坐标。您将作品表示为单个字母的描述更多Joe Iddon's suggestion,并且具有简单且易于打印的优点。我认为这是一个合理的方法。

标签: python artificial-intelligence


【解决方案1】:

有趣的是,我一直在研究这个!以前,我在 javascript 中写过 a chess AI,但是今天我一直在将该代码转换为 Python 以用于更大的项目,因此我对这些知识记忆犹新。

最初,在 JS 版本中,我将board 有效地存储为strings8x8 array 的每个部分(实际上这是在一个带有其他数据(例如castling)的对象内部,但事实并非如此重要)。

但是,这种使用array(Python 中的list)的方法由于reference 传递它们的方式而导致问题。问题是通过negamax 算法传递board state 意味着对于要考虑的每个move,整个array(在JS 中)必须复制 停止将move 设置为原始板状态。

我通过将板状态存储为strings(在 Python 中为immutable)来解决此问题。我建议您开始使用lists,因为它们更容易访问和更改值,即使它们可能最终导致缓慢(通过复制它们),当您进行优化时。

存储board 状态的实际技巧是为每个部分使用一个character,并使用upperlowercase 来表示whiteblack 边。我从广泛使用的FEN notation 中窃取了这项技术,结果证明它对displaying 和在板上执行operations 都非常有用state

要明白我的意思,您可以使用以下命令初始化起始状态:

state = ["RNBQKBNR", "PPPPPPPP", "        ", "        ", "        ", "        ", "pppppppp", "rnbqkbnr"]
state = [list(r) for r in state]

然后您可以轻松地创建一个display 函数:

def display(state):
   for r in reversed(state):
      print(''.join(r))

然后,每当您想显示给定状态时,都可以调用display(state),它给出:

rnbqkbnr
pppppppp




PPPPPPPP
RNBQKBNR

希望这对您有所帮助!您可以在github 上查看我完整实现国际象棋 AI 的代码:in Pythonin javascript :)

【讨论】:

    【解决方案2】:

    好的,它是这样的: 你有 64 个单元格,传统上与​​字母和数字协调。 将每个单元格命名为数字,以便单元格协调:“a1”将是 11,h5 将是 85,等等。

    现在开始行动:

    1. 上:(单元格值)+ 1,下:(单元格值)- 1,右:(单元格值)+ 10,左:(单元格值)- 10,
    2. 诊断:左上:(单元格值)- 9,右上:(单元格值)+ 11, Down-Left: (单元格值) - 11, Down-Right: ((单元格值) + 9,
    3. 对于骑士:(单元格值)+ 21,(单元格值)- 21,(单元格 value) + 12, (cell value) - 12, (cell value) + 8, (cell value) - 8, (单元格值)+ 19,(单元格值)- 19。

    如您所见,我最近自己构建了一个(如果您介意的话,基于JS)哈哈。

    祝你好运!

    【讨论】:

      【解决方案3】:

      正如有人提到的,最明显的简单实现是列表列表,例如在我的实现中,此逻辑创建板,然后使用add() 方法将碎片添加到其中:

      https://github.com/akulakov/pychess/blob/7176b168568000af721e79887981bcd6467cfbc0/chess.py#L141

      【讨论】:

        猜你喜欢
        • 2022-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-26
        • 1970-01-01
        • 2014-03-02
        • 2013-05-24
        相关资源
        最近更新 更多