首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python connect 4 check win函数

Python connect 4 check win函数
EN

Stack Overflow用户
提问于 2015-04-30 00:12:16
回答 3查看 16.1K关注 0票数 8

我正在写一个连接4游戏,在其中你可以选择棋盘的大小。这个游戏在大多数棋盘大小下都能完美地工作,但当棋盘比它宽时,它会给我带来问题。我不断得到索引超出范围的错误,我不确定我做错了什么。这就是我现在的检查功能,因为它是唯一给我带来问题的部分。

代码语言:javascript
复制
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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-30 00:23:06

你刚刚混淆了你的维度,你应该这样设置:

代码语言:javascript
复制
def checkOWin(board):
    boardHeight = len(board[0])
    boardWidth = len(board)

因为当你引用boardx时,这是在计算板子中列表的数量,而当你引用boardx时,它只是指板子中特定行的长度。

代码语言:javascript
复制
if board[x][y] == tile and board[x+1][y] == tile and board[x+2][y] == tile and board[x+3][y] == tile:

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

票数 8
EN

Stack Overflow用户

发布于 2020-09-21 19:59:30

虽然连续嵌套的for循环是win检测的明显解决方案,但在python这样的语言中,这是一种相当慢的方法。这个问题实际上可以归结为在Connect 4板的两个维度上的卷积操作,卷积内核设计为匹配4块瓷砖的水平、垂直和对角线。

因此,一种更快的方法是:

  1. 创建用于水平、垂直和对角win检测的内核。

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。

  1. 使用Scipy高度优化的convolve2d函数对电路板进行卷积运算。

  1. 在由卷积输出形成的数组中,任何"4“都表示板中有4个相连的瓦片。

从scipy.signal导入

def winning_move(scipy.signal,player):对于detection_kernels中的内核: if ( convolve2d (board == player,mode=,==“valid”)== 4).any():return True返回False

这使得检测获胜条件的速度大大加快,这在游戏树上实现类似树搜索的算法时至关重要。我还发现这个解决方案更优雅,更具可读性。

票数 15
EN

Stack Overflow用户

发布于 2018-11-01 07:28:15

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

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

代码语言:javascript
复制
board = [['_','_','_','_','_','_','_'],
         ['_','_','_','_','_','_','_'],
         ['_','_','_','X','_','_','_'],
         ['_','_','_','O','_','_','_'],
         ['_','X','X','O','O','O','O'],
         ['X','X','X','O','O','X','O']]

我将条件修改为:

代码语言:javascript
复制
  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),因为如果收到索引错误,我们知道我们已经到达游戏板的边缘,无法满足win条件。因此,我们进入下一个要测试的点。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29949169

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档