Загрузка данных


import pygame
import random

pygame.init()

CELL = 20
COLS, ROWS = 17, 17
WIDTH, HEIGHT = COLS * CELL, ROWS * CELL
FPS = 10

WHITE  = (255, 255, 255)
BLACK  = (30,  30,  30)
GREEN  = (29,  158, 117)
LGREE  = (93,  202, 165)
RED    = (216,  90,  48)
GRAY   = (50,   50,  50)

screen = pygame.display.set_mode((WIDTH, HEIGHT + 40))
pygame.display.set_caption("Змейка")
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 20)
big  = pygame.font.SysFont("Arial", 36, bold=True)


def place_food(snake):
    while True:
        pos = (random.randint(0, COLS - 1), random.randint(0, ROWS - 1))
        if pos not in snake:
            return pos


def draw(screen, snake, food, score, best):
    screen.fill(BLACK)

    # сетка
    for x in range(0, WIDTH, CELL):
        pygame.draw.line(screen, GRAY, (x, 0), (x, HEIGHT))
    for y in range(0, HEIGHT, CELL):
        pygame.draw.line(screen, GRAY, (0, y), (WIDTH, y))

    # еда
    fx, fy = food
    pygame.draw.circle(screen, RED,
                       (fx * CELL + CELL // 2, fy * CELL + CELL // 2), CELL // 2 - 2)

    # змейка
    for i, (sx, sy) in enumerate(snake):
        color = GREEN if i == 0 else LGREE
        rect = pygame.Rect(sx * CELL + 1, sy * CELL + 1, CELL - 2, CELL - 2)
        pygame.draw.rect(screen, color, rect, border_radius=4)

    # статус
    panel = pygame.Rect(0, HEIGHT, WIDTH, 40)
    pygame.draw.rect(screen, (20, 20, 20), panel)
    txt = font.render(f"Счёт: {score}   Рекорд: {best}", True, WHITE)
    screen.blit(txt, (10, HEIGHT + 10))


def game_over_screen(screen, score, best):
    overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
    overlay.fill((0, 0, 0, 160))
    screen.blit(overlay, (0, 0))

    t1 = big.render("Игра окончена!", True, WHITE)
    t2 = font.render(f"Счёт: {score}   Рекорд: {best}", True, (200, 200, 200))
    t3 = font.render("Нажми R для перезапуска или Q для выхода", True, (150, 150, 150))

    screen.blit(t1, (WIDTH // 2 - t1.get_width() // 2, HEIGHT // 2 - 60))
    screen.blit(t2, (WIDTH // 2 - t2.get_width() // 2, HEIGHT // 2))
    screen.blit(t3, (WIDTH // 2 - t3.get_width() // 2, HEIGHT // 2 + 40))
    pygame.display.flip()


def run():
    best = 0

    while True:
        snake = [(8, 8), (7, 8), (6, 8)]
        direction = (1, 0)
        next_dir  = (1, 0)
        food  = place_food(set(snake))
        score = 0
        speed = FPS
        alive = True

        while alive:
            clock.tick(speed)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    return
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP    and direction != (0,  1): next_dir = (0, -1)
                    if event.key == pygame.K_DOWN  and direction != (0, -1): next_dir = (0,  1)
                    if event.key == pygame.K_LEFT  and direction != (1,  0): next_dir = (-1, 0)
                    if event.key == pygame.K_RIGHT and direction != (-1, 0): next_dir = (1,  0)

            direction = next_dir
            head = (snake[0][0] + direction[0], snake[0][1] + direction[1])

            # столкновение со стеной или собой
            if not (0 <= head[0] < COLS and 0 <= head[1] < ROWS) or head in snake:
                alive = False
                break

            snake.insert(0, head)

            if head == food:
                score += 10
                food   = place_food(set(snake))
                speed  = min(25, FPS + score // 50)
            else:
                snake.pop()

            if score > best:
                best = score

            draw(screen, snake, food, score, best)
            pygame.display.flip()

        # экран окончания
        draw(screen, snake, food, score, best)
        game_over_screen(screen, score, best)

        waiting = True
        while waiting:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    return
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_r:
                        waiting = False
                    if event.key == pygame.K_q:
                        pygame.quit()
                        return


run()