我正在写一个连接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
Run Code Online (Sandbox Code Playgroud)
任何帮助或建议将不胜感激.提前致谢!
Man*_*sse 14
尽管连续嵌套的 for 循环是检测胜利的明显解决方案,但在 Python 等语言中这是一种相当慢的方法。该问题实际上可以同化为 Connect 4 板的两个维度上的卷积操作,其卷积核旨在匹配 4 个瓦片的水平、垂直和对角线。
因此,更快的方法是:
Run Code Online (Sandbox Code Playgroud)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]
从您的棋盘创建一个 2D 数组,其中玩家的所有图块都设置为 1,所有空/对手图块都设置为 0。
使用 Scipy 高度优化的 convolve2d 函数通过卷积操作运行电路板。
在卷积输出形成的数组中,任何“4”表示棋盘中有4个连接的瓦片。
Run Code Online (Sandbox Code Playgroud)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)
Run Code Online (Sandbox Code Playgroud)
因为当你引用board [x]时,那就是计算电路板中列表的数量,当你引用电路板[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:
Run Code Online (Sandbox Code Playgroud)
当我翻转这些值时,函数运行没有错误.