NeoTetris
Made by neofenixlive
Execute
Go back.
import turtle import random import time COLS, ROWS = 10, 20 BLOCK_SIZE = 20 OFFSET_X = -100 OFFSET_Y = 200 FRAME_TIME = 1.0 / 30 COLORS = [ "#000000", "#FF8000", "#0000FF", "#00FF00", "#FF0000", "#FF6060", "#C0C0FF", "#FFFF00" ] SHAPES = [ [[1, 1, 1], [0, 1, 0]], # T [[0, 2, 2], [2, 2, 0]], # Z [[3, 3, 0], [0, 3, 3]], # S [[4, 0, 0], [4, 4, 4]], # L [[0, 0, 5], [5, 5, 5]], # J [[6, 6, 6, 6]], # I [[7, 7], [7, 7]] # O ] class Tetris: def __init__(self): self.grid = [[0 for _ in range(COLS)] for _ in range(ROWS)] self.score = 0 self.game_over = False self.current_piece = self.new_piece() self.next_piece = self.new_piece() self.px, self.py = 3, 0 def new_piece(self): shape = random.choice(SHAPES) color_id = max(max(row) for row in shape) return {'shape': shape, 'color': color_id} def check_collision(self, shape, off_x, off_y): for cy, row in enumerate(shape): for cx, cell in enumerate(row): if cell: if (cx + off_x < 0 or cx + off_x >= COLS or cy + off_y >= ROWS or self.grid[cy + off_y][cx + off_x]): return True return False def rotate(self): shape = self.current_piece['shape'] rotated = [list(row) for row in zip(*shape[::-1])] if not self.check_collision(rotated, self.px, self.py): self.current_piece['shape'] = rotated def move(self, dx): if not self.check_collision(self.current_piece['shape'], self.px + dx, self.py): self.px += dx def drop(self): if not self.check_collision(self.current_piece['shape'], self.px, self.py + 1): self.py += 1 return False else: self.lock_piece() return True def lock_piece(self): for cy, row in enumerate(self.current_piece['shape']): for cx, cell in enumerate(row): if cell: self.grid[cy + self.py][cx + self.px] = self.current_piece['color'] self.clear_lines() self.current_piece = self.next_piece self.next_piece = self.new_piece() self.px, self.py = 3, 0 if self.check_collision(self.current_piece['shape'], self.px, self.py): self.game_over = True def clear_lines(self): new_grid = [row for row in self.grid if any(x == 0 for x in row)] cleared = ROWS - len(new_grid) for _ in range(cleared): new_grid.insert(0, [0] * COLS) self.grid = new_grid self.score += cleared * 100 screen = turtle.Screen() screen.bgcolor("#202020") screen.tracer(0) pen = turtle.Turtle() pen.penup() pen.hideturtle() pen.speed(0) game = Tetris() def draw_block(x, y, color_idx): pen.goto(OFFSET_X + x * BLOCK_SIZE, OFFSET_Y - y * BLOCK_SIZE) pen.fillcolor(COLORS[color_idx]) pen.pencolor("black") pen.begin_fill() for _ in range(4): pen.forward(BLOCK_SIZE) pen.right(90) pen.end_fill() def draw_game(): pen.clear() for y, row in enumerate(game.grid): for x, color in enumerate(row): if color > 0: draw_block(x, y, color) else: pen.goto(OFFSET_X + x * BLOCK_SIZE, OFFSET_Y - y * BLOCK_SIZE) pen.pencolor("#2a2a2a") for _ in range(4): pen.forward(BLOCK_SIZE); pen.right(90) if not game.game_over: for y, row in enumerate(game.current_piece['shape']): for x, val in enumerate(row): if val: draw_block(x + game.px, y + game.py, game.current_piece['color']) pen.pencolor("white") pen.goto(OFFSET_X, OFFSET_Y) pen.setheading(0) pen.pendown() for _ in range(2): pen.forward(COLS * BLOCK_SIZE) pen.right(90) pen.forward(ROWS * BLOCK_SIZE) pen.right(90) pen.penup() pen.goto(110, 170) pen.color("white") pen.write(f"Score:\n{game.score}", font=("Arial", 16, "bold")) screen.update() screen.listen() screen.onkey(lambda: game.move(-1), "Left") screen.onkey(lambda: game.move(1), "Right") screen.onkey(game.rotate, "Up") screen.onkey(game.drop, "Down") last_time = time.time() fall_timer = 0 fall_speed = 0.5 while not game.game_over: start_frame = time.time() if not game.game_over: current_time = time.time() dt = current_time - last_time last_time = current_time fall_timer += dt if fall_timer > fall_speed: game.drop() fall_timer = 0 draw_game() else: draw_game() time.sleep(1) elapsed = time.time() - start_frame if elapsed < FRAME_TIME: time.sleep(FRAME_TIME - elapsed) pen.goto(0, 0) pen.write("GAME OVER", align="center", font=("Arial", 16, "bold"))