import tkinter as tk
import random
import time


class SnakeGame:
    def __init__(self, master):
        self.master = master
        self.master.title("贪吃蛇游戏")
        self.master.resizable(False, False)

        # 游戏设置
        self.GRID_SIZE = 20  # 网格大小
        self.CANVAS_WIDTH = 600  # 画布宽度
        self.CANVAS_HEIGHT = 400  # 画布高度
        self.SPEED = 150  # 游戏速度（毫秒）

        # 计算网格数量
        self.GRID_WIDTH = self.CANVAS_WIDTH // self.GRID_SIZE
        self.GRID_HEIGHT = self.CANVAS_HEIGHT // self.GRID_SIZE

        # 创建画布
        self.canvas = tk.Canvas(
            master,
            width=self.CANVAS_WIDTH,
            height=self.CANVAS_HEIGHT,
            bg='black'
        )
        self.canvas.pack()

        # 创建分数标签
        self.score_label = tk.Label(master, text="分数: 0", font=('Arial', 14))
        self.score_label.pack()

        # 创建游戏说明
        self.info_label = tk.Label(
            master,
            text="使用方向键控制蛇的移动\n按R键重新开始游戏",
            font=('Arial', 10)
        )
        self.info_label.pack()

        # 初始化游戏状态
        self.init_game()

        # 绑定键盘事件
        self.master.bind('<KeyPress>', self.on_key_press)
        self.master.focus_set()

        # 开始游戏循环
        self.game_loop()

    def init_game(self):
        """初始化游戏状态"""
        # 蛇的身体（列表，每个元素是(x, y)坐标）
        self.snake = [(5, 5), (4, 5), (3, 5)]
        self.direction = 'Right'  # 初始方向
        self.next_direction = 'Right'  # 下一帧的方向

        # 食物位置
        self.food = self.generate_food()

        # 分数
        self.score = 0

        # 游戏是否结束
        self.game_over = False

    def generate_food(self):
        """生成食物位置"""
        while True:
            food_x = random.randint(0, self.GRID_WIDTH - 1)
            food_y = random.randint(0, self.GRID_HEIGHT - 1)
            food_pos = (food_x, food_y)

            # 确保食物不在蛇身上
            if food_pos not in self.snake:
                return food_pos

    def on_key_press(self, event):
        """处理键盘输入"""
        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'
        elif key.lower() == 'r':  # 按R键重新开始
            self.restart_game()

    def move_snake(self):
        """移动蛇"""
        if self.game_over:
            return

        # 更新方向
        self.direction = self.next_direction

        # 获取蛇头位置
        head_x, head_y = self.snake[0]

        # 根据方向计算新头部位置
        if self.direction == 'Up':
            new_head = (head_x, head_y - 1)
        elif self.direction == 'Down':
            new_head = (head_x, head_y + 1)
        elif self.direction == 'Left':
            new_head = (head_x - 1, head_y)
        elif self.direction == 'Right':
            new_head = (head_x + 1, head_y)

        new_head_x, new_head_y = new_head

        # 检查碰撞边界
        if (new_head_x < 0 or new_head_x >= self.GRID_WIDTH or
                new_head_y < 0 or new_head_y >= self.GRID_HEIGHT):
            self.game_over = True
            return

        # 检查碰撞自身
        if new_head in self.snake:
            self.game_over = True
            return

        # 添加新头部
        self.snake.insert(0, new_head)

        # 检查是否吃到食物
        if new_head == self.food:
            # 吃到食物，增加分数
            self.score += 10
            self.score_label.config(text=f"分数: {self.score}")
            # 生成新食物
            self.food = self.generate_food()
        else:
            # 没有吃到食物，移除尾部
            self.snake.pop()

    def draw(self):
        """绘制游戏画面"""
        # 清空画布
        self.canvas.delete('all')

        if self.game_over:
            # 绘制游戏结束文本
            self.canvas.create_text(
                self.CANVAS_WIDTH // 2,
                self.CANVAS_HEIGHT // 2,
                text="游戏结束!\n按R键重新开始",
                fill='white',
                font=('Arial', 24)
            )
            return

        # 绘制蛇
        for i, (x, y) in enumerate(self.snake):
            color = 'green' if i == 0 else 'light green'  # 蛇头用深绿色，身体用浅绿色
            self.canvas.create_rectangle(
                x * self.GRID_SIZE,
                y * self.GRID_SIZE,
                (x + 1) * self.GRID_SIZE,
                (y + 1) * self.GRID_SIZE,
                fill=color,
                outline='white'
            )

        # 绘制食物
        food_x, food_y = self.food
        self.canvas.create_oval(
            food_x * self.GRID_SIZE,
            food_y * self.GRID_SIZE,
            (food_x + 1) * self.GRID_SIZE,
            (food_y + 1) * self.GRID_SIZE,
            fill='red',
            outline='white'
        )

    def game_loop(self):
        """游戏主循环"""
        self.move_snake()
        self.draw()

        # 如果游戏未结束，继续循环
        if not self.game_over:
            self.master.after(self.SPEED, self.game_loop)

    def restart_game(self):
        """重新开始游戏"""
        self.init_game()
        self.game_loop()


def main():
    root = tk.Tk()
    game = SnakeGame(root)
    root.mainloop()


if __name__ == "__main__":
    main()
