如何使用随机模块获得更好的结果

时间:2019-01-04 09:21:00

标签: python python-3.x random

我目前正在使用Python进行扫雷游戏,但是我的地雷分区存在一些问题:

要选择不同地雷的位置,我使用Python random模块生成x和y坐标。首先,我选择将所有地雷放置在玩家第一次上场比赛之前,但问题是,第一场比赛通常是一个地雷或一个以地雷为邻居的地雷。因此,我决定在玩家首次玩游戏后放置地雷,以确保显示的第一个cas不会与地雷为邻,但问题在于,对于地雷游戏来说,地雷的重新分配不是很有趣。我该如何做得更好?

这是我的功能,可在玩家第一次玩后在pos是第一个cas坐标显示的情况下将地雷放在Board类中:

    def place_mines(self, pos):
        posed_mines = 0
        while posed_mines < self.mines_number:
            x = random.randrange(0, COLUMN_NUMBER-1)
            y = random.randrange(0, LINE_NUMBER-1)
            if not self.Matrix[y][x].is_mined and (x < pos[0]-1 or x > pos[0]+1) and (y < pos[1]-1 or y > pos[1]+1):
                self.Matrix[y][x].mine()
            posed_mines += 1

游戏结果:

mines repartition

以下是在玩家首次播放之前放置所有地雷的功能:

    def place_mines(self):
        posed_mines = 0
        while posed_mines < self.mines_number:
            x = random.randrange(0, COLUMN_NUMBER-1)
            y = random.randrange(0, LINE_NUMBER-1)
            if not self.Matrix[y][x].is_mined:
                self.Matrix[y][x].mine()
                posed_mines += 1

以及游戏结果:

mines repartition

我的问题不是重复的,因为在链接的问题上,玩家首次玩游戏后没有完成排雷

1 个答案:

答案 0 :(得分:1)

如果您不关心时间/空间的复杂性,并且电路板足够小而无需关心,则可以使用random.sample()进行选择:

import random, itertools

def place_mines(self, pos):
    available_cells = set(itertools.product(range(COLUMN_NUMBER-1), range(LINE_NUMBER-1))))
    available_cells.remove(pos)
    for x, y in random.sample(available_cells, self.mines_number):
        self.Matrix[y][x].mine()

如果mines_number大大小于电路板的尺寸,则存在更多的计算效率更高的解决方案,但是只要上面的代码不需要紧闭循环并且电路板的尺寸合理,则上面的地图生成就可以了。


现在,关于代码样式的评论无关:为什么要使用COLUMN_NUMBER-1LINE_NUMBER-1?如果COLUMN_NUMBERLINE_NUMBER是self.MATRIX的大小,则这看起来像是一个一次性的错误。通常,您只需使用range(len(lst))random.randrange(0, len(lst))即可获得与lst相同大小的范围,而不必将len(lst)减1。