import tkinter as tk
import random
from enum import Enum
from typing import List, Tuple

class Direction(Enum):
    """方向枚举"""
    UP = (0, -1)
    DOWN = (0, 1)
    LEFT = (-1, 0)
    RIGHT = (1, 0)

class SnakeGame:
    def __init__(self, root):
        self.root = root
        self.root.title("贪吃蛇游戏")
        
        # 游戏参数
        self.grid_size = 20
        self.grid_width = 30
        self.grid_height = 20
        self.cell_size = 25
        
        # 计算窗口大小
        canvas_width = self.grid_width * self.cell_size
        canvas_height = self.grid_height * self.cell_size
        self.hud_height = 50
        
        # 创建主框架
        main_frame = tk.Frame(root, bg="#333")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建游戏状态面板
        self.status_frame = tk.Frame(main_frame, bg="#2c3e50", height=self.hud_height)
        self.status_frame.pack(side=tk.TOP, fill=tk.X)
        self.status_frame.pack_propagate(False)
        
        # 分数显示
        self.score_var = tk.StringVar(value="得分: 0")
        self.score_label = tk.Label(
            self.status_frame,
            textvariable=self.score_var,
            font=("Microsoft YaHei", 16, "bold"),
            fg="white",
            bg="#2c3e50"
        )
        self.score_label.pack(side=tk.LEFT, padx=20, pady=10)
        
        # 最高分显示
        self.high_score_var = tk.StringVar(value="最高分: 0")
        self.high_score_label = tk.Label(
            self.status_frame,
            textvariable=self.high_score_var,
            font=("Microsoft YaHei", 16, "bold"),
            fg="#f39c12",
            bg="#2c3e50"
        )
        self.high_score_label.pack(side=tk.LEFT, padx=20, pady=10)
        
        # 游戏控制按钮
        button_frame = tk.Frame(self.status_frame, bg="#2c3e50")
        button_frame.pack(side=tk.RIGHT, padx=20)
        
        self.start_btn = tk.Button(
            button_frame,
            text="开始游戏",
            command=self.start_game,
            font=("Microsoft YaHei", 12),
            bg="#27ae60",
            fg="white",
            width=10
        )
        self.start_btn.pack(side=tk.LEFT, padx=5)
        
        self.pause_btn = tk.Button(
            button_frame,
            text="暂停",
            command=self.pause_game,
            font=("Microsoft YaHei", 12),
            bg="#e74c3c",
            fg="white",
            width=10,
            state=tk.DISABLED
        )
        self.pause_btn.pack(side=tk.LEFT, padx=5)
        
        self.restart_btn = tk.Button(
            button_frame,
            text="重新开始",
            command=self.restart_game,
            font=("Microsoft YaHei", 12),
            bg="#3498db",
            fg="white",
            width=10
        )
        self.restart_btn.pack(side=tk.LEFT, padx=5)
        
        # 创建游戏画布
        self.canvas = tk.Canvas(
            main_frame,
            width=canvas_width,
            height=canvas_height,
            bg="#1a1a1a",
            highlightthickness=0
        )
        self.canvas.pack()
        
        # 游戏状态
        self.score = 0
        self.high_score = 0
        self.game_running = False
        self.game_paused = False
        self.speed = 150  # 初始速度（毫秒）
        self.min_speed = 50  # 最快速度
        
        # 贪吃蛇
        self.snake: List[Tuple[int, int]] = []
        self.snake_colors = ["#27ae60", "#2ecc71", "#1abc9c"]  # 蛇身颜色渐变
        self.direction = Direction.RIGHT
        self.next_direction = Direction.RIGHT
        
        # 食物
        self.food_pos: Tuple[int, int] = None
        self.food_id = None
        
        # 绘制网格
        self.draw_grid()
        
        # 绑定按键事件
        self.root.bind("<KeyPress>", self.on_key_press)
        
        # 显示开始界面
        self.show_start_screen()
        
    def draw_grid(self):
        """绘制游戏网格"""
        for x in range(self.grid_width):
            for y in range(self.grid_height):
                x1 = x * self.cell_size
                y1 = y * self.cell_size
                x2 = x1 + self.cell_size
                y2 = y1 + self.cell_size
                
                # 交错绘制网格背景
                if (x + y) % 2 == 0:
                    color = "#2a2a2a"
                else:
                    color = "#222222"
                    
                self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline="", tags="grid")
        
    def show_start_screen(self):
        """显示开始界面"""
        self.canvas.delete("game_over")
        
        # 游戏标题
        self.canvas.create_text(
            self.grid_width * self.cell_size // 2,
            self.grid_height * self.cell_size // 2 - 60,
            text="贪吃蛇",
            font=("Microsoft YaHei", 40, "bold"),
            fill="#f39c12",
            tags="start_screen"
        )
        
        # 操作说明
        instructions = [
            "操作说明:",
            "↑ ↓ ← → 或 WASD: 控制方向",
            "空格: 暂停游戏",
            "P: 暂停/继续游戏"
        ]
        
        for i, line in enumerate(instructions):
            self.canvas.create_text(
                self.grid_width * self.cell_size // 2,
                self.grid_height * self.cell_size // 2 + i * 25,
                text=line,
                font=("Microsoft YaHei", 14),
                fill="white",
                tags="start_screen"
            )
        
    def start_game(self):
        """开始游戏"""
        if not self.game_running:
            self.canvas.delete("start_screen")
            self.init_game()
            self.game_running = True
            self.game_paused = False
            self.start_btn.config(state=tk.DISABLED)
            self.pause_btn.config(state=tk.NORMAL, text="暂停", bg="#e74c3c")
            self.game_loop()
            
    def init_game(self):
        """初始化游戏"""
        # 重置状态
        self.score = 0
        self.speed = 150
        self.score_var.set(f"得分: {self.score}")
        
        # 初始化蛇
        center_x = self.grid_width // 2
        center_y = self.grid_height // 2
        self.snake = [(center_x, center_y), (center_x-1, center_y), (center_x-2, center_y)]
        self.direction = Direction.RIGHT
        self.next_direction = Direction.RIGHT
        
        # 生成食物
        self.generate_food()
        
        # 绘制初始状态
        self.draw_snake()
        self.draw_food()
        
    def pause_game(self):
        """暂停/继续游戏"""
        if self.game_running:
            self.game_paused = not self.game_paused
            if self.game_paused:
                self.pause_btn.config(text="继续", bg="#27ae60")
            else:
                self.pause_btn.config(text="暂停", bg="#e74c3c")
                self.game_loop()
                
    def restart_game(self):
        """重新开始游戏"""
        self.game_running = False
        self.game_paused = False
        self.canvas.delete("all")
        self.draw_grid()
        self.show_start_screen()
        self.start_btn.config(state=tk.NORMAL)
        self.pause_btn.config(state=tk.DISABLED, text="暂停", bg="#e74c3c")
        
    def generate_food(self):
        """生成食物"""
        # 获取所有空闲位置
        snake_positions = set(self.snake)
        all_positions = {(x, y) for x in range(self.grid_width) for y in range(self.grid_height)}
        free_positions = all_positions - snake_positions
        
        if free_positions:
            self.food_pos = random.choice(list(free_positions))
        else:
            # 没有位置了，游戏胜利
            self.game_win()
            return
            
    def draw_food(self):
        """绘制食物"""
        if self.food_id:
            self.canvas.delete(self.food_id)
            
        if self.food_pos:
            x, y = self.food_pos
            x1 = x * self.cell_size + 2
            y1 = y * self.cell_size + 2
            x2 = (x + 1) * self.cell_size - 2
            y2 = (y + 1) * self.cell_size - 2
            
            # 绘制一个红色的苹果
            self.food_id = self.canvas.create_oval(
                x1, y1, x2, y2,
                fill="#e74c3c",
                outline="#c0392b",
                width=2,
                tags="food"
            )
            
            # 绘制苹果梗
            stem_x = (x1 + x2) / 2
            self.canvas.create_line(
                stem_x, y1 - 3,
                stem_x, y1 + 3,
                fill="#8b4513",
                width=2,
                tags="food"
            )
            
    def draw_snake(self):
        """绘制贪吃蛇"""
        # 删除旧的蛇
        self.canvas.delete("snake")
        
        # 绘制蛇身
        for i, (x, y) in enumerate(self.snake):
            x1 = x * self.cell_size
            y1 = y * self.cell_size
            x2 = x1 + self.cell_size
            y2 = y1 + self.cell_size
            
            # 头部和身体使用不同颜色
            if i == 0:  # 蛇头
                color = "#f39c12"  # 橙色头部
                # 绘制眼睛
                eye_size = 3
                left_eye_x = x1 + 6
                right_eye_x = x2 - 6
                eye_y = y1 + 6
                
                self.canvas.create_oval(
                    x1, y1, x2, y2,
                    fill=color,
                    outline="#d35400",
                    width=2,
                    tags="snake"
                )
                
                # 根据方向绘制眼睛
                if self.direction == Direction.RIGHT:
                    self.canvas.create_oval(
                        x2 - 8, eye_y - eye_size, x2 - 4, eye_y + eye_size,
                        fill="black", tags="snake"
                    )
                elif self.direction == Direction.LEFT:
                    self.canvas.create_oval(
                        x1 + 4, eye_y - eye_size, x1 + 8, eye_y + eye_size,
                        fill="black", tags="snake"
                    )
                elif self.direction == Direction.UP:
                    self.canvas.create_oval(
                        left_eye_x - eye_size, y1 + 4, left_eye_x + eye_size, y1 + 8,
                        fill="black", tags="snake"
                    )
                else:  # DOWN
                    self.canvas.create_oval(
                        left_eye_x - eye_size, y2 - 8, left_eye_x + eye_size, y2 - 4,
                        fill="black", tags="snake"
                    )
                    
            else:  # 蛇身
                # 颜色渐变
                color_idx = min(i, len(self.snake_colors) - 1)
                color = self.snake_colors[color_idx]
                
                self.canvas.create_oval(
                    x1 + 2, y1 + 2, x2 - 2, y2 - 2,
                    fill=color,
                    outline="#27ae60",
                    width=1,
                    tags="snake"
                )
                
    def move_snake(self):
        """移动贪吃蛇"""
        if not self.game_running or self.game_paused:
            return False
            
        # 更新方向
        self.direction = self.next_direction
        
        # 获取蛇头位置
        head_x, head_y = self.snake[0]
        dx, dy = self.direction.value
        
        # 计算新的头部位置
        new_x = (head_x + dx) % self.grid_width
        new_y = (head_y + dy) % self.grid_height
        
        # 检查是否撞到自己
        if (new_x, new_y) in self.snake[1:]:
            self.game_over()
            return False
            
        # 移动蛇
        new_head = (new_x, new_y)
        self.snake.insert(0, new_head)
        
        # 检查是否吃到食物
        if new_head == self.food_pos:
            self.score += 10
            self.score_var.set(f"得分: {self.score}")
            
            # 更新最高分
            if self.score > self.high_score:
                self.high_score = self.score
                self.high_score_var.set(f"最高分: {self.high_score}")
                
            # 加速游戏
            if self.speed > self.min_speed:
                self.speed -= 2
                
            # 生成新食物
            self.generate_food()
            self.draw_food()
        else:
            # 没吃到食物，移除尾部
            self.snake.pop()
            
        # 重新绘制蛇
        self.draw_snake()
        
        return True
        
    def game_loop(self):
        """游戏主循环"""
        if self.game_running and not self.game_paused:
            if self.move_snake():
                # 继续游戏循环
                self.root.after(self.speed, self.game_loop)
                
    def on_key_press(self, event):
        """处理按键事件"""
        if not self.game_running or self.game_paused:
            return
            
        key = event.keysym
        
        # 方向控制
        if key in ("Up", "w", "W") and self.direction != Direction.DOWN:
            self.next_direction = Direction.UP
        elif key in ("Down", "s", "S") and self.direction != Direction.UP:
            self.next_direction = Direction.DOWN
        elif key in ("Left", "a", "A") and self.direction != Direction.RIGHT:
            self.next_direction = Direction.LEFT
        elif key in ("Right", "d", "D") and self.direction != Direction.LEFT:
            self.next_direction = Direction.RIGHT
        elif key == "space":
            self.pause_game()
        elif key in ("p", "P"):
            self.pause_game()
            
    def game_over(self):
        """游戏结束"""
        self.game_running = False
        self.canvas.create_text(
            self.grid_width * self.cell_size // 2,
            self.grid_height * self.cell_size // 2 - 30,
            text="游戏结束!",
            font=("Microsoft YaHei", 36, "bold"),
            fill="#e74c3c",
            tags="game_over"
        )
        
        self.canvas.create_text(
            self.grid_width * self.cell_size // 2,
            self.grid_height * self.cell_size // 2 + 20,
            text=f"最终得分: {self.score}",
            font=("Microsoft YaHei", 24),
            fill="white",
            tags="game_over"
        )
        
        self.start_btn.config(state=tk.NORMAL)
        self.pause_btn.config(state=tk.DISABLED)
        
    def game_win(self):
        """游戏胜利（填满整个屏幕）"""
        self.game_running = False
        self.canvas.create_text(
            self.grid_width * self.cell_size // 2,
            self.grid_height * self.cell_size // 2,
            text="恭喜通关!",
            font=("Microsoft YaHei", 36, "bold"),
            fill="#f39c12",
            tags="game_over"
        )
        
        self.start_btn.config(state=tk.NORMAL)
        self.pause_btn.config(state=tk.DISABLED)

def main():
    root = tk.Tk()
    
    # 设置窗口居中
    window_width = 800
    window_height = 600
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2
    root.geometry(f"{window_width}x{window_height}+{x}+{y}")
    
    root.resizable(False, False)
    game = SnakeGame(root)
    root.mainloop()

if __name__ == "__main__":
    main()