import pygame
import random

# 初始化
pygame.init()

# 常量定义
SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 960
GRID_SIZE = 20  # 网格大小
GRID_WIDTH = SCREEN_WIDTH // GRID_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // GRID_SIZE

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

# 屏幕设置
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Snake Game")

class Snake(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((GRID_SIZE, GRID_SIZE))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect(center=(SCREEN_WIDTH // 2+10, SCREEN_HEIGHT // 2+10))
        self.direction = "right"
        self.body_segments = []
        self.growth_amount = 1
        self.move_counter = 0  # 新增计数器
        self.move_interval = 18  # 每 5 帧移动一次

    def update(self):
        self.move_counter += 1
        if self.move_counter < self.move_interval:
            return  # 未达到移动间隔，直接返回

        self.move_counter = 0  # 重置计数器

        # 保存头部移动前的位置
        old_head_pos = self.rect.copy()

        # 移动头部
        if self.direction == "left":
            self.rect.x -= GRID_SIZE
        elif self.direction == "right":
            self.rect.x += GRID_SIZE
        elif self.direction == "up":
            self.rect.y -= GRID_SIZE
        elif self.direction == "down":
            self.rect.y += GRID_SIZE

        # 更新身体段的位置
        if self.body_segments:
            old_positions = [old_head_pos] + [seg.rect.copy() for seg in self.body_segments[:-1]]
            for i, seg in enumerate(self.body_segments):
                seg.rect = old_positions[i]

        # 检测是否撞墙
        if (self.rect.left < 0 or self.rect.right > SCREEN_WIDTH or
            self.rect.top < 0 or self.rect.bottom > SCREEN_HEIGHT):
            game_over()

        # 检测是否撞到身体
        for segment in self.body_segments:
            if self.rect.colliderect(segment.rect):
                game_over()

    def add_segment(self):
        for _ in range(self.growth_amount):
            new_segment = pygame.sprite.Sprite()
            new_segment.image = pygame.Surface((GRID_SIZE, GRID_SIZE))
            new_segment.image.fill((0, 200, 0))
            
            if self.body_segments:
                base_pos = self.body_segments[-1].rect.copy()
            else:
                base_pos = self.rect.copy()
            
            offset = GRID_SIZE
            if self.direction == "left":
                base_pos.x += offset
            elif self.direction == "right":
                base_pos.x -= offset
            elif self.direction == "up":
                base_pos.y += offset
            elif self.direction == "down":
                base_pos.y -= offset
            
            new_segment.rect = base_pos
            self.body_segments.append(new_segment)
            all_sprites.add(new_segment)

class Food(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((GRID_SIZE, GRID_SIZE))
        self.image.fill(RED)
        self.rect = self.image.get_rect(center=(
            random.randint(0, GRID_WIDTH - 1) * GRID_SIZE + GRID_SIZE // 2,
            random.randint(0, GRID_HEIGHT - 1) * GRID_SIZE + GRID_SIZE // 2
        ))

    def update(self):
        if pygame.sprite.collide_rect(snake, self):
            self.rect.center = (
                random.randint(0, GRID_WIDTH - 1) * GRID_SIZE + GRID_SIZE // 2,
                random.randint(0, GRID_HEIGHT - 1) * GRID_SIZE + GRID_SIZE // 2
            )
            snake.add_segment()

def draw_grid():
    for x in range(0, SCREEN_WIDTH, GRID_SIZE):
        pygame.draw.line(screen, WHITE, (x, 0), (x, SCREEN_HEIGHT))
    for y in range(0, SCREEN_HEIGHT, GRID_SIZE):
        pygame.draw.line(screen, WHITE, (0, y), (SCREEN_WIDTH, y))

def game_over():
    global running
    running = False
    print("Game Over! Your score:", len(snake.body_segments))

# 创建蛇对象
snake = Snake()

# 创建精灵组
all_sprites = pygame.sprite.Group()
food_group = pygame.sprite.Group()

# 将蛇和食物添加到精灵组
all_sprites.add(snake)
for _ in range(5):
    food = Food()
    all_sprites.add(food)
    snake.add_segment()
    food_group.add(food)

running = True
clock = pygame.time.Clock()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT and snake.direction != "right":
                snake.direction = "left"
            elif event.key == pygame.K_RIGHT and snake.direction != "left":
                snake.direction = "right"
            elif event.key == pygame.K_UP and snake.direction != "down":
                snake.direction = "up"
            elif event.key == pygame.K_DOWN and snake.direction != "up":
                snake.direction = "down"

    # 更新所有精灵的位置
    all_sprites.update()

    # 填充背景颜色
    screen.fill(BLACK)

    # 绘制网格
    draw_grid()

    # 绘制所有精灵
    all_sprites.draw(screen)

    # 刷新屏幕显示
    pygame.display.flip()

    # 控制游戏帧率
    clock.tick(10000)

pygame.quit()