Python connect 4 检查win函数

Python connect 4 check win function

我正在编写一个 connect 4 游戏,您可以在其中选择棋盘的大小。该游戏对于大多数棋盘尺寸都可以完美运行,但是当棋盘高而宽时,我就会遇到问题。我不断收到索引超出范围的错误,我不确定自己做错了什么。这就是我现在的检查功能,因为它是唯一给我问题的部分。

def checkOWin(board):

    boardHeight = len(board)
    boardWidth = len(board[0])
    tile = 'O'
    # check horizontal spaces
    for y in range(boardHeight):
        for x in range(boardWidth - 3):
            if board[x][y] == tile and board[x+1][y] == tile and board[x+2][y] == tile and board[x+3][y] == tile:
                return True

    # check vertical spaces
    for x in range(boardWidth):
        for y in range(boardHeight - 3):
            if board[x][y] == tile and board[x][y+1] == tile and board[x][y+2] == tile and board[x][y+3] == tile:
                return True

    # check / diagonal spaces
    for x in range(boardWidth - 3):
        for y in range(3, boardHeight):
            if board[x][y] == tile and board[x+1][y-1] == tile and board[x+2][y-2] == tile and board[x+3][y-3] == tile:
                return True

    # check \ diagonal spaces
    for x in range(boardWidth - 3):
        for y in range(boardHeight - 3):
            if board[x][y] == tile and board[x+1][y+1] == tile and board[x+2][y+2] == tile and board[x+3][y+3] == tile:
                return True

    return False

如有任何帮助或建议,我们将不胜感激。提前致谢!

您刚刚混淆了尺寸,您应该这样设置它们:

def checkOWin(board):
    boardHeight = len(board[0])
    boardWidth = len(board)

因为当你引用 board[x] 时,那是在计算 board 中列表的数量,而当你引用 board[x][y] 时 那是到板中一个特定行的长度。

if board[x][y] == tile and board[x+1][y] == tile and board[x+2][y] == tile and board[x+3][y] == tile:

当我翻转这些值时,函数 运行 没有错误。

好的,所以这是 3 年后的事了,我正在学习编程和 Python 并正在做我自己的 Connect Four 项目所以请耐心等待...但我认为问题出在条件上。

这是一个示例输入,应该与 OP 使用的类似:

board = [['_','_','_','_','_','_','_'],
         ['_','_','_','_','_','_','_'],
         ['_','_','_','X','_','_','_'],
         ['_','_','_','O','_','_','_'],
         ['_','X','X','O','O','O','O'],
         ['X','X','X','O','O','X','O']]

我将条件修改为:

  for x in range(boardWidth):
    for y in range(boardHeight):
      try:
        if board[y][x] == tile and board[y][x+1] == tile and board[y][x+2] == tile and board[y][x+3] == tile:
          return True
      except IndexError:
        next

我们在看板列表中存储了 6 个不同的列表。 y 在访问面板时排在第一位,因为它首先告诉我们需要使用这 6 个列表中的哪一个,从而在面板列表中向上或向下移动。现在 x 索引将我们移动到我们访问过的任何 y 列表中。

try 和 except 允许您删除 for x in range(boardWidth - 3),因为如果收到索引错误,我们知道我们已经到达游戏板的边缘并且无法满足获胜条件。所以我们继续下一个要测试的点。

虽然连续嵌套的 for 循环是检测获胜的明显解决方案,但在 python 等语言中这是一种相当缓慢的方法。该问题实际上可以被同化为在 Connect 4 board 的两个维度上进行卷积运算,卷积核设计为匹配 4 个图块的水平、垂直和对角线。

因此,更快的方法是:

  1. 为水平、垂直和对角线获胜检测创建内核。
horizontal_kernel = np.array([[ 1, 1, 1, 1]])
vertical_kernel = np.transpose(horizontal_kernel)
diag1_kernel = np.eye(4, dtype=np.uint8)
diag2_kernel = np.fliplr(diag1_kernel)
detection_kernels = [horizontal_kernel, vertical_kernel, diag1_kernel, diag2_kernel]
  1. 从您的棋盘创建一个二维数组,其中玩家的所有棋子都设置为 1,所有 empty/opponent 个棋子都设置为 0。

  2. 运行 棋盘使用 Scipy 高度优化的 convolve2d 函数进行卷积运算。

  3. 卷积输出形成的数组中,任意一个“4”表示棋盘上有4个相连的方块

from scipy.signal import convolve2d

def winning_move(board, player):
    for kernel in detection_kernels:
        if (convolve2d(board == player, kernel, mode="valid") == 4).any():
            return True
    return False

这允许大量 speed-up 用于检测获胜条件,这在对游戏树实施 tree-search 类算法时至关重要。我还发现此解决方案更加优雅和可读。