[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Sticky Variables: Terrain Loading



I've encountered another case of variables being taken as references
rather than values. In trying to load an image and use its colors to
decide which of several terrains to add to a growing list, I did this:

            for y in range(self.size):
                for x in range(self.size):
                    rgb = the_map.get_at((x,y))
                    r = rgb[0] > 100
                    g = rgb[1] > 100
                    b = rgb[2] > 150
                    y = r and g
                    if b:
                        terrain = "water"
                    elif y:
                        terrain = "sand"
                    else:
                        terrain = "grass"
                    self.land.append(terrain)
                    del terrain

Ie., look at pixel (x,y) in the_map and pick a terrain based on the
colors. The problem is, the program decides that it's adding references
to the same variable, "terrain," rather than doing what I want: adding a
string. The result is that every entry in the "land" ends up being not
only identical, but the same entry. Even though I "del terrain" to make
it plain that I want to create a new variable.
g.world.land[0] is g.world.land[1]
True

I can fix the problem here just by saying "if b:
self.land.append("water")", but I'd like to know the underlying problem
here. The "del terrain" line was an afterthought because I assumed that
"terrain" went out of scope every pass through the loop, or that by
assigning it a new string value Python would understand that I want to
add the _string_ to the list and not a reference to the variable; and I
would think that "del terrain" should unambiguously say STOP KEEPING
TRACK OF THIS VARIABLE. So, what am I doing wrong here?

In contrast, my random-terrain code used in a test works fine:
terrain = ["grass","sand","water"][random.randint(0,2)]
self.land.append(terrain)