import tkinter as tk
import random

# === НАСТРОЙКИ ===
WIDTH = 600
HEIGHT = 600
CELL = 20                      # размер одной клетки
COLS = WIDTH // CELL
ROWS = HEIGHT // CELL
SPEED = 100                    # мс между шагами (меньше = быстрее)

# === ЦВЕТА ===
BG_COLOR = "#1e1e1e"
SNAKE_COLOR = "#4ade80"
HEAD_COLOR = "#22c55e"
FOOD_COLOR = "#ef4444"
TEXT_COLOR = "#ffffff"


class SnakeGame:
    def __init__(self, root):
        self.root = root
        self.root.title("Змейка 🐍")
        self.root.resizable(False, False)

        self.canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg=BG_COLOR)
        self.canvas.pack()

        self.score_label = tk.Label(
            root, text="Счёт: 0", font=("Arial", 14),
            bg=BG_COLOR, fg=TEXT_COLOR
        )
        self.score_label.pack(fill="x")

        self.reset_game()
        self.root.bind("<Key>", self.on_key)
        self.root.bind("<Return>", lambda e: self.reset_game() if self.game_over else None)
        self.root.bind("<r>", lambda e: self.reset_game())

    def reset_game(self):
        self.snake = [(COLS // 2, ROWS // 2)]
        self.direction = (1, 0)      # старт — вправо
        self.next_direction = (1, 0)
        self.food = self.spawn_food()
        self.score = 0
        self.game_over = False
        self.score_label.config(text="Счёт: 0")
        self.update()
        if not self.game_over:
            self.root.after(SPEED, self.game_loop)

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

    def on_key(self, event):
        key = event.keysym
        new_dir = None
        if key in ("Up", "w", "W"):
            new_dir = (0, -1)
        elif key in ("Down", "s", "S"):
            new_dir = (0, 1)
        elif key in ("Left", "a", "A"):
            new_dir = (-1, 0)
        elif key in ("Right", "d", "D"):
            new_dir = (1, 0)

        if new_dir:
            # запрет разворота на 180°
            if (new_dir[0] * -1, new_dir[1] * -1) != self.direction:
                self.next_direction = new_dir

    def game_loop(self):
        if self.game_over:
            return

        self.direction = self.next_direction
        head_x, head_y = self.snake[0]
        dx, dy = self.direction
        new_head = (head_x + dx, head_y + dy)

        # столкновение со стеной
        if not (0 <= new_head[0] < COLS and 0 <= new_head[1] < ROWS):
            return self.end_game()

        # столкновение с собой
        if new_head in self.snake:
            return self.end_game()

        self.snake.insert(0, new_head)

        # съели еду?
        if new_head == self.food:
            self.score += 1
            self.score_label.config(text=f"Счёт: {self.score}")
            self.food = self.spawn_food()
        else:
            self.snake.pop()

        self.update()
        self.root.after(SPEED, self.game_loop)

    def end_game(self):
        self.game_over = True
        self.update()
        self.canvas.create_text(
            WIDTH // 2, HEIGHT // 2,
            text=f"ИГРА ОКОНЧЕНА\nСчёт: {self.score}\n\nR — заново",
            fill=TEXT_COLOR, font=("Arial", 24, "bold"),
            justify="center"
        )

    def update(self):
        self.canvas.delete("all")

        # еда
        fx, fy = self.food
        self.canvas.create_oval(
            fx * CELL + 2, fy * CELL + 2,
            (fx + 1) * CELL - 2, (fy + 1) * CELL - 2,
            fill=FOOD_COLOR, outline=""
        )

        # змейка
        for i, (x, y) in enumerate(self.snake):
            color = HEAD_COLOR if i == 0 else SNAKE_COLOR
            self.canvas.create_rectangle(
                x * CELL + 1, y * CELL + 1,
                (x + 1) * CELL - 1, (y + 1) * CELL - 1,
                fill=color, outline=""
            )


if __name__ == "__main__":
    root = tk.Tk()
    game = SnakeGame(root)
    root.mainloop()

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: