Этот код запускает Тетрис на Python. 
import pygame
import random

# Initialize Pygame
pygame.init()

# Colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
CYAN = (0, 255, 255)
YELLOW = (255, 255, 0)
MAGENTA = (255, 0, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
ORANGE = (255, 165, 0)

# Game dimensions
BLOCK_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SCREEN_WIDTH = BLOCK_SIZE * (GRID_WIDTH + 6)
SCREEN_HEIGHT = BLOCK_SIZE * GRID_HEIGHT

# Tetromino shapes
SHAPES = [
    [[1, 1, 1, 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, 0], [0, 1, 1]],
    [[0, 1, 1], [1, 1, 0]]
]

COLORS = [CYAN, YELLOW, MAGENTA, RED, GREEN, BLUE, ORANGE]


class Tetris:
    def __init__(self):
        self.game_state = 'menu'  # Possible states: 'menu', 'playing', 'paused', 'game_over'
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        self.hold_piece = None
        self.hold_used = False
        pygame.display.set_caption("Tetris")
        self.clock = pygame.time.Clock()
        self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
        self.piece_queue = [self.create_random_piece() for _ in range(3)]
        self.current_piece = self.get_next_piece()
        self.game_over = False
        self.score = 0

    def show_menu(self):
        menu = True
        while menu:
            self.screen.fill(BLACK)
            font = pygame.font.Font(None, 74)
            title_text = font.render("Тетрис", True, WHITE)
            self.screen.blit(title_text, (SCREEN_WIDTH // 2 - title_text.get_width() // 2, SCREEN_HEIGHT // 4))

            button_font = pygame.font.Font(None, 50)
            button_text = button_font.render("Начать игру", True, WHITE)
            button_rect = button_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))

            pygame.draw.rect(self.screen, WHITE, button_rect.inflate(20, 20), 2)
            self.screen.blit(button_text, button_rect)

            pygame.display.flip()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    menu = False
                    self.game_over = True
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if button_rect.collidepoint(event.pos):
                        menu = False
                        self.game_state = 'playing'

            self.clock.tick(60)

    def create_random_piece(self):
        shape = random.choice(SHAPES)
        color = random.choice(COLORS)
        return {
            'shape': shape,
            'color': color,
            'x': 0,
            'y': 0
        }

    def get_next_piece(self):
        next_piece = self.piece_queue.pop(0)
        next_piece['x'] = GRID_WIDTH // 2 - len(next_piece['shape'][0]) // 2
        next_piece['y'] = 0
        self.piece_queue.append(self.create_random_piece())
        return next_piece

    def valid_move(self, piece, x, y):
        for i, row in enumerate(piece['shape']):
            for j, cell in enumerate(row):
                if cell:
                    if (x + j < 0 or x + j >= GRID_WIDTH or
                            y + i >= GRID_HEIGHT or
                            self.grid[y + i][x + j]):
                        return False
        return True

    def place_piece(self, piece):
        for i, row in enumerate(piece['shape']):
            for j, cell in enumerate(row):
                if cell:
                    self.grid[piece['y'] + i][piece['x'] + j] = piece['color']

    def remove_complete_lines(self):
        lines_cleared = 0
        new_grid = []
        for row in self.grid:
            if not all(row):
                new_grid.append(row)
            else:
                lines_cleared += 1
        for _ in range(lines_cleared):
            new_grid.insert(0, [0 for _ in range(GRID_WIDTH)])
        self.grid = new_grid
        self.score += lines_cleared * 100

    def rotate_piece(self, piece):
        return {
            'shape': list(zip(*reversed(piece['shape']))),
            'color': piece['color'],
            'x': piece['x'],
            'y': piece['y']
        }

    def draw_next_pieces(self):
        font = pygame.font.Font(None, 36)
        next_text = font.render("Next:", True, WHITE)
        self.screen.blit(next_text, (GRID_WIDTH * BLOCK_SIZE + 10, 100))

        for index, piece in enumerate(self.piece_queue[:2]):
            for i, row in enumerate(piece['shape']):
                for j, cell in enumerate(row):
                    if cell:
                        pygame.draw.rect(
                            self.screen,
                            piece['color'],
                            (GRID_WIDTH * BLOCK_SIZE + 10 + j * BLOCK_SIZE,
                             130 + index * 100 + i * BLOCK_SIZE,
                             BLOCK_SIZE, BLOCK_SIZE)
                        )
                        pygame.draw.rect(
                            self.screen,
                            WHITE,
                            (GRID_WIDTH * BLOCK_SIZE + 10 + j * BLOCK_SIZE,
                             130 + index * 100 + i * BLOCK_SIZE,
                             BLOCK_SIZE, BLOCK_SIZE), 1
                        )

    def hold_piece_swap(self, current, hold):
        current['x'] = GRID_WIDTH // 2 - len(current['shape'][0]) // 2
        current['y'] = 0
        if hold is None:
            hold = current
            current = self.get_next_piece()
        else:
            hold, current = current, hold
            current['x'] = GRID_WIDTH // 2 - len(current['shape'][0]) // 2
            current['y'] = 0
        return current, hold

    def draw_grid(self):
        for y, row in enumerate(self.grid):
            for x, color in enumerate(row):
                if color:
                    pygame.draw.rect(self.screen, color, (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
                    pygame.draw.rect(self.screen, WHITE, (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)

    def draw_piece(self, piece):
        for i, row in enumerate(piece['shape']):
            for j, cell in enumerate(row):
                if cell:
                    pygame.draw.rect(self.screen, piece['color'],
                                     ((piece['x'] + j) * BLOCK_SIZE, (piece['y'] + i) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
                    pygame.draw.rect(self.screen, WHITE,
                                     ((piece['x'] + j) * BLOCK_SIZE, (piece['y'] + i) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)

    def draw_score(self):
        font = pygame.font.Font(None, 36)
        score_text = font.render(f"Количество очков: {self.score}", True, WHITE)
        self.screen.blit(score_text, (GRID_WIDTH * BLOCK_SIZE + 10, 10))

    def show_game_over(self):
        self.screen.fill(BLACK)
        font = pygame.font.Font(None, 74)
        game_over_text = font.render("Игра окончена", True, RED)
        self.screen.blit(
            game_over_text,
            (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2,
             SCREEN_HEIGHT // 2 - game_over_text.get_height() // 2)
        )
        pygame.display.flip()
        pygame.time.delay(1500)
        self.reset_game()
        self.game_state = 'menu'

    def reset_game(self):
        self.grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
        self.piece_queue = [self.create_random_piece() for _ in range(3)]
        self.current_piece = self.get_next_piece()
        self.score = 0
        self.total_lines_cleared = 0
        self.hold_piece = None
        self.hold_used = False

    def run(self):
        fall_time = 0
        normal_fall_speed = 0.5
        fast_fall_speed = 0.1428571428571429
        fall_speed = normal_fall_speed
        key_down_pressed = False
        down_key_timer = 0

        while not self.game_over:
            if self.game_state == 'menu':
                self.show_menu()
            elif self.game_state == 'playing':
                pass  # Game logic will go here
            elif self.game_state == 'paused':
                pass  # Paused logic will go here
            elif self.game_state == 'game_over':
                self.show_game_over()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.game_over = True
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        if self.valid_move(self.current_piece, self.current_piece['x'] - 1, self.current_piece['y']):
                            self.current_piece['x'] -= 1
                    if event.key == pygame.K_RIGHT:
                        if self.valid_move(self.current_piece, self.current_piece['x'] + 1, self.current_piece['y']):
                            self.current_piece['x'] += 1
                    if event.key == pygame.K_DOWN:
                        key_down_pressed = True
                        down_key_timer = 0  # Start timing
                        if self.valid_move(self.current_piece, self.current_piece['x'], self.current_piece['y'] + 1):
                            self.current_piece['y'] += 1
                    if event.key == pygame.K_UP:
                        rotated_piece = self.rotate_piece(self.current_piece)
                        if self.valid_move(rotated_piece, rotated_piece['x'], rotated_piece['y']):
                            self.current_piece = rotated_piece
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_DOWN:
                        key_down_pressed = False
                        down_key_timer = 0
                        fall_speed = normal_fall_speed

            if key_down_pressed:
                down_key_timer += self.clock.get_time()
                if down_key_timer >= 150:  # After 0.15 seconds
                    fall_speed = fast_fall_speed
            else:
                fall_speed = normal_fall_speed

            fall_time += self.clock.get_rawtime()
            self.clock.tick()

            if fall_time / 1000 > fall_speed:
                if self.valid_move(self.current_piece, self.current_piece['x'], self.current_piece['y'] + 1):
                    self.current_piece['y'] += 1
                else:
                    self.place_piece(self.current_piece)
                    self.remove_complete_lines()
                    self.current_piece = self.get_next_piece()
                    if not self.valid_move(self.current_piece, self.current_piece['x'], self.current_piece['y']):
                        self.game_state = 'game_over'
                fall_time = 0

            self.screen.fill(BLACK)
            self.draw_grid()
            self.draw_piece(self.current_piece)
            self.draw_score()
            pygame.display.flip()

        pygame.quit()


if __name__ == "__main__":
    game = Tetris()
    game.run()


Сделай
A. Отображение следующих 2 фигур в очереди (включая текущую) справа от игрового поля во время игрового процесса 
B. Отображение надписи "Количество очков" не выходящей за рамки игры.
C. Возможность положить фигуру в резерв, отобразив её в правом верхнем углу, и возможность вынуть и заменить ею текущую в руке. При этом она по-прежнему должна браться как новая, возникая в верхней части игрового поля, а также отключить возможность взять новую в резерв, если фигурка уже в нём есть. 
D. Адаптацию пунктов A и C для мобильных устройств, а также кнопки UP, DOWN, RIGHT, LEFT под них в том числе.
F. Кнопку паузы в правом нижнем углу. 
G. Ускорение игры на 1,005x за каждую линию, собранную за текущую сессию.