重度嵌套循环中的随机生成

时间:2015-06-24 13:57:14

标签: python arrays python-2.7 multidimensional-array

我有一个小小的游戏,我一直在为一个学校项目做,并且它一直在努力。

我使用了一个非常混乱的嵌套列表系统用于多个屏幕,每个屏幕都有一个2D数组用于屏幕上的对象。这些2D“水平”阵列也排列在它们自己的2D阵列中,构成了“世界”。字符串对应于使用pygame绘制的对象图块。

我的问题是level中的每个world array数组都相同,我无法理解为什么会这样。

 def generate_world(load):
    # This bit not important
    if load is True:
        in_array()
    # This is
    else:
        for world_y in Game_world.game_array:
            for world_x in world_y:
                generate_clutter(world_x)

    print Game_world.game_array
    out_array()
    # Current_level.array = Level.new_level_array


def generate_clutter(world_x):
    for level_y in world_x:
        for level_x, _ in enumerate(level_y):

            ### GENERATE CLUTTER ###
            i = randrange(1, 24)
            if i == 19 or i == 20:
                level_y[level_x] = "g1"
            elif i == 21 or i == 22:
                level_y[level_x] = "g2"
            elif i == 23:
                level_y[level_x] = "c1"
            else:
                level_y[level_x] = "-"

我确信这是一个简单的我忽略的东西,但对我而言,似乎应该对每个单独的列表项进行随机生成,所以我无法理解重复。

我知道四重嵌套列表并不漂亮,但我认为我现在太深了,无法做出任何重大改变。

编辑:

这是最初创建列表/数组的要点。它们的大小永远不会改变,现有的字符串只会被替换。

class World:

    def __init__(self, name, load):
        if load is False:
            n = [["-" for x in range(20)]for x in range(15)]

            self.game_array = [[n, n, n, n, n, n, n],
                              [n, n, n, n, n, n, n],
                              [n, n, n, n, n, n, n]]

1 个答案:

答案 0 :(得分:0)

在Python中,一切都是对象 - 甚至是整数值。如何初始化“空”数组可能会产生一些令人惊讶的结果。

考虑这个初始化:

>>> l=[[1]*2]*2
>>> l
[[1, 1], [1, 1]]

您似乎创建了一个2x2矩阵,每个单元格包含值1。实际上,您已创建了两个列表的列表(每个列表包含[1,1])。更深入的是,您已创建了对单个列表[1,1]的两个引用的列表。

如果您现在修改其中一个单元格

,则可以看到此结果
>>> l[0][0]=2
>>> l
[[2, 1], [2, 1]]
>>> 

请注意,l[0][0]l[1][0]都已修改。

为了避免这种影响,你需要跳过一些箍

>>> l2 = [[1 for _ in range(2)] for _ in range(2)]
>>> l2
[[1, 1], [1, 1]]
>>> l2[0][0]=2
>>> l2
[[2, 1], [1, 1]]
>>> 

如果您使用前一种方法初始化Game_world.game_array,则level_y[level_x]的每项任务都将修改数组中的多个单元格。

作为附加评论,您可以使用generate_clutter

轻微简化dict功能
def generate_clutter(world_x):
    clutter_map = {19:"g1", 20:"g1", 21:"g2", 22:"g2", 23:"c1"}
    for level_y in world_x:
        for level_x, _ in enumerate(level_y):
            level_y[level_x] = clutter_map.get(randrange(1,24),'-')

这将选择杂波表示的逻辑与值的实际映射分开,并且更容易扩展和维护。

查看您的编辑,初始化需要类似于:

self.game_array = [
                   [
                    [
                     ["-" for x in range(20)]
                     for x in range(15)
                    ]
                    for x in range(7)
                   ]
                   for x in range(3)
                  ]