import tkinter as tk
import random
from tkinter import messagebox

class SnakeGame:
    def __init__(self):
        # 游戏窗口设置
        self.window = tk.Tk()
        self.window.title("贪吃蛇游戏")
        self.window.resizable(False, False)
        
        # 游戏参数
        self.grid_size = 20  # 网格大小
        self.grid_width = 30  # 宽度格子数
        self.grid_height = 20  # 高度格子数
        self.cell_size = 25  # 每个格子像素大小
        
        # 计算窗口尺寸
        self.canvas_width = self.grid_width * self.cell_size
        self.canvas_height = self.grid_height * self.cell_size
        
        # 创建画布
        self.canvas = tk.Canvas(self.window, width=self.canvas_width, 
                               height=self.canvas_height, bg='black')
        self.canvas.pack()
        
        # 控制面板
        self.control_frame = tk.Frame(self.window)
        self.control_frame.pack(pady=5)
        
        self.score_label = tk.Label(self.control_frame, text="分数: 0", 
                                   font=('Arial', 14), fg='red')
        self.score_label.pack(side=tk.LEFT, padx=20)
        
        self.restart_button = tk.Button(self.control_frame, text="重新开始", 
                                       command=self.restart_game, font=('Arial', 12))
        self.restart_button.pack(side=tk.LEFT, padx=20)
        
        # 游戏状态
        self.snake = [(self.grid_width // 2, self.grid_height // 2)]
        self.direction = 'Right'
        self.next_direction = 'Right'
        self.food = self.generate_food()
        self.score = 0
        self.game_over_flag = False
        
        # 绑定键盘事件
        self.window.bind('<Key>', self.on_key_press)
        self.window.bind('<KeyPress-Up>', lambda e: self.on_key_press(e, 'Up'))
        self.window.bind('<KeyPress-Down>', lambda e: self.on_key_press(e, 'Down'))
        self.window.bind('<KeyPress-Left>', lambda e: self.on_key_press(e, 'Left'))
        self.window.bind('<KeyPress-Right>', lambda e: self.on_key_press(e, 'Right'))
        
        # 开始游戏循环
        self.update()
        self.window.mainloop()
    
    def generate_food(self):
        """生成食物，确保不在蛇身上"""
        while True:
            food = (random.randint(0, self.grid_width - 1),
                   random.randint(0, self.grid_height - 1))
            if food not in self.snake:
                return food
    
    def on_key_press(self, event, key=None):
        """处理键盘输入"""
        if key:
            direction_map = {
                'Up': 'Up',
                'Down': 'Down', 
                'Left': 'Left',
                'Right': 'Right'
            }
            key = direction_map.get(key, key)
        else:
            key = event.keysym
        
        # 防止蛇直接反向移动
        if key == 'Up' and self.direction != 'Down':
            self.next_direction = 'Up'
        elif key == 'Down' and self.direction != 'Up':
            self.next_direction = 'Down'
        elif key == 'Left' and self.direction != 'Right':
            self.next_direction = 'Left'
        elif key == 'Right' and self.direction != 'Left':
            self.next_direction = 'Right'
    
    def move_snake(self):
        """移动蛇"""
        head = self.snake[0]
        new_head = list(head)
        
        if self.next_direction == 'Up':
            new_head[1] -= 1
        elif self.next_direction == 'Down':
            new_head[1] += 1
        elif self.next_direction == 'Left':
            new_head[0] -= 1
        elif self.next_direction == 'Right':
            new_head[0] += 1
        
        new_head = tuple(new_head)
        self.direction = self.next_direction
        
        # 检查是否吃到食物
        if new_head == self.food:
            # 吃到食物，增加分数，蛇变长
            self.snake.insert(0, new_head)
            self.food = self.generate_food()
            self.score += 10
            self.score_label.config(text=f"分数: {self.score}")
        else:
            # 没吃到食物，移动蛇
            self.snake.insert(0, new_head)
            self.snake.pop()
        
        # 检查游戏结束条件
        if (new_head[0] < 0 or new_head[0] >= self.grid_width or
            new_head[1] < 0 or new_head[1] >= self.grid_height or
            new_head in self.snake[1:]):
            self.game_over()
            return False
        return True
    
    def draw(self):
        """绘制游戏界面"""
        self.canvas.delete('all')
        
        # 绘制网格线
        for i in range(self.grid_width + 1):
            self.canvas.create_line(i * self.cell_size, 0, 
                                   i * self.cell_size, self.canvas_height,
                                   fill='gray20')
        for i in range(self.grid_height + 1):
            self.canvas.create_line(0, i * self.cell_size,
                                   self.canvas_width, i * self.cell_size,
                                   fill='gray20')
        
        # 绘制蛇
        for i, segment in enumerate(self.snake):
            x = segment[0] * self.cell_size
            y = segment[1] * self.cell_size
            if i == 0:  # 蛇头
                self.canvas.create_rectangle(x, y, x + self.cell_size, 
                                            y + self.cell_size, fill='lightgreen',
                                            outline='darkgreen', width=2)
            else:  # 蛇身
                self.canvas.create_rectangle(x, y, x + self.cell_size,
                                            y + self.cell_size, fill='green',
                                            outline='darkgreen')
        
        # 绘制食物
        fx = self.food[0] * self.cell_size
        fy = self.food[1] * self.cell_size
        self.canvas.create_oval(fx + 2, fy + 2, fx + self.cell_size - 2,
                               fy + self.cell_size - 2, fill='red')
    
    def game_over(self):
        """游戏结束"""
        self.game_over_flag = True
        response = messagebox.askyesno("游戏结束", 
                                       f"你的得分: {self.score}\n是否重新开始？")
        if response:
            self.restart_game()
    
    def restart_game(self):
        """重新开始游戏"""
        self.snake = [(self.grid_width // 2, self.grid_height // 2)]
        self.direction = 'Right'
        self.next_direction = 'Right'
        self.score = 0
        self.game_over_flag = False
        self.score_label.config(text="分数: 0")
        self.food = self.generate_food()
    
    def update(self):
        """游戏主循环"""
        if not self.game_over_flag:
            if self.move_snake():
                self.draw()
            self.window.after(100, self.update)  # 每100毫秒更新一次

if __name__ == "__main__":
    game = SnakeGame()