"""
贪吃蛇游戏 - 经典原版复刻
开发者: 卢思成
学校: 东台市第一小学
班级: 六（10）班
学号: 19号
版本: 1.0
"""

import pygame
import random
import sys
import time

# 初始化pygame
pygame.init()

# 游戏常量设置
屏幕宽度 = 600
屏幕高度 = 600
网格大小 = 20
网格宽度 = 屏幕宽度 // 网格大小
网格高度 = 屏幕高度 // 网格大小
游戏帧率 = 10  # 原版贪吃蛇速度

# 颜色定义 (使用原版风格颜色)
背景颜色 = (15, 56, 15)        # 深绿色背景
网格颜色 = (30, 80, 30)        # 网格线颜色
蛇头颜色 = (0, 255, 0)         # 蛇头 - 亮绿色
蛇身颜色 = (0, 200, 0)         # 蛇身 - 绿色
食物颜色 = (255, 0, 0)         # 食物 - 红色
文字颜色 = (255, 255, 255)     # 白色文字
边框颜色 = (100, 200, 100)     # 边框颜色
得分颜色 = (255, 215, 0)       # 金色得分显示

# 方向常量
上 = (0, -1)
下 = (0, 1)
左 = (-1, 0)
右 = (1, 0)


class 贪吃蛇游戏:
    def __init__(self):
        # 初始化屏幕
        self.屏幕 = pygame.display.set_mode((屏幕宽度, 屏幕高度))
        pygame.display.set_caption("贪吃蛇 - 经典原版 - 卢思成制作")

        # 初始化字体 - 使用默认字体避免错误
        try:
            # 尝试使用系统字体
            self.大字体 = pygame.font.Font(None, 48)
            self.中字体 = pygame.font.Font(None, 36)
            self.小字体 = pygame.font.Font(None, 24)
        except:
            # 如果上面的方法失败，使用默认方法
            self.大字体 = pygame.font.Font(None, 48)
            self.中字体 = pygame.font.Font(None, 36)
            self.小字体 = pygame.font.Font(None, 24)

        # 游戏状态
        self.游戏状态 = "菜单"  # 菜单, 游戏中, 游戏结束
        self.时钟 = pygame.time.Clock()

        # 初始化游戏变量
        self.重置游戏()

        # 开发者信息
        self.开发者信息 = {
            "姓名": "卢思成",
            "学校": "东台市第一小学",
            "班级": "六（10）班",
            "学号": "19号"
        }

        # 游戏说明
        self.游戏说明 = [
            "经典贪吃蛇游戏规则:",
            "1. 使用方向键控制蛇的移动",
            "2. 吃到红色食物可以增加长度",
            "3. 撞到墙壁或自己的身体游戏结束",
            "4. 尽可能获得高分!"
        ]

    def 重置游戏(self):
        """重置游戏状态"""
        # 蛇的初始位置和长度
        self.蛇 = [(网格宽度 // 2, 网格高度 // 2)]
        self.蛇方向 = 右
        self.下一方向 = 右

        # 游戏分数
        self.分数 = 0
        self.最高分 = 0

        # 游戏速度
        self.游戏速度 = 游戏帧率

        # 生成第一个食物
        self.食物位置 = self.生成食物()

        # 游戏计时
        self.游戏时间 = 0
        self.开始时间 = time.time()

        # 移动计数
        self.移动计数 = 0

    def 生成食物(self):
        """在地图上随机生成食物"""
        while True:
            食物位置 = (random.randint(0, 网格宽度 - 1),
                    random.randint(0, 网格高度 - 1))
            # 确保食物不会生成在蛇身上
            if 食物位置 not in self.蛇:
                return 食物位置

    def 处理输入(self):
        """处理玩家输入"""
        for 事件 in pygame.event.get():
            if 事件.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif 事件.type == pygame.KEYDOWN:
                if self.游戏状态 == "菜单":
                    if 事件.key == pygame.K_SPACE or 事件.key == pygame.K_RETURN:
                        self.游戏状态 = "游戏中"
                    elif 事件.key == pygame.K_ESCAPE:
                        pygame.quit()
                        sys.exit()

                elif self.游戏状态 == "游戏中":
                    if 事件.key == pygame.K_UP and self.蛇方向 != 下:
                        self.下一方向 = 上
                    elif 事件.key == pygame.K_DOWN and self.蛇方向 != 上:
                        self.下一方向 = 下
                    elif 事件.key == pygame.K_LEFT and self.蛇方向 != 右:
                        self.下一方向 = 左
                    elif 事件.key == pygame.K_RIGHT and self.蛇方向 != 左:
                        self.下一方向 = 右
                    elif 事件.key == pygame.K_p:
                        self.游戏状态 = "菜单"
                    elif 事件.key == pygame.K_ESCAPE:
                        self.游戏状态 = "菜单"

                elif self.游戏状态 == "游戏结束":
                    if 事件.key == pygame.K_SPACE or 事件.key == pygame.K_RETURN:
                        self.重置游戏()
                        self.游戏状态 = "游戏中"
                    elif 事件.key == pygame.K_ESCAPE:
                        self.游戏状态 = "菜单"

    def 更新游戏(self):
        """更新游戏逻辑"""
        if self.游戏状态 != "游戏中":
            return

        # 更新蛇的方向
        self.蛇方向 = self.下一方向

        # 计算新的蛇头位置
        蛇头 = self.蛇[0]
        新蛇头 = (蛇头[0] + self.蛇方向[0],
               蛇头[1] + self.蛇方向[1])

        # 检查是否撞墙
        if (新蛇头[0] < 0 or 新蛇头[0] >= 网格宽度 or
                新蛇头[1] < 0 or 新蛇头[1] >= 网格高度):
            self.游戏状态 = "游戏结束"
            if self.分数 > self.最高分:
                self.最高分 = self.分数
            return

        # 检查是否撞到自己
        if 新蛇头 in self.蛇:
            self.游戏状态 = "游戏结束"
            if self.分数 > self.最高分:
                self.最高分 = self.分数
            return

        # 移动蛇
        self.蛇.insert(0, 新蛇头)

        # 检查是否吃到食物
        if 新蛇头 == self.食物位置:
            self.分数 += 10
            self.食物位置 = self.生成食物()

            # 每得50分加速一次
            if self.分数 % 50 == 0:
                self.游戏速度 += 1
        else:
            # 如果没有吃到食物，移除尾部
            self.蛇.pop()

        # 更新游戏时间
        self.游戏时间 = int(time.time() - self.开始时间)

        # 增加移动计数
        self.移动计数 += 1

    def 绘制背景(self):
        """绘制游戏背景和网格"""
        # 填充背景色
        self.屏幕.fill(背景颜色)

        # 绘制边框
        pygame.draw.rect(self.屏幕, 边框颜色, (0, 0, 屏幕宽度, 屏幕高度), 3)

        # 绘制网格线
        for x in range(0, 屏幕宽度, 网格大小):
            pygame.draw.line(self.屏幕, 网格颜色, (x, 0), (x, 屏幕高度), 1)
        for y in range(0, 屏幕高度, 网格大小):
            pygame.draw.line(self.屏幕, 网格颜色, (0, y), (屏幕宽度, y), 1)

    def 绘制蛇(self):
        """绘制蛇的身体"""
        for i, 位置 in enumerate(self.蛇):
            # 计算像素位置
            x = 位置[0] * 网格大小
            y = 位置[1] * 网格大小

            if i == 0:  # 蛇头
                # 绘制蛇头
                pygame.draw.rect(self.屏幕, 蛇头颜色,
                                 (x, y, 网格大小, 网格大小))

                # 绘制蛇头边框
                pygame.draw.rect(self.屏幕, (0, 150, 0),
                                 (x, y, 网格大小, 网格大小), 1)

                # 绘制蛇眼睛
                眼睛大小 = 网格大小 // 5
                左眼偏移 = 网格大小 // 4
                右眼偏移 = 网格大小 - 网格大小 // 4 - 眼睛大小

                # 根据方向绘制眼睛
                if self.蛇方向 == 右:
                    # 向右看
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 右眼偏移, y + 左眼偏移, 眼睛大小, 眼睛大小))
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 右眼偏移, y + 右眼偏移, 眼睛大小, 眼睛大小))
                elif self.蛇方向 == 左:
                    # 向左看
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 左眼偏移, y + 左眼偏移, 眼睛大小, 眼睛大小))
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 左眼偏移, y + 右眼偏移, 眼睛大小, 眼睛大小))
                elif self.蛇方向 == 上:
                    # 向上看
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 左眼偏移, y + 左眼偏移, 眼睛大小, 眼睛大小))
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 右眼偏移, y + 左眼偏移, 眼睛大小, 眼睛大小))
                else:  # 向下
                    # 向下看
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 左眼偏移, y + 右眼偏移, 眼睛大小, 眼睛大小))
                    pygame.draw.rect(self.屏幕, (0, 0, 0),
                                     (x + 右眼偏移, y + 右眼偏移, 眼睛大小, 眼睛大小))

            else:  # 蛇身
                # 绘制蛇身体
                pygame.draw.rect(self.屏幕, 蛇身颜色,
                                 (x, y, 网格大小, 网格大小))

                # 绘制蛇身体边框
                pygame.draw.rect(self.屏幕, (0, 150, 0),
                                 (x, y, 网格大小, 网格大小), 1)

                # 绘制蛇身体纹路
                纹路宽度 = 网格大小 // 4
                pygame.draw.rect(self.屏幕, (0, 180, 0),
                                 (x + 纹路宽度, y, 纹路宽度, 网格大小))

    def 绘制食物(self):
        """绘制食物"""
        x = self.食物位置[0] * 网格大小
        y = self.食物位置[1] * 网格大小

        # 绘制食物主体
        pygame.draw.rect(self.屏幕, 食物颜色,
                         (x, y, 网格大小, 网格大小))

        # 绘制食物边框
        pygame.draw.rect(self.屏幕, (180, 0, 0),
                         (x, y, 网格大小, 网格大小), 1)

        # 绘制食物高光
        高光大小 = 网格大小 // 3
        pygame.draw.rect(self.屏幕, (255, 100, 100),
                         (x + 高光大小, y + 高光大小, 高光大小, 高光大小))

    def 绘制菜单(self):
        """绘制主菜单"""
        # 绘制游戏标题
        标题 = self.大字体.render("贪吃蛇游戏", True, 蛇头颜色)
        标题阴影 = self.大字体.render("贪吃蛇游戏", True, (0, 100, 0))
        self.屏幕.blit(标题阴影, (屏幕宽度//2 - 标题.get_width()//2 + 3, 103))
        self.屏幕.blit(标题, (屏幕宽度//2 - 标题.get_width()//2, 100))

        # 绘制副标题
        副标题 = self.中字体.render("经典原版复刻", True, 食物颜色)
        self.屏幕.blit(副标题, (屏幕宽度//2 - 副标题.get_width()//2, 160))

        # 绘制最高分
        最高分文字 = self.中字体.render(f"最高分: {self.最高分}", True, 得分颜色)
        self.屏幕.blit(最高分文字, (屏幕宽度//2 - 最高分文字.get_width()//2, 220))

        # 绘制开始按钮
        按钮宽度, 按钮高度 = 200, 50
        按钮x = 屏幕宽度//2 - 按钮宽度//2
        按钮y = 300

        pygame.draw.rect(self.屏幕, 蛇头颜色,
                         (按钮x, 按钮y, 按钮宽度, 按钮高度))
        pygame.draw.rect(self.屏幕, (0, 150, 0),
                         (按钮x, 按钮y, 按钮宽度, 按钮高度), 3)

        开始文字 = self.中字体.render("开始游戏", True, 文字颜色)
        self.屏幕.blit(开始文字, (按钮x + 按钮宽度//2 - 开始文字.get_width()//2,
                            按钮y + 按钮高度//2 - 开始文字.get_height()//2))

        # 绘制操作说明
        控制提示 = "按空格键或回车键开始游戏"
        控制文字 = self.小字体.render(控制提示, True, 文字颜色)
        self.屏幕.blit(控制文字, (屏幕宽度//2 - 控制文字.get_width()//2, 370))

        # 绘制游戏说明
        y偏移 = 420
        for 行 in self.游戏说明:
            说明文字 = self.小字体.render(行, True, 文字颜色)
            self.屏幕.blit(说明文字, (屏幕宽度//2 - 说明文字.get_width()//2, y偏移))
            y偏移 += 25

        # 绘制开发者信息
        开发者文字 = f"开发者: {self.开发者信息['姓名']}"
        开发者渲染 = self.小字体.render(开发者文字, True, (150, 150, 150))
        self.屏幕.blit(开发者渲染, (屏幕宽度//2 - 开发者渲染.get_width()//2,
                             屏幕高度 - 80))

        学校信息 = f"{self.开发者信息['学校']} {self.开发者信息['班级']} {self.开发者信息['学号']}"
        学校渲染 = self.小字体.render(学校信息, True, (150, 150, 150))
        self.屏幕.blit(学校渲染, (屏幕宽度//2 - 学校渲染.get_width()//2,
                            屏幕高度 - 60))

        # 绘制控制说明
        控制说明 = "游戏中: 方向键移动 | P键暂停 | ESC返回菜单"
        控制说明渲染 = self.小字体.render(控制说明, True, (180, 180, 180))
        self.屏幕.blit(控制说明渲染, (屏幕宽度//2 - 控制说明渲染.get_width()//2,
                              屏幕高度 - 30))

    def 绘制游戏界面(self):
        """绘制游戏进行中的界面"""
        # 绘制游戏区域
        self.绘制背景()
        self.绘制蛇()
        self.绘制食物()

        # 绘制分数
        分数文字 = self.中字体.render(f"分数: {self.分数}", True, 得分颜色)
        self.屏幕.blit(分数文字, (10, 10))

        # 绘制最高分
        最高分文字 = self.中字体.render(f"最高分: {self.最高分}", True, 得分颜色)
        self.屏幕.blit(最高分文字, (屏幕宽度 - 最高分文字.get_width() - 10, 10))

        # 绘制蛇长度
        长度文字 = self.小字体.render(f"长度: {len(self.蛇)}", True, 文字颜色)
        self.屏幕.blit(长度文字, (10, 50))

        # 绘制游戏时间
        时间文字 = self.小字体.render(f"时间: {self.游戏时间}秒", True, 文字颜色)
        self.屏幕.blit(时间文字, (屏幕宽度 - 时间文字.get_width() - 10, 50))

        # 绘制游戏速度
        速度文字 = self.小字体.render(f"速度: {self.游戏速度}", True, 文字颜色)
        self.屏幕.blit(速度文字, (屏幕宽度//2 - 速度文字.get_width()//2, 10))

        # 绘制控制提示
        控制提示 = "方向键移动 | P键暂停 | ESC返回菜单"
        控制渲染 = self.小字体.render(控制提示, True, (180, 180, 180))
        self.屏幕.blit(控制渲染, (屏幕宽度//2 - 控制渲染.get_width()//2, 屏幕高度 - 30))

    def 绘制游戏结束(self):
        """绘制游戏结束界面"""
        # 半透明覆盖层
        覆盖层 = pygame.Surface((屏幕宽度, 屏幕高度), pygame.SRCALPHA)
        覆盖层.fill((0, 0, 0, 150))
        self.屏幕.blit(覆盖层, (0, 0))

        # 游戏结束标题
        结束标题 = self.大字体.render("游戏结束!", True, 食物颜色)
        self.屏幕.blit(结束标题, (屏幕宽度//2 - 结束标题.get_width()//2, 150))

        # 绘制最终分数
        最终分数 = self.中字体.render(f"最终分数: {self.分数}", True, 得分颜色)
        self.屏幕.blit(最终分数, (屏幕宽度//2 - 最终分数.get_width()//2, 220))

        # 绘制蛇长度
        最终长度 = self.中字体.render(f"蛇长度: {len(self.蛇)}", True, 蛇头颜色)
        self.屏幕.blit(最终长度, (屏幕宽度//2 - 最终长度.get_width()//2, 260))

        # 绘制游戏时间
        游戏时间 = self.中字体.render(f"游戏时间: {self.游戏时间}秒", True, 文字颜色)
        self.屏幕.blit(游戏时间, (屏幕宽度//2 - 游戏时间.get_width()//2, 300))

        # 绘制重新开始按钮
        按钮宽度, 按钮高度 = 200, 50
        按钮x = 屏幕宽度//2 - 按钮宽度//2
        按钮y = 350

        pygame.draw.rect(self.屏幕, 蛇头颜色,
                         (按钮x, 按钮y, 按钮宽度, 按钮高度))
        pygame.draw.rect(self.屏幕, (0, 150, 0),
                         (按钮x, 按钮y, 按钮宽度, 按钮高度), 3)

        重新开始文字 = self.中字体.render("重新开始", True, 文字颜色)
        self.屏幕.blit(重新开始文字, (按钮x + 按钮宽度//2 - 重新开始文字.get_width()//2,
                              按钮y + 按钮高度//2 - 重新开始文字.get_height()//2))

        # 绘制返回菜单按钮
        菜单按钮y = 按钮y + 按钮高度 + 20
        pygame.draw.rect(self.屏幕, 边框颜色,
                         (按钮x, 菜单按钮y, 按钮宽度, 按钮高度))
        pygame.draw.rect(self.屏幕, (50, 150, 50),
                         (按钮x, 菜单按钮y, 按钮宽度, 按钮高度), 3)

        菜单文字 = self.中字体.render("返回菜单", True, 文字颜色)
        self.屏幕.blit(菜单文字, (按钮x + 按钮宽度//2 - 菜单文字.get_width()//2,
                            菜单按钮y + 按钮高度//2 - 菜单文字.get_height()//2))

        # 绘制操作提示
        操作提示 = "按空格键重新开始，ESC键返回菜单"
        提示文字 = self.小字体.render(操作提示, True, 文字颜色)
        self.屏幕.blit(提示文字, (屏幕宽度//2 - 提示文字.get_width()//2, 450))

    def 运行(self):
        """运行游戏主循环"""
        print("""
        贪吃蛇游戏 - 经典原版复刻
        开发者: 卢思成
        学校: 东台市第一小学
        班级: 六（10）班
        学号: 19号
        
        操作说明:
        游戏中: 方向键控制蛇的移动
        菜单中: 空格键开始游戏
        游戏中: P键暂停，ESC键返回菜单
        游戏结束: 空格键重新开始
        
        游戏规则:
        1. 使用方向键控制蛇的移动
        2. 吃到红色食物可以增加长度
        3. 撞到墙壁或自己的身体游戏结束
        4. 尽可能获得高分!
        """)

        while True:
            # 处理输入
            self.处理输入()

            # 更新游戏状态
            self.更新游戏()

            # 绘制游戏
            if self.游戏状态 == "菜单":
                self.绘制背景()
                self.绘制菜单()
            elif self.游戏状态 == "游戏中":
                self.绘制游戏界面()
            elif self.游戏状态 == "游戏结束":
                # 先绘制游戏画面
                self.绘制游戏界面()
                # 再绘制结束界面
                self.绘制游戏结束()

            # 更新显示
            pygame.display.flip()

            # 控制帧率
            self.时钟.tick(self.游戏速度)


# 运行游戏
if __name__ == "__main__":
    try:
        游戏 = 贪吃蛇游戏()
        游戏.运行()
    except Exception as 错误:
        print(f"游戏启动出错: {错误}")
        import traceback
        traceback.print_exc()
        input("按回车键退出...")
