繁体   English   中英

Python连接4检查win函数

[英]Python connect 4 check win function

我正在编写一个连接 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

任何帮助或建议将不胜感激。 提前致谢!

尽管连续嵌套的 for 循环是检测获胜的明显解决方案,但在 Python 等语言中这是一种相当慢的方法。 该问题实际上可以同化为 Connect 4 板的两个维度上的卷积操作,其卷积核旨在匹配 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. 从您的棋盘创建一个 2D 数组,其中玩家的所有图块都设置为 1,所有空/对手图块都设置为 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

这可以极大地加速检测获胜条件,这对于在博弈树上实施类似树搜索的算法至关重要。 我还发现这个解决方案更加优雅和可读。

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

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

因为当你提到 board[x] 时,这是计算板中列表的数量,而当你提到 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)因为如果收到索引错误,我们知道我们已经到达游戏板的边缘并且无法满足获胜条件。 所以我们继续下一个测试点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM