首页 > 解决方案 > 在 Python 中创建扫雷时出现的问题

问题描述

我的任务是在终端中创建扫雷器作为一个项目。我对 Python 比较陌生,所以这对我来说是一项艰巨的任务。出于某种原因,我无法正确计算炸弹周围的数字。我在下面粘贴了代码和一些输出。运行代码时我没有收到任何错误。(我注意到这可能与炸弹上方右上角的代码有关,但我已经查看了所有内容,似乎找不到问题。有时炸弹也比应有的少。 )

import random

def minesweeper(dim_size, num_bombs):

    print_list = []

    for i in range(dim_size):
        print_list.append([])
        for j in range(dim_size):
            print_list[i].append(0)

    for i in range(num_bombs):
        random_row = random.randrange(0,dim_size-1)
        random_column = random.randrange(0,dim_size-1)
        print_list[random_row][random_column] = 'X'

        # centre-top
        if random_row >= 1:
            if print_list[random_row - 1][random_column] != 'X':
                print_list[random_row - 1][random_column] += 1
        # right-top
        if random_row >= 1 and random_column > dim_size:
            if print_list[random_row - 1][random_column + 1] != 'X':
                print_list[random_row - 1][random_column + 1] += 1
        # right
        if random_column < dim_size:
            if print_list[random_row][random_column + 1] != 'X':
                print_list[random_row][random_column + 1] += 1
        # bottom-right
        if random_row < dim_size and random_column < dim_size:
            if print_list[random_row + 1][random_column + 1] != 'X':
                print_list[random_row + 1][random_column + 1] += 1
        # bottom
        if random_row < dim_size:
            if print_list[random_row + 1][random_column] != 'X':
                print_list[random_row + 1][random_column] += 1
        # bottom-left
        if random_row < dim_size and random_column >= 1:
            if print_list[random_row + 1][random_column - 1] != 'X':
                print_list[random_row + 1][random_column - 1] += 1
        # left
        if random_column >= 1:
            if print_list[random_row][random_column - 1] != 'X':
                print_list[random_row][random_column - 1] += 1
        # top-left
        if random_row >= 1 and random_column >= 1:
            if print_list[random_row - 1][random_column - 1] != 'X':
                print_list[random_row - 1][random_column - 1] += 1

    for row in range(dim_size):
        for column in range(dim_size):
            print(print_list[row][column], end='    ')
        print()

if __name__ == '__main__':
    minesweeper(5,5)

输出:

1    X    1    0    0    
2    3    3    1    0    
2    X    X    X    1    
X    3    3    2    1    
1    1    0    0    0  


2    X    1    0    0    
4    X    2    0    0    
X    X    3    0    0    
2    3    X    1    0    
0    1    1    1    0   


X    2    X    X    1    
X    3    2    2    1    
1    2    1    0    0    
0    1    X    1    0    
0    1    1    1    0    


X    3    X    2    0    
1    4    3    2    0    
1    1    X    1    0    
X    2    1    1    0    
1    1    0    0    0 

标签: pythonpython-3.xterminal

解决方案


有几件事很突出:

random.randrange不包括端点,所以如果你的端点是dim_size-1,那意味着你只会生成零到三(含)之间的数字。这意味着地雷永远不会出现在底行或最右列的任何位置。

您已经指出的第二个问题与您放置地雷的方式有关。你生成一个随机的 xy 坐标,然后在那里放置一个地雷。如果碰巧多次生成相同的坐标怎么办?您只需将另一个地雷放置在已被地雷占用的同一块区域中。

我将首先生成所有可能坐标的集合,而不是使用random.randrange,甚至random.randint生成随机坐标,然后使用random.sample从该集合中提取五个唯一坐标。以相同的方式绘制彩票号码,相同的数字(在我们的例子中是坐标)永远不能被多次绘制:

import random
import itertools

dim_size = 5
num_mines = 5

for x, y in random.sample(list(itertools.product(range(dim_size), repeat=2)), k=num_mines):
    print("Put a mine at {}, {}".format(x, y))

输出:

Put a mine at 4, 4
Put a mine at 4, 3
Put a mine at 3, 1
Put a mine at 1, 0
Put a mine at 3, 0
>>> 

推荐阅读