Home > OS >  Pygame Tetris Filling Entire Column
Pygame Tetris Filling Entire Column

Time:12-24

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))

Example of problem

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))]

  • Related