import tkinter as tk import random # Define Tetris shapes and their rotations SHAPES = [ [[1, 1, 1, 1]], [[1, 1], [1, 1]], [[0, 1, 0], [1, 1, 1]], [[1, 0, 0], [1, 1, 1]], [[0, 0, 1], [1, 1, 1]], [[1, 1, 0], [0, 1, 1]], [[0, 1, 1], [1, 1, 0]] ] COLORS = ["red", "blue", "green", "yellow", "purple", "orange", "cyan"] class Tetris: def __init__(self, root): self.root = root self.canvas = tk.Canvas(root, width=200, height=400, bg="black") self.canvas.pack() self.width, self.height = 10, 20 self.cell_size = 20 self.board = [[0] * self.width for _ in range(self.height)] self.current_piece = self.new_piece() self.next_piece = self.new_piece() self.x, self.y = 3, 0 self.score = 0 self.running = True self.speed = 500 self.root.bind("", lambda event: self.move_piece(-1, 0)) self.root.bind("", lambda event: self.move_piece(1, 0)) self.root.bind("", lambda event: self.move_piece(0, 1, add_score=True)) self.root.bind("", lambda event: self.rotate_piece()) self.update() def new_piece(self): shape = random.choice(SHAPES) color = random.choice(COLORS) return {'shape': shape, 'color': color} def draw_board(self): self.canvas.delete("all") for y, row in enumerate(self.board): for x, cell in enumerate(row): if cell: self.canvas.create_rectangle( x * self.cell_size, y * self.cell_size, (x + 1) * self.cell_size, (y + 1) * self.cell_size, fill=cell, outline="black") self.draw_piece() self.canvas.create_text(100, 10, text=f"Score: {self.score}", fill="white", font=("Arial", 12)) def draw_piece(self): shape, color = self.current_piece['shape'], self.current_piece['color'] for dy, row in enumerate(shape): for dx, cell in enumerate(row): if cell: self.canvas.create_rectangle( (self.x + dx) * self.cell_size, (self.y + dy) * self.cell_size, (self.x + dx + 1) * self.cell_size, (self.y + dy + 1) * self.cell_size, fill=color, outline="black") def move_piece(self, dx, dy, add_score=False): if not self.check_collision(self.x + dx, self.y + dy, self.current_piece['shape']): self.x += dx self.y += dy if add_score: self.score += 100 self.update() def rotate_piece(self): rotated = list(zip(*reversed(self.current_piece['shape']))) if not self.check_collision(self.x, self.y, rotated): self.current_piece['shape'] = rotated self.update() def check_collision(self, x, y, shape): for dy, row in enumerate(shape): for dx, cell in enumerate(row): if cell: if x + dx < 0 or x + dx >= self.width or y + dy >= self.height: return True if self.board[y + dy][x + dx]: return True return False def lock_piece(self): shape, color = self.current_piece['shape'], self.current_piece['color'] for dy, row in enumerate(shape): for dx, cell in enumerate(row): if cell: self.board[self.y + dy][self.x + dx] = color self.clear_lines() self.current_piece = self.next_piece self.next_piece = self.new_piece() self.x, self.y = 3, 0 if self.check_collision(self.x, self.y, self.current_piece['shape']): self.running = False def clear_lines(self): new_board = [row for row in self.board if any(cell == 0 for cell in row)] lines_cleared = self.height - len(new_board) self.score += lines_cleared * 100 self.board = [[0] * self.width for _ in range(lines_cleared)] + new_board def update(self): if not self.running: self.canvas.create_text(100, 200, text="GAME OVER", fill="white", font=("Arial", 20)) return self.draw_board() self.root.after(self.speed, self.step) def step(self): if self.check_collision(self.x, self.y + 1, self.current_piece['shape']): self.lock_piece() else: self.y += 1 self.update() if __name__ == "__main__": root = tk.Tk() root.title("Tetris") game = Tetris(root) root.mainloop()