import pygame
import random
import sys

# 初始化pygame
pygame.init()

# 窗口基础设置
WIDTH, HEIGHT = 640, 480
CELL_SIZE = 20
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("贪吃蛇闯关版")

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

# 字体（兼容中文）
font_large = pygame.font.SysFont("simhei", 36)
font_mid = pygame.font.SysFont("simhei", 24)
font_small = pygame.font.SysFont("simhei", 18)

# 全局变量
clock = pygame.time.Clock()
snake = []
food = (0, 0)
direction = (CELL_SIZE, 0)
next_dir = direction
score = 0
level = 1
speed = 8
game_state = "start"  # start / playing / levelup / gameover

# 生成随机食物（不生成在蛇身上）
def create_food():
    while True:
        x = random.randrange(0, WIDTH, CELL_SIZE)
        y = random.randrange(0, HEIGHT, CELL_SIZE)
        if (x, y) not in snake:
            return (x, y)

# 重置游戏（初始化所有游戏元素）
def reset_game():
    global snake, direction, next_dir, food, score, speed
    snake = [
        (WIDTH // 2, HEIGHT // 2),
        (WIDTH // 2 - CELL_SIZE, HEIGHT // 2),
        (WIDTH // 2 - CELL_SIZE * 2, HEIGHT // 2)
    ]
    direction = (CELL_SIZE, 0)
    next_dir = direction
    food = create_food()
    score = 0
    speed = 8 + (level - 1) * 2

# 绘制文字
def draw_text(text, color, x, y, font):
    txt_surface = font.render(text, True, color)
    screen.blit(txt_surface, (x, y))

# 开始界面
def show_start():
    screen.fill(BLACK)
    draw_text("贪吃蛇 闯关模式", GREEN, 220, 150, font_large)
    draw_text("方向键 ↑ ↓ ← → 控制蛇移动", WHITE, 180, 220, font_mid)
    draw_text("吃到食物得分，撞墙/撞自己游戏结束", WHITE, 150, 270, font_small)
    draw_text("按 空格键 开始游戏", YELLOW, 230, 330, font_mid)
    pygame.display.update()

# 过关提示界面
def show_level_up():
    screen.fill(BLACK)
    draw_text(f"恭喜！通关第 {level} 关", YELLOW, 200, 180, font_large)
    draw_text("按下空格进入下一关", WHITE, 210, 260, font_mid)
    pygame.display.update()

# 游戏结束界面
def show_game_over():
    screen.fill(BLACK)
    draw_text("游戏结束", RED, 240, 160, font_large)
    draw_text(f"最终得分：{score}", WHITE, 230, 230, font_mid)
    draw_text(f"到达关卡：{level}", WHITE, 230, 270, font_mid)
    draw_text("按 空格键 重新开始", YELLOW, 210, 330, font_mid)
    pygame.display.update()

# 主游戏逻辑
def game_loop():
    global direction, next_dir, score, level, game_state, food

    while True:
        # 事件监听
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            # 键盘按键
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if game_state == "start":
                        level = 1
                        reset_game()
                        game_state = "playing"
                    elif game_state == "levelup":
                        level += 1
                        reset_game()
                        game_state = "playing"
                    elif game_state == "gameover":
                        level = 1
                        reset_game()
                        game_state = "playing"

                # 方向控制（禁止直接反向）
                if game_state == "playing":
                    if event.key == pygame.K_UP and direction != (0, CELL_SIZE):
                        next_dir = (0, -CELL_SIZE)
                    elif event.key == pygame.K_DOWN and direction != (0, -CELL_SIZE):
                        next_dir = (0, CELL_SIZE)
                    elif event.key == pygame.K_LEFT and direction != (CELL_SIZE, 0):
                        next_dir = (-CELL_SIZE, 0)
                    elif event.key == pygame.K_RIGHT and direction != (-CELL_SIZE, 0):
                        next_dir = (CELL_SIZE, 0)

        # 不同状态渲染界面
        if game_state == "start":
            show_start()
            continue
        if game_state == "levelup":
            show_level_up()
            continue
        if game_state == "gameover":
            show_game_over()
            continue

        # 游戏进行中逻辑
        direction = next_dir
        head_x, head_y = snake[0]
        new_head = (head_x + direction[0], head_y + direction[1])

        # 撞墙判断
        if new_head[0] < 0 or new_head[0] >= WIDTH or new_head[1] < 0 or new_head[1] >= HEIGHT:
            game_state = "gameover"
            continue

        # 撞到自己判断
        if new_head in snake:
            game_state = "gameover"
            continue

        # 移动蛇
        snake.insert(0, new_head)

        # 吃到食物
        if new_head == food:
            score += 10
            food = create_food()
            # 每50分通关
            if score % 50 == 0:
                game_state = "levelup"
        else:
            snake.pop()

        # 绘制画面
        screen.fill(BLACK)
        # 画蛇
        for idx, pos in enumerate(snake):
            x, y = pos
            if idx == 0:
                pygame.draw.rect(screen, BLUE, (x, y, CELL_SIZE - 1, CELL_SIZE - 1))
            else:
                pygame.draw.rect(screen, GREEN, (x, y, CELL_SIZE - 1, CELL_SIZE - 1))
        # 画食物
        pygame.draw.rect(screen, RED, (food[0], food[1], CELL_SIZE - 1, CELL_SIZE - 1))

        # 绘制分数、关卡
        draw_text(f"关卡：{level}", WHITE, 10, 10, font_mid)
        draw_text(f"分数：{score}", WHITE, 120, 10, font_mid)

        pygame.display.update()
        clock.tick(speed)

if __name__ == "__main__":
    game_loop()