import pygame
import random
import sys

pygame.init()

# ---------- 窗口 ----------
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("扶老奶奶过马路")
clock = pygame.time.Clock()

# 安全字体：只用默认字体，避免 SysFont 崩溃
FONT_SM = pygame.font.Font(None, 24)
FONT_MD = pygame.font.Font(None, 32)
FONT_LG = pygame.font.Font(None, 56)

# ---------- 颜色 ----------
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (120, 120, 120)
DARK_GRAY = (60, 60, 60)
RED = (220, 50, 50)
GREEN = (50, 200, 80)
YELLOW = (240, 220, 60)
SKIN = (255, 200, 150)
HAIR = (200, 200, 200)
DRESS = (180, 100, 160)
CAR_COLORS = [(200, 60, 60), (60, 100, 200), (220, 180, 60), (80, 180, 100), (180, 80, 200)]

# ---------- 道路布局 ----------
ROAD_TOP = 240
ROAD_BOTTOM = 360
ROAD_MID_Y = (ROAD_TOP + ROAD_BOTTOM) // 2

# ---------- 红绿灯 ----------
class TrafficLight:
    def __init__(self):
        self.state = "red"          # red / green / yellow
        self.timer = 0
        self.red_dur = 300           # 红灯持续帧数（约5秒）
        self.green_dur = 240        # 绿灯持续帧数（约4秒）
        self.yellow_dur = 60        # 黄灯持续帧数（约1秒）

    def update(self):
        self.timer += 1
        if self.state == "red" and self.timer >= self.red_dur:
            self.state = "green"; self.timer = 0
        elif self.state == "green" and self.timer >= self.green_dur:
            self.state = "yellow"; self.timer = 0
        elif self.state == "yellow" and self.timer >= self.yellow_dur:
            self.state = "red"; self.timer = 0

    def draw(self, x, y):
        # 灯柱
        pygame.draw.rect(screen, DARK_GRAY, (x - 6, y - 46, 12, 92))
        # 灯箱
        pygame.draw.rect(screen, (30, 30, 30), (x - 16, y - 46, 32, 92), border_radius=6)
        # 三盏灯
        r_on = RED if self.state == "red" else (60, 20, 20)
        y_on = YELLOW if self.state == "yellow" else (60, 60, 20)
        g_on = GREEN if self.state == "green" else (20, 60, 30)
        pygame.draw.circle(screen, r_on, (x, y - 30), 9)
        pygame.draw.circle(screen, y_on, (x, y), 9)
        pygame.draw.circle(screen, g_on, (x, y + 30), 9)

    def is_safe_for_pedestrian(self):
        # 红灯或黄灯时行人才可以过（黄灯作为过渡，允许继续走）
        return self.state in ("red", "yellow")

# ---------- 老奶奶（玩家控制）----------
class Grandma:
    def __init__(self):
        self.reset()

    def reset(self):
        self.x = 60
        self.y = HEIGHT - 60
        self.speed = 3
        self.reached = False       # 是否到达对面
        self.failed = False        # 是否被车撞

    def handle_input(self, keys):
        if keys[pygame.K_LEFT]:
            self.x -= self.speed
        if keys[pygame.K_RIGHT]:
            self.x += self.speed
        if keys[pygame.K_UP]:
            self.y -= self.speed
        if keys[pygame.K_DOWN]:
            self.y += self.speed
        # 边界限制
        self.x = max(20, min(WIDTH - 20, self.x))
        self.y = max(ROAD_BOTTOM + 20, min(HEIGHT - 20, self.y))

    def draw(self):
        # 画老奶奶
        body_x, body_y = int(self.x), int(self.y)
        # 裙子
        pygame.draw.polygon(screen, DRESS, [
            (body_x, body_y - 18),
            (body_x - 12, body_y + 10),
            (body_x + 12, body_y + 10)
        ])
        # 头
        pygame.draw.circle(screen, SKIN, (body_x, body_y - 24), 9)
        # 白发
        pygame.draw.arc(screen, HAIR, (body_x - 9, body_y - 33, 18, 14), 3.14, 6.28, 4)
        # 拐杖
        pygame.draw.line(screen, (120, 80, 40), (body_x + 12, body_y - 20), (body_x + 18, body_y + 10), 3)
        # 小手（牵着玩家的手）
        pygame.draw.circle(screen, SKIN, (body_x - 10, body_y - 5), 4)

        # 画玩家（小朋友牵着奶奶）
        player_x = body_x - 22
        # 身体
        pygame.draw.rect(screen, (60, 130, 220), (player_x - 6, body_y - 14, 12, 24), border_radius=3)
        # 头
        pygame.draw.circle(screen, SKIN, (player_x, body_y - 20), 7)
        # 头发
        pygame.draw.arc(screen, (80, 50, 30), (player_x - 7, body_y - 27, 14, 12), 3.14, 6.28, 3)
        # 牵手
        pygame.draw.line(screen, SKIN, (player_x + 6, body_y - 6), (body_x - 10, body_y - 5), 3)

    def on_road(self):
        return ROAD_TOP <= self.y <= ROAD_BOTTOM

    def reached_other_side(self):
        return self.y < ROAD_TOP - 10 and self.x > 40

# ---------- 汽车 ----------
class Car:
    def __init__(self, light_state):
        # 随机车道：上半路或下半路
        lane = random.choice(["up", "down"])
        if lane == "up":
            self.y = random.randint(ROAD_TOP + 8, ROAD_MID_Y - 8)
            self.x = -40
            self.vx = random.uniform(3.5, 6.0)
        else:
            self.y = random.randint(ROAD_MID_Y + 8, ROAD_BOTTOM - 8)
            self.x = WIDTH + 40
            self.vx = -random.uniform(3.5, 6.0)
        self.color = random.choice(CAR_COLORS)
        self.width = 44
        self.height = 22
        self.moving = (light_state == "green")

    def update(self, light_state):
        # 绿灯时车才动
        if light_state == "green":
            self.x += self.vx
            self.moving = True
        else:
            self.moving = False
        return self.x < -60 or self.x > WIDTH + 60

    def draw(self):
        if not self.moving:
            # 停车时画刹车灯
            if self.vx > 0:  # 向右行驶的车
                pygame.draw.rect(screen, (255, 0, 0), (self.x + self.width - 4, self.y + 4, 4, 5))
                pygame.draw.rect(screen, (255, 0, 0), (self.x + self.width - 4, self.y + self.height - 9, 4, 5))
            else:  # 向左行驶的车
                pygame.draw.rect(screen, (255, 0, 0), (self.x, self.y + 4, 4, 5))
                pygame.draw.rect(screen, (255, 0, 0), (self.x, self.y + self.height - 9, 4, 5))
        # 车身
        pygame.draw.rect(screen, self.color, (int(self.x), int(self.y), self.width, self.height), border_radius=4)
        # 车窗
        pygame.draw.rect(screen, (180, 220, 255), (int(self.x) + 6, int(self.y) + 4, 12, self.height - 8), border_radius=2)
        pygame.draw.rect(screen, (180, 220, 255), (int(self.x) + self.width - 18, int(self.y) + 4, 12, self.height - 8), border_radius=2)
        # 车轮
        pygame.draw.circle(screen, BLACK, (int(self.x) + 10, int(self.y) + self.height), 4)
        pygame.draw.circle(screen, BLACK, (int(self.x) + self.width - 10, int(self.y) + self.height), 4)

    def collides_with(self, grandma):
        gr = pygame.Rect(int(grandma.x) - 12, int(grandma.y) - 28, 24, 40)
        cr = pygame.Rect(int(self.x), int(self.y), self.width, self.height)
        return gr.colliderect(cr)

# ---------- 游戏状态 ----------
state = "ready"        # ready / playing / won / lost
light = TrafficLight()
grandma = Grandma()
cars = []
car_spawn_timer = 0
crossings = 0          # 成功次数
message = ""

# ---------- 绘制场景 ----------
def draw_scene():
    # 天空
    screen.fill((135, 206, 235))
    # 草地（上下）
    pygame.draw.rect(screen, (100, 180, 100), (0, 0, WIDTH, ROAD_TOP))
    pygame.draw.rect(screen, (100, 180, 100), (0, ROAD_BOTTOM, WIDTH, HEIGHT - ROAD_BOTTOM))
    # 道路
    pygame.draw.rect(screen, DARK_GRAY, (0, ROAD_TOP, WIDTH, ROAD_BOTTOM - ROAD_TOP))
    # 中线
    for x in range(0, WIDTH, 40):
        pygame.draw.rect(screen, YELLOW, (x, ROAD_MID_Y - 2, 20, 4))
    # 斑马线
    for x in range(120, 200, 20):
        pygame.draw.rect(screen, WHITE, (x, ROAD_TOP + 4, 10, ROAD_BOTTOM - ROAD_TOP - 8), 1)
    # 树
    for tx in [40, 300, 760]:
        pygame.draw.rect(screen, (100, 60, 30), (tx - 5, 40, 10, 40))
        pygame.draw.circle(screen, (60, 140, 60), (tx, 40), 25)
    # 红绿灯
    light.draw(160, ROAD_MID_Y)
    # 状态文字
    status = FONT_SM.render(
        f"🚦 {light.state.upper()}   |   成功护送: {crossings}", True, BLACK
    )
    screen.blit(status, (10, 10))
    # 操作提示
    hint = FONT_SM.render("←→↑↓ 移动  |  红灯时扶奶奶过马路", True, BLACK)
    screen.blit(hint, (10, HEIGHT - 30))

# ---------- 主循环 ----------
running = True
while running:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:
                state = "ready"
                crossings = 0
                cars.clear()
                grandma.reset()
                light = TrafficLight()
            if state == "ready" and event.key == pygame.K_SPACE:
                state = "playing"

    # ----- 更新 -----
    if state == "playing":
        keys = pygame.key.get_pressed()
        grandma.handle_input(keys)
        light.update()

        # 生成车
        car_spawn_timer += 1
        if car_spawn_timer > 45:
            car_spawn_timer = 0
            if len(cars) < 5:
                cars.append(Car(light.state))

        # 更新车
        for car in cars[:]:
            if car.update(light.state):
                cars.remove(car)
            # 碰撞检测
            if grandma.on_road() and car.collides_with(grandma):
                state = "lost"
                message = "奶奶被车撞了！按 R 重新开始"

        # 成功过马路
        if grandma.reached_other_side():
            crossings += 1
            if crossings >= 3:
                state = "won"
                message = f"太棒了！成功护送 {crossings} 次！按 R 再玩"
            else:
                # 复位奶奶回到起点
                grandma.reset()
                message = f"成功！再护送 {3 - crossings} 次"

    # ----- 绘制 -----
    draw_scene()
    for car in cars:
        car.draw()
    grandma.draw()

    # 遮罩层
    if state == "ready":
        overlay = pygame.Surface((WIDTH, HEIGHT)); overlay.set_alpha(180); overlay.fill(BLACK)
        screen.blit(overlay, (0, 0))
        t1 = FONT_LG.render("扶老奶奶过马路", True, YELLOW)
        screen.blit(t1, (WIDTH//2 - 180, 200))
        t2 = FONT_MD.render("红灯时扶奶奶过马路，绿灯时绝对不能上道！", True, WHITE)
        screen.blit(t2, (WIDTH//2 - 230, 280))
        t3 = FONT_MD.render("← → ↑ ↓ 控制移动", True, WHITE)
        screen.blit(t3, (WIDTH//2 - 100, 340))
        t4 = FONT_MD.render("按 空格键 开始", True, GREEN)
        screen.blit(t4, (WIDTH//2 - 90, 400))
    elif state == "won" or state == "lost":
        overlay = pygame.Surface((WIDTH, HEIGHT)); overlay.set_alpha(160); overlay.fill(BLACK)
        screen.blit(overlay, (0, 0))
        color = GREEN if state == "won" else RED
        t1 = FONT_LG.render(message.split('！')[0], True, color)
        screen.blit(t1, (WIDTH//2 - 160, 250))
        t2 = FONT_MD.render("按 R 键重新开始", True, WHITE)
        screen.blit(t2, (WIDTH//2 - 100, 320))

    # 临时消息
    if message and state == "playing":
        msg_surf = FONT_SM.render(message, True, WHITE)
        screen.blit(msg_surf, (WIDTH//2 - 150, 70))
        # 3秒后清除
        if car_spawn_timer % 180 == 0:
            message = ""

    pygame.display.flip()

pygame.quit()
sys.exit()