import tkinter as tk
import random
import math

CELL = 20
COLS = 30
ROWS = 28
WIDTH = COLS * CELL
HEIGHT = ROWS * CELL

class SnakeGame:
    def __init__(self, root):
        self.root = root
        self.root.title("016. 贪吃蛇")
        self.root.resizable(False, False)

        self.canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="#1a1a2e")
        self.canvas.pack()

        # 蛇身（坐标列表，头在前面）
        self.snake = [(ROWS // 2, COLS // 2)]
        self.direction = (0, 1)  # 初始向右
        self.next_direction = (0, 1)
        self.food = None
        self.score = 0
        self.high_score = 0
        self.running = True
        self.paused = False

        # UI 文字
        self.score_text = self.canvas.create_text(
            10, 10, anchor="nw",
            text="", fill="white", font=("Consolas", 12, "bold")
        )
        self.hint_text = self.canvas.create_text(
            WIDTH // 2, 30, anchor="n",
            text="方向键控制  |  空格暂停  |  P 重新开始",
            fill="#888888", font=("Microsoft YaHei", 10)
        )

        self.spawn_food()
        self.update_ui()
        self.bind_keys()
        self.game_loop()

    def bind_keys(self):
        self.root.bind("<Up>", lambda e: self.set_dir((-1, 0)))
        self.root.bind("<Down>", lambda e: self.set_dir((1, 0)))
        self.root.bind("<Left>", lambda e: self.set_dir((0, -1)))
        self.root.bind("<Right>", lambda e: self.set_dir((0, 1)))
        self.root.bind("<space>", lambda e: self.toggle_pause())
        self.root.bind("<p>", lambda e: self.restart())
        self.root.bind("<Escape>", lambda e: self.root.quit())

    def set_dir(self, d):
        # 禁止直接反向
        if d[0] + self.direction[0] != 0 or d[1] + self.direction[1] != 0:
            self.next_direction = d

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

    def draw(self):
        self.canvas.delete("snake", "food")

        # 画蛇（头部大一点，身体渐变）
        for i, (r, c) in enumerate(self.snake):
            x1 = c * CELL + 1
            y1 = r * CELL + 1
            x2 = x1 + CELL - 2
            y2 = y1 + CELL - 2

            if i == 0:
                # 蛇头（亮绿色，稍大）
                self.canvas.create_oval(
                    x1 - 1, y1 - 1, x2 + 1, y2 + 1,
                    fill="#00ff88", outline="#00cc66", width=1, tags="snake"
                )
                # 眼睛
                eye_offset = 3
                if self.direction == (0, 1):  # 右
                    self.canvas.create_oval(x2 - 6, y1 + 4, x2 - 2, y1 + 8, fill="white", tags="snake")
                    self.canvas.create_oval(x2 - 5, y1 + 5, x2 - 3, y1 + 7, fill="black", tags="snake")
                elif self.direction == (0, -1):  # 左
                    self.canvas.create_oval(x1 + 2, y1 + 4, x1 + 6, y1 + 8, fill="white", tags="snake")
                    self.canvas.create_oval(x1 + 3, y1 + 5, x1 + 5, y1 + 7, fill="black", tags="snake")
                elif self.direction == (-1, 0):  # 上
                    self.canvas.create_oval(x1 + 4, y1 + 2, x1 + 8, y1 + 6, fill="white", tags="snake")
                    self.canvas.create_oval(x1 + 5, y1 + 3, x1 + 7, y1 + 5, fill="black", tags="snake")
                else:  # 下
                    self.canvas.create_oval(x1 + 4, y2 - 6, x1 + 8, y2 - 2, fill="white", tags="snake")
                    self.canvas.create_oval(x1 + 5, y2 - 5, x1 + 7, y2 - 3, fill="black", tags="snake")
            else:
                # 蛇身（渐变绿色）
                ratio = i / max(len(self.snake) - 1, 1)
                g = int(200 - ratio * 80)
                color = f"#00{g:02x}66"
                self.canvas.create_oval(
                    x1, y1, x2, y2,
                    fill=color, outline="#004422", width=1, tags="snake"
                )

        # 画食物（红色，带光晕）
        fr, fc = self.food
        fx1 = fc * CELL + 2
        fy1 = fr * CELL + 2
        fx2 = fx1 + CELL - 4
        fy2 = fy1 + CELL - 4

        # 光晕
        self.canvas.create_oval(
            fx1 - 2, fy1 - 2, fx2 + 2, fy2 + 2,
            fill="#ff6666", outline="", tags="food"
        )
        # 主体
        self.canvas.create_oval(
            fx1, fy1, fx2, fy2,
            fill="#ff3333", outline="#cc0000", width=1, tags="food"
        )

    def update_ui(self):
        if self.paused:
            text = f"⏸ 暂停中  |  得分: {self.score}  |  最高: {self.high_score}"
        else:
            text = f"得分: {self.score}  |  最高: {self.high_score}"
        self.canvas.itemconfig(self.score_text, text=text)

    def toggle_pause(self):
        if not self.running:
            return
        self.paused = not self.paused
        self.update_ui()

    def game_loop(self):
        if not self.running:
            return

        if not self.paused:
            self.direction = self.next_direction
            head = self.snake[0]
            new_head = (head[0] + self.direction[0], head[1] + self.direction[1])

            # 撞墙
            if (new_head[0] < 0 or new_head[0] >= ROWS or
                new_head[1] < 0 or new_head[1] >= COLS):
                self.game_over()
                return

            # 撞自己
            if new_head in self.snake:
                self.game_over()
                return

            self.snake.insert(0, new_head)

            # 吃食物
            if new_head == self.food:
                self.score += 10
                self.high_score = max(self.high_score, self.score)
                self.spawn_food()
            else:
                self.snake.pop()

            self.draw()
            self.update_ui()

        speed = max(60, 130 - len(self.snake) * 2)
        self.root.after(speed, self.game_loop)

    def game_over(self):
        self.running = False
        # 半透明遮罩效果
        self.canvas.create_rectangle(
            0, 0, WIDTH, HEIGHT,
            fill="#000000", stipple="gray50", tags="overlay"
        )
        self.canvas.create_text(
            WIDTH // 2, HEIGHT // 2 - 30,
            text="游戏结束！",
            fill="#ff4444", font=("Microsoft YaHei", 28, "bold"),
            tags="overlay"
        )
        self.canvas.create_text(
            WIDTH // 2, HEIGHT // 2 + 20,
            text=f"最终得分: {self.score}",
            fill="white", font=("Consolas", 16),
            tags="overlay"
        )
        self.canvas.create_text(
            WIDTH // 2, HEIGHT // 2 + 60,
            text="按 P 重新开始  |  ESC 退出",
            fill="#aaaaaa", font=("Microsoft YaHei", 11),
            tags="overlay"
        )

    def restart(self):
        self.canvas.delete("all")
        self.snake = [(ROWS // 2, COLS // 2)]
        self.direction = (0, 1)
        self.next_direction = (0, 1)
        self.score = 0
        self.running = True
        self.paused = False

        self.score_text = self.canvas.create_text(
            10, 10, anchor="nw",
            text="", fill="white", font=("Consolas", 12, "bold")
        )
        self.hint_text = self.canvas.create_text(
            WIDTH // 2, 30, anchor="n",
            text="方向键控制  |  空格暂停  |  P 重新开始",
            fill="#888888", font=("Microsoft YaHei", 10)
        )

        self.spawn_food()
        self.update_ui()
        self.game_loop()


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