Okay so I'm using Pygame to make Tetris, and my problem is that when the piece hits the bottom, the program draws the blocks to the entire column instead of only the rows it is meant to. I am using a board object with a 2-dimensional list of block objects.
class Block:
def __init__(self, exists, color):
self.exists = exists
self.color = color
class Board:
def __init__(self, state, bottom, points, level, alive):
self.state = state
self.alive = alive
self.bottom = bottom
self.points = points
self.level = level
# Different Script
board = Board.Board([[Board.Block(False, (0, 0, 0))] * 10] * 20, [670, 670, 670, 670, 670, 670, 670, 670, 670, 670], 0, 1, True)
I think the problem should be here. It seems like the program is filling the entire column with blocks with exists = True, but I cannot figure out why. My logic for if/when the piece hits the bottom:
bottom = [None] * len(piece.shape)
for col in range(len(piece.bottom())):
index = int(((piece.position[0] - 10) / 30) - 8 col)
bottom[col] = board.bottom[index]
for col in range(len(bottom)):
if(piece.bottom()[col] == bottom[col]):
new_piece = True
break
if(new_piece):
for row in range(len(piece.shape)):
for col in range(len(piece.shape[row])):
if(piece.shape[row][col] == 1):
block = Board.Block(True, piece.color)
index_col = int(((piece.position[0] - 10) / 30) - 8 col)
index_row = int(((piece.position[1] - 10) / 30) - 3 row)
board.state[index_row][index_col] = block
piece = PieceSelector.selector()
The reason I have that weird math for index_row/index_col is because the board is a pygame.rect object with dimensions (250, 100, 300, 600). So that is simply the algorithm to convert the pixel value to the index of the list. It is probably helpful to have an idea of the Piece class:
class Piece:
def __init__(self, position, shape, index, color):
self.shape = shape
self.color = color
self.index = index
self.position = position
# Example Piece
long_piece = Piece([250, 100], [[1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], 0, [255, 128, 0])
Also this is the function that actually draws the blocks. I do not think this is the problem but I should probably still include it.
def draw_blocks(self, screen):
for row in range(len(self.state)):
for col in range(len(self.state[row])):
if(self.state[row][col].exists):
row_pxl = row * 30 100
col_pxl = col * 30 250
py.draw.rect(screen, self.state[row][col].color, (col_pxl, row_pxl, 29, 29))
CodePudding user response:
I haven’t checked out all your code, but the obvious problem is when you are doing bottom = [None] * len(piece.shape)
, this basically creates multiple references to the same object, hence when one changes - all change.
Try changing it to: bottom = [None for _ in range(len(piece.shape))]