TECH / 2024-11-04
Building a Simple Tetris Game in Python in Just One Prompt!
#### Introduction
Recently, I watched a YouTube video by [Matthew Berman](https://www.youtube.com/watch?v=RRfbML4Lq40) about building games in Python. The video showed how straightforward Python game development could be and inspired me to create something classic: Tetris! I decided to challenge myself by asking ChatGPT to generate the code in just one prompt, and to my surprise, I got a fully functional (almost) Tetris game!
In this post, I’ll walk you through the code setup, provide the full code, and present some debugging challenges to make the game even better. Let’s dive in!
### Getting Started: The Power of a Single Prompt
After watching Matthew Berman’s video, I reached out to ChatGPT with a single prompt to generate a basic Tetris game using Python’s `pygame` library. Here’s how I got it up and running:
`pygame` `pygame` `pygame` `pip install pygame` `tetris.py` `python tetris.py`
### Full Code: A Simple Tetris Game in Python
Here’s the code generated by ChatGPT. It includes the main game components such as creating the grid, moving and rotating pieces, clearing rows, and more:
`import pygame import random # Initialize pygame pygame.init() # Screen settings SCREEN_WIDTH, SCREEN_HEIGHT = 300, 600 GRID_SIZE = 30 COLUMNS, ROWS = SCREEN_WIDTH // GRID_SIZE, SCREEN_HEIGHT // GRID_SIZE screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("Simple Tetris") # Colors BLACK = (0, 0, 0) WHITE = (255, 255, 255) COLORS = [ (0, 255, 255), (255, 0, 0), (0, 255, 0), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128) ] # Tetrimino shapes SHAPES = [ [[1, 1, 1, 1]], # I [[1, 1], [1, 1]], # O [[1, 0, 0], [1, 1, 1]], # L [[0, 0, 1], [1, 1, 1]], # J [[0, 1, 1], [1, 1, 0]], # S [[1, 1, 0], [0, 1, 1]], # Z [[0, 1, 0], [1, 1, 1]] # T ] class Piece: def __init__(self, shape, color): self.shape = shape self.color = color self.x = COLUMNS // 2 - len(shape[0]) // 2 self.y = 0 def rotate(self): self.shape = [list(row) for row in zip(*self.shape[::-1])] def create_grid(locked_positions={}): grid = [[BLACK for _ in range(COLUMNS)] for _ in range(ROWS)] for (x, y), color in locked_positions.items(): grid[y][x] = color return grid def valid_space(piece, grid): for y, row in enumerate(piece.shape): for x, cell in enumerate(row): if cell: if (piece.x + x < 0 or piece.x + x >= COLUMNS or piece.y + y >= ROWS or grid[piece.y + y][piece.x + x] != BLACK): return False return True def clear_rows(grid, locked): full_rows = 0 for y in range(len(grid) - 1, -1, -1): if BLACK not in grid[y]: full_rows += 1 del grid[y] grid.insert(0, [BLACK for _ in range(COLUMNS)]) for key in sorted(locked, key=lambda k: k[1])[::-1]: if key[1] < y: locked[(key[0], key[1] + 1)] = locked.pop(key) return full_rows def draw_grid(screen, grid): for y in range(ROWS): for x in range(COLUMNS): pygame.draw.rect(screen, grid[y][x], (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE), 0) pygame.draw.rect(screen, WHITE, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE), 1) def main(): clock = pygame.time.Clock() grid = create_grid() locked_positions = {} current_piece = Piece(random.choice(SHAPES), random.choice(COLORS)) fall_time = 0 run = True score = 0 while run: grid = create_grid(locked_positions) fall_speed = 0.3 fall_time += clock.get_rawtime() clock.tick() # Falling piece if fall_time / 1000 >= fall_speed: fall_time = 0 current_piece.y += 1 if not valid_space(current_piece, grid): current_piece.y -= 1 for y, row in enumerate(current_piece.shape): for x, cell in enumerate(row): if cell: locked_positions[(current_piece.x + x, current_piece.y + y)] = current_piece.color current_piece = Piece(random.choice(SHAPES), random.choice(COLORS)) score += clear_rows(grid, locked_positions) * 10 # Piece movement for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: current_piece.x -= 1 if not valid_space(current_piece, grid): current_piece.x += 1 elif event.key == pygame.K_RIGHT: current_piece.x += 1 if not valid_space(current_piece, grid): current_piece.x -= 1 elif event.key == pygame.K_DOWN: current_piece.y += 1 if not valid_space(current_piece, grid): current_piece.y -= 1 elif event.key == pygame.K_UP: current_piece.rotate() if not valid_space(current_piece, grid): for _ in range(3): current_piece.rotate() # Draw everything draw_grid(screen, grid) for y, row in enumerate(current_piece.shape): for x, cell in enumerate(row): if cell: pygame.draw.rect(screen, current_piece.color, ((current_piece.x + x) * GRID_SIZE, (current_piece.y + y) * GRID_SIZE, GRID_SIZE, GRID_SIZE), 0) pygame.display.update() # Check game over if any(y == 0 for (x, y) in locked_positions): run = False pygame.quit() print(f"Game Over! Your score: {score}") if __name__ == "__main__": main()`
### Debugging Challenges: Making It Better
The code worked almost perfectly, but there were a few minor bugs that provided a great opportunity to dive deeper and improve the game. Here are some debugging challenges to tackle:
`valid_space()` `clear_rows()`
Each of these challenges can serve as a fun way to enhance your debugging skills while making the game more polished and enjoyable!
### Wrapping Up
From one prompt to a playable Tetris game, this experience showed the power of code generation and inspiration. Watching Matthew Berman’s video provided the spark, but debugging and refining the code turned it into a learning experience. Give this code a try, solve the bugs, and enjoy the process of making this classic game your own. Happy coding!
