Python:为什么这个算法不能按预期工作?

2024-04-27 02:27:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我在代码战上遇到了一个问题。描述如下:

在流行的扫雷游戏中,你的棋盘上有一些地雷,而那些不包含地雷的单元格中有一个数字,表示相邻单元格中地雷的总数。从一些地雷的安排开始,我们想创建一个扫雷游戏设置。

示例

为了

matrix = [[True, False, False],
      [False, True, False],
      [False, False, False]]

输出应为:

minesweeper(matrix) = [[1, 2, 1],
                   [2, 1, 1],
                   [1, 1, 1]]  

所以根据我的理解,我们必须看整个矩阵,因为我们需要知道哪些单元格是真的,即包含一个炸弹,当我们找到一个炸弹时,所有相邻单元格的值应该增加1。我第一次尝试使用if/elif语句为边界单元格编写代码(不抛出错误),但是代码变得非常难看和冗长。所以我唯一能想到的是:

def minesweeper(matrix):

# First creating the same matrix but instead full of zeros.
result = [[0]* len(matrix[0]) for row in matrix]

# Start iterating through the original matrix to find True elements
for y in range(len(matrix)):
    for x in range(len(matrix[0])):
        if matrix[y][x] == True:

            # The remaining code tries to increment all possible neighbours by 1.
            for j in range(-1,2):
                for i in range(-1,2):

                    # If statement so that we do not increment the bomb cell itself.
                    if not (j == 0 and i == 0):
                        try:
                            result[y+j][x+i] += 1
                        except:
                            continue
return result

函数的输出

input = [[True, False, False],
        [False, True, False],
        [False, False, False]]

[[1, 2, 2], [2, 1, 2], [2, 2, 2]]

有人知道为什么它不起作用吗?我也知道你应该试着用try/except语句来捕捉错误,这可能是一种不好的做法,如果没有超长的if/elif语句,我就想不出另一种方法。你知道吗


Tags: the代码infalsetrue游戏forlen
3条回答

在执行lenminmax函数时限制范围的另一种可能方法是只执行一次,而不检查每个点上的单元格是否是单元格本身(迭代):

true = True  # or "true"
false = False  # or "false"

matrix = [[true, false, false],
          [false, true, false],
          [false, false, false]]


def minesweeper(matrix):
    # First creating the same matrix but instead full of zeros.
    result = [[0] * len(matrix[0]) for row in matrix]

    # Start iterating through the original matrix to find "true" elements
    y_max = len(matrix)
    for y in range(y_max):
        x_max = len(matrix[0])
        for x in range(x_max):
            if matrix[y][x] == true:
                # The remaining code increments all neighbours by 1, but not beyond the matrix size!
                for dy in range(max(0, y - 2), min(y_max, y + 2)):
                    for dx in range(max(0, x - 2), min(x_max, x + 2)):
                        result[dx][dy] += 1
                # Do not increment the bomb cell itself (it was).
                result[y][x] -= 1

    return result

print(minesweeper(matrix))给出期望的结果[[1, 2, 1], [2, 1, 1], [1, 1, 1]]。你知道吗

我认为您的问题是使用负索引访问值在Python中是有效的操作。因此,在处理第一个元素时,将增加结果矩阵中的最后一个元素。你知道吗

你应该试着用更小的步骤来调试你的代码,或者使用调试器单步调试,或者在第一次迭代x和y之后停止并签出值

在公认答案的帮助下,下面的代码工作了。try/except语句完全没有用,因为它里面的代码无论如何都不会抛出错误。你知道吗

def minesweeper(matrix):
    result = [[0]* len(matrix[0]) for row in matrix]

    for y in range(len(matrix)):
        for x in range(len(matrix[0])):
            if matrix[y][x] == True:
                for j in range(-1,2):
                    for i in range(-1,2):
                        if not (j == 0 and i == 0) and not ((y+j) < 0 or (x+i) < 0):    
                            result[y+yi][x+xi] += 1
    return result

相关问题 更多 >