I am in the middle of re-factoring the Block Party codebase to be more object oriented so I can easily scale the graphics and add multiplayer support. In the process I changed some algorithms around to make them clearer and more streamlined. I got the code to working fairly well but there was one weird bug that was stumping me. When the blocks got stacked to a certain height they started drawing trails from the top of the screen to where they ended up resting. I couldn’t figure out what was going on because all of my printouts showed that I was only writing into the game grid at the proper x, y coordinates. . I then decided to print out the whole game grid every time I placed a block. Here is what I came up with:

pythonbug-bp

As it turns out my optimizations of the line dropping code was the culprit. I was doing pretty much the same thing as the old code except the old code worked by deep copying the game grid every time it did a change. My problem came down to one simple line in the algorithms:

for ii in range(clearlines[i] - 1, nextclearline, -1):
    self.grid[ii + i + 1] = self.grid[ii]

Changing it to this fixed the issue

for ii in range(clearlines[i] - 1, nextclearline, -1):
    self.grid[ii + i + 1] = list(self.grid[ii])

Notice before I was copying the address of the row into its dropped position. In the old code we were copying between two different grids so this didn’t matter. I’ve changed it to use the same grid when dropping lines. What would happen is every time a line was dropped the top row’s address would be copied to the next row but the top row would not get a list. In essence the top two rows would be the same list. Every time after that a line was dropped the next row would get the same list until your blocks stacked high enough and wrote into one of those rows. After that it is sort of like crossing the streams in Ghost Busters, bad mojo would happen, except this time I don’t think you would save the world from Zuul.

The solution, and I should have known better, was to make sure the row is copied instead of assigned. A further optimized solution would have been to special case the top row and just create a new list for that and do the assignments for the rest of the rows. Something like this should do just fine:

for ii in range(clearlines[i] - 1, nextclearline, -1):
    self.grid[ii + i + 1] = self.grid[ii]

#row 0 is just there for padding so we can copy ourself
self.grid[0] = list(self.grid[0])

[read this post in: ar de es fr it ja ko pt ru zh-CN ]