目前,我在用 Python 实现六边形国际象棋时,在计算棋子的有效走法时遇到了困难。让我首先描述一下六角象棋中马的移动是如何定义的。
让我重点关注骑士的1个移动 Action 。马向上移动 4 行,向左移动 1 列。这在以下代码行中进行了描述:
target = (position_col - 1, position_row - 4)
if on_board(target):
if empty_hexagon(target, board) or piece_color_on_position(target, board) != self.color:
move = Move(self, self.position, target)
self.moves.append(move)
现在这适用于某些职位,如下所示:
现在这确实适用于这个特定的六边形,但不适用于所有六边形。例如,参见这个位置:
发生这种情况是因为我的板上并非所有行都包含相同数量的列。我的棋盘基本上是一个充满六边形对象的二维数组,我认为这在本例中并不是特别重要,但它具有以下结构:
self.board = [
[None],
[None, None],
[None, None, None],
[None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None],
[None, None, None,],
[None, None],
[None]
]
我想创建一个偏移函数,它查看当前行和目标行并计算偏移量,以便我可以仅使用“正常”移动步骤并计算相应的目标列。有没有办法做到这一点,或者也许我可以使用另一个坐标系来更轻松地做到这一点?
提前致谢!
我尝试了一些方法,但都没有正确实现。
我使用一个函数来计算每行列的差异。如果我的起始行包含 3 列,而我的目标行包含 5 列,那么我会将这个差异添加到我的目标列中。然而这并没有达到预期的效果。
编辑1* 偏移量如下所示:
offset = BOARD_LENGTH[position_row - 4] - BOARD_LENGTH[position_row]
target = (position_col - 1 + offset, position_row - 4)
if on_board(target):
if empty_hexagon(target, board) or piece_color_on_position(target, board) != self.color:
move = Move(self, self.position, target)
self.moves.append(move)
其中 BOARD_LENGTH = [1,2,3,4,5,6,6,6,5,6,5,6,5,6,6,6,5,4,3,2, 1]
(这些是我的二维板列表中每行六边形的数量。)
这种偏移的实现没有达到预期的效果,因为计算棋子的有效移动仍然给我提供了错误的方格来移动到很多起始位置。
编辑2* 从我最初的屏幕截图来看,骑士似乎没有向上移动 4 行,向右移动 1 列。我将在此处添加屏幕截图以显示我的坐标系。在这里我们可以看到,我们实际上向上移动了 4 行。由于我们使用的是六边形,因此直接位于六边形顶部的六边形不是向上移动 1 行,而是向上移动 2 行。希望此屏幕截图能够澄清这一点:
最佳答案
好的,感谢乔,我想我已经在这里找到了答案。首先感谢大家对这个问题的关注。如果其他人将来需要寻找此(或类似)问题的解决方案,我将在这里发布我的解决方案。
查看我使用的坐标系来制定有效的公式对我来说是不可能的。因此,我将坐标系更改为以下内容:
我们不是将棋盘上的每个六边形从 0 开始,而是想象该六边形的左侧和右侧都有六边形。在位置 (0,3) 处,我们想象其左侧有 3 个六边形,右侧有 2 个六边形。因此,我们的董事会现在看起来像:
self.board = [
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None],
[None, None, None, None, None, None]
]
注意*并非此二维列表的所有元素都填充有六边形。
问题现在更容易理解了。看起来目前只有偶数行和不均匀行之间存在不匹配。如果我们从偶数行转到奇数行,我们会看到相同的列索引位于偶数行中相同索引的右侧。也就是说,如果我们有第 10 行,第 3 列。如果我们要移动到第 9 行第 3 列,我们将向上移动一行并向右移动。这可以在上面的屏幕截图中共享的坐标系中看到。
现在我只看骑士的单一 Action 。为此我将代码更改为:
knight_offset = calculate_offset(position_row, position_row - 5)
target = (position_col - knight_offset, position_row - 5)
if on_board(target, board):
if empty_hexagon(target, board) or piece_color_on_position(target, board) != self.color:
move = Move(self, self.position, target)
self.moves.append(move)
我添加了以下辅助函数来处理偏移量:
def calculate_offset(start_row, target_row):
'''
This function calculates the offset that should be used to move from hex A, to hex B
'''
if start_row % 2 == 0 and target_row % 2 == 1:
return 1
return 0
这似乎对这个单一的骑士运动有效。从下面的截图可以看出(我也对其他位置进行了测试,但这似乎有效):
我可能需要对不同棋子的不同移动和偏移进行更多修改,尤其是移动到棋盘的左侧和右侧。不过,据我所知,这个问题已经解决了,我又有了前进的方向。感谢您的所有提示!
关于python - 用 Python 计算六角形棋子的有效走法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77253312/