| 55 | |
| 56 | |
| 57 | class Tetris: |
| 58 | def __init__(self, width, height): |
| 59 | self.width = width |
| 60 | self.height = height |
| 61 | self.grid = [[0 for _ in range(width)] for _ in range(height)] |
| 62 | self.current_piece = self.new_piece() |
| 63 | self.game_over = False |
| 64 | self.score = 0 # Add score attribute |
| 65 | |
| 66 | def new_piece(self): |
| 67 | # Choose a random shape |
| 68 | shape = random.choice(SHAPES) |
| 69 | # Return a new Tetromino object |
| 70 | return Tetromino(self.width // 2, 0, shape) |
| 71 | |
| 72 | def valid_move(self, piece, x, y, rotation): |
| 73 | """Check if the piece can move to the given position""" |
| 74 | for i, row in enumerate( |
| 75 | piece.shape[(piece.rotation + rotation) % len(piece.shape)] |
| 76 | ): |
| 77 | for j, cell in enumerate(row): |
| 78 | try: |
| 79 | if cell == "O" and ( |
| 80 | self.grid[piece.y + i + y][piece.x + j + x] != 0 |
| 81 | ): |
| 82 | return False |
| 83 | except IndexError: |
| 84 | return False |
| 85 | return True |
| 86 | |
| 87 | def clear_lines(self): |
| 88 | """Clear the lines that are full and return the number of cleared lines""" |
| 89 | lines_cleared = 0 |
| 90 | for i, row in enumerate(self.grid[:-1]): |
| 91 | if all(cell != 0 for cell in row): |
| 92 | lines_cleared += 1 |
| 93 | del self.grid[i] |
| 94 | self.grid.insert(0, [0 for _ in range(self.width)]) |
| 95 | return lines_cleared |
| 96 | |
| 97 | def lock_piece(self, piece): |
| 98 | """Lock the piece in place and create a new piece""" |
| 99 | for i, row in enumerate(piece.shape[piece.rotation % len(piece.shape)]): |
| 100 | for j, cell in enumerate(row): |
| 101 | if cell == "O": |
| 102 | self.grid[piece.y + i][piece.x + j] = piece.color |
| 103 | # Clear the lines and update the score |
| 104 | lines_cleared = self.clear_lines() |
| 105 | self.score += ( |
| 106 | lines_cleared * 100 |
| 107 | ) # Update the score based on the number of cleared lines |
| 108 | # Create a new piece |
| 109 | self.current_piece = self.new_piece() |
| 110 | # Check if the game is over |
| 111 | if not self.valid_move(self.current_piece, 0, 0, 0): |
| 112 | self.game_over = True |
| 113 | return lines_cleared |
| 114 | |