首页 > 解决方案 > 有没有办法检查 Python 中具有可变大小的二维数组的对角线?

问题描述

我目前正在基于 Connect 4 逻辑在 Python 中编写 Connect N 游戏(您需要连续 4 块才能获胜的游戏)。我基本上编写了 Connect 4 函数,但很难让它在 n 维获胜条件下工作。

我需要基本上检查水平、垂直、正斜率和负斜率对角线,它们连续有 4 个相同的部分。对于我的 Connect 4 逻辑,我有以下内容:

def winning_move(board, player_number):
    # Check horizontal locations for win
    for c in range(COLUMN_COUNT-3):
        for r in range(ROW_COUNT):
            if board[r][c] == player_number and board[r][c+1] == player_number and board[r][c+2] == player_number and board[r][c+3] == player_number:
                return True

    # Check vertical locations for win
    for c in range(COLUMN_COUNT):
        for r in range(ROW_COUNT-3):
            if board[r][c] == player_number and board[r+1][c] == player_number and board[r+2][c] == player_number and board[r+3][c] == player_number:
                return True

    # Check positively sloped diaganols
    for c in range(COLUMN_COUNT-3):
        for r in range(ROW_COUNT-3):
            if board[r][c] == player_number and board[r+1][c+1] == player_number and board[r+2][c+2] == player_number and board[r+3][c+3] == player_number:
                return True

    # Check negatively sloped diaganols
    for c in range(COLUMN_COUNT-3):
        for r in range(3, ROW_COUNT):
            if board[r][c] == player_number and board[r-1][c+1] == player_number and board[r-2][c+2] == player_number and board[r-3][c+3] == player_number:
                return True

以我有限的知识,我考虑过使用 for 循环进行迭代,但我不能将 for 循环作为 if 的条件。所以我认为可能有一种方法可以检查矩阵的某个范围,但在任何地方都找不到我该怎么做。

有没有办法在不使用 for 循环的情况下基本上检查矩阵内的范围窗口?

提前致谢。

标签: pythonmathmatrixmultidimensional-arraygame-development

解决方案


我们可以使用递归来解决这些问题,其中函数递归地检查矩阵中下一个元素的条件,即玩家是否有获胜的举动。以下是一个工作代码,它适用于任何大小的二维数组或矩阵。输出也显示在代码之后。

def winning_move_new(my_board, player_number):

    num_rows = len(my_board)
    num_cols = len(my_board[0])

    found_win = False

    if findAdjacentElementsMatch(my_board, player_number, num_rows, num_cols, "row_search"):
        found_win = True

    if findAdjacentElementsMatch(my_board, player_number, num_rows, num_cols, "col_search"):
        found_win = True

    if findAdjacentElementsMatch(my_board, player_number, num_rows, num_cols, "diag_search"):
        found_win = True

    if findAdjacentElementsMatch(my_board, player_number, num_rows, num_cols, "neg_diag_search"):
        found_win = True

    return found_win

def findAdjacentElementsMatch(board, player_number, num_rows, num_cols, search_type):

    if search_type == "row_search":
        for row in range(num_rows):
            if isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type = "row_search",
                                         next_row = row, next_col = 0):
                print("Found row matching at row=", row)
                return True

    elif search_type == "col_search":
        for col in range(num_cols):
            if isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type = "col_search", 
                                         next_row = 0, next_col = col):
                print("Found column matching at column=", col)
                return True

    elif search_type == "diag_search":
        if isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type = "diag_search", 
                                     next_row = 0, next_col = 0):
            print("Found diagonal matching")
            return True

    elif search_type == "neg_diag_search":
        if isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type = "neg_diag_search", 
                                     next_row = num_rows-1, next_col = 0):
            print("Found negative-diagonal matching")
            return True

    return False

def isNextElementAlsoMatching(board, player_number, num_rows, num_cols, 
                              search_type, next_row = 0, next_col = 0):

    if (next_row >= num_rows or next_col >= num_cols or
        next_row < 0         or next_col < 0):
        return True # The last recursive step

    else:
        if (search_type == 'row_search'):
            # Row-search looks for entries in the next column within the same row
            return (board[next_row][next_col] == player_number and 
                    isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type, 
                                              next_row, next_col+1))

        elif (search_type == 'col_search'):
            # Column-search looks for entries in the next row within the same column
            return (board[next_row][next_col] == player_number and 
                    isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type,
                                              next_row+1, next_col))

        elif (search_type == 'diag_search'):
            # Diagonal-search looks for entries with the same row,col indices
            return (board[next_row][next_col] == player_number and 
                    isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type,
                                              next_row+1, next_col+1))

        elif (search_type == 'neg_diag_search'):
            # Negative-diagonal-search looks for entries in the reverse-diagonal
            return (board[next_row][next_col] == player_number and 
                    isNextElementAlsoMatching(board, player_number, num_rows, num_cols, search_type,
                                              next_row-1, next_col+1))


my_board = [[12, 12, 14, 12],\
            [19, 12, 12, 17],\
            [12, 12, 12, 12],\
            [12, 12, 15, 12]]

player_number = 12
winning_move_new(my_board, player_number)

上述矩阵的这段代码的输出是:

Found row matching at row= 2
Found column matching at column= 1
Found diagonal matching
Found negative-diagonal matching

推荐阅读