在Python中,有没有一种方法可以检查2维数组的对角线,它的大小是可变的?

问题描述 投票:1回答:1

我目前正在使用基于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循环的情况下基本检查矩阵内的范围窗口?

提前感谢。

python math matrix multidimensional-array game-development
1个回答
0
投票

我们可以使用递归解决此类问题,其中函数递归检查矩阵中下一个元素的条件,即玩家是否有获胜举动。以下是有效的代码,可在任何大小的2D数组或矩阵上工作。输出也显示在代码之后。

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
© www.soinside.com 2019 - 2024. All rights reserved.