在Python中创建扫雷器时出现问题

在Python中创建扫雷器时出现问题,python,python-3.x,terminal,Python,Python 3.x,Terminal,我的任务是在航站楼作为一个项目创建扫雷舰。我对Python比较陌生,所以这对我来说是一个相当大的任务。由于某种原因,我无法正确计算炸弹周围的数字。我在下面粘贴了代码和一些输出。我在运行代码时没有收到任何错误。(我注意到这可能与炸弹上方右上角区块的代码有关,但我查看了所有内容,似乎都找不到问题所在。有时炸弹数量也比应该的少。) 有两件事很突出: random.randrange不包括端点,因此,如果端点为dim_size-1,则意味着您只能生成0到3之间的数字。这意味着地雷永远不会出现在最下面一行

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


有两件事很突出:

random.randrange
不包括端点,因此,如果端点为
dim_size-1
,则意味着您只能生成0到3之间的数字。这意味着地雷永远不会出现在最下面一行或最右边一列的任何地方

第二个问题,你已经指出,与你放置地雷的方式有关。生成一个随机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
>>> 

好吧,因为“有时炸弹的数量也比应该的少”。。。您需要使用While循环来跟踪您在网格中放置的炸弹数量。使用for loop只能在范围内运行(num_bombs)&它不在乎是否放置了所需数量的炸弹。但是While循环将首先检查代码是否放置了所需的num_炸弹,如果是的话。。。它将停止运行,但如果没有,它将继续运行

同样在放置炸弹之前,你需要检查该行/列是否有炸弹,如果有。。。不要放置炸弹。。。如果不是的话,就埋下炸弹

代码如下:

planted_num_bomb=0#放置的炸弹数量
当放置炸弹
有5个结果:

    0    0    2    X    1    
    1    1    3    X    2    
    2    X    3    X    2
    2    X    3    1    1
    1    1    1    0    0
    
    1    2    1    0    0    
    1    X    X    1    0    
    2    4    X    3    0
    1    X    3    X    1
    1    1    2    1    1
    5 #number of bombs planted
    
    1    0    2    X    1    
    X    1    2    X    2    
    3    2    1    1    1
    X    X    1    0    0
    2    2    1    0    0
    5 #number of bombs planted
    
    1    0    1    1    0    
    X    2    2    X    1    
    3    3    X    2    1    
    X    X    2    1    0
    2    2    1    0    0
    5 #number of bombs planted

0    0    0    0    0    
2    2    1    0    0    
X    X    X    2    0    
X    4    3    X    1
1    1    1    1    1
5 #number of bombs planted
现在如果你看看。。。代码无法将地雷放置在第5列。。。为什么?答案在顶部(第一个答案)。如果你找到了这个问题的解决方案,仍然使用while循环,因为for循环并不总是安装所需数量的炸弹,为什么?因为,在for循环中,当我们跳过(有炸弹时代码中的继续部分)时,for循环仍然将其视为迭代


无论如何,祝你在WTC训练营好运。

在右上角的案例中,建议
random.sample
使用>而不是+1。请注意,通过
sample
ing一个
范围(dim\u size**2)
对象,然后使用
divmod(num,dim\u size)
将每个原始数字转换为坐标,可以更有效地实现这一点。由于
range
是一个惰性序列,因此无论电路板有多大,制作一个都不会产生任何成本,而
list
ifying
itertools.product
必须执行更多的工作(无可否认,对于任何合理大小的电路板,它可能“足够快,用户永远不会注意到”)。
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
>>> 
    0    0    2    X    1    
    1    1    3    X    2    
    2    X    3    X    2
    2    X    3    1    1
    1    1    1    0    0
    
    1    2    1    0    0    
    1    X    X    1    0    
    2    4    X    3    0
    1    X    3    X    1
    1    1    2    1    1
    5 #number of bombs planted
    
    1    0    2    X    1    
    X    1    2    X    2    
    3    2    1    1    1
    X    X    1    0    0
    2    2    1    0    0
    5 #number of bombs planted
    
    1    0    1    1    0    
    X    2    2    X    1    
    3    3    X    2    1    
    X    X    2    1    0
    2    2    1    0    0
    5 #number of bombs planted

0    0    0    0    0    
2    2    1    0    0    
X    X    X    2    0    
X    4    3    X    1
1    1    1    1    1
5 #number of bombs planted