import pygame
import sys
import random
import math

# ========== 初始化 ==========
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("🪟 Glass Bridge – Easier Mode")
clock = pygame.time.Clock()

# ========== 颜色 ==========
BG_DEEP = (5, 3, 8)
WALL_DARK = (18, 12, 22)
LIGHT_BEAM = (255, 240, 200, 15)
GLASS_SAFE = (70, 200, 110, 200)
GLASS_DANGER = (220, 70, 70, 200)
GLASS_NEUTRAL = (180, 180, 190, 70)
PLAYER_GREEN = (30, 140, 80)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GOLD = (255, 215, 0)
RED = (255, 60, 60)
CYAN = (0, 255, 255)
BLOOD_RED = (160, 20, 20)

# ========== 字体 ==========
font_step = pygame.font.Font(None, 90)
font_small = pygame.font.Font(None, 32)
font_big = pygame.font.Font(None, 70)

# ========== 游戏参数 ==========
STEP_COUNT = 6          # 从18步改为6步，极易获胜
GLASS_WIDTH = 140
GLASS_HEIGHT = 28
GLASS_Y = 370
LEFT_GLASS_X = 210
RIGHT_GLASS_X = 450
PLAYER_START_X = 350
PLAYER_START_Y = 490
HINT_DURATION = 60      # 提示持续帧数（1秒）
MAX_HINTS = 3

# ========== 工具函数 ==========
def draw_glass(surface, rect, color, border_color, border_width=2, cracked=False):
    s = pygame.Surface(rect.size, pygame.SRCALPHA)
    pygame.draw.rect(s, color, s.get_rect(), border_radius=8)
    if cracked:
        for _ in range(8):
            start_x = random.randint(4, rect.width-8)
            start_y = random.randint(4, rect.height-8)
            end_x = start_x + random.randint(-15, 15)
            end_y = start_y + random.randint(-15, 15)
            pygame.draw.line(s, (0,0,0,180), (start_x, start_y), (end_x, end_y), 2)
    if border_color:
        pygame.draw.rect(s, border_color, s.get_rect(), border_width, border_radius=8)
    shine = pygame.Surface((rect.width, rect.height//2), pygame.SRCALPHA)
    shine.fill((255,255,255,25))
    s.blit(shine, (0,0))
    surface.blit(s, rect.topleft)

# ========== 碎片粒子 ==========
class Shard:
    def __init__(self, x, y, color):
        self.x = x; self.y = y
        self.vx = random.uniform(-6, 6)
        self.vy = random.uniform(-12, -5)
        self.color = color
        self.life = 45; self.max_life = 45
        self.size = random.randint(5, 10)
        self.angle = random.randint(0, 360)
        self.rot_speed = random.uniform(-10, 10)

    def update(self):
        self.x += self.vx; self.y += self.vy
        self.vy += 0.35
        self.life -= 1
        self.angle += self.rot_speed

    def draw(self, surface):
        alpha = int(255 * self.life / self.max_life)
        if alpha <= 0: return
        s = pygame.Surface((self.size, self.size), pygame.SRCALPHA)
        pygame.draw.rect(s, (*self.color, alpha), s.get_rect())
        rotated = pygame.transform.rotate(s, self.angle)
        surface.blit(rotated, (self.x - rotated.get_width()//2, self.y - rotated.get_height()//2))

# ========== 主游戏类 ==========
class GlassBridge:
    def __init__(self):
        self.reset()

    def reset(self):
        self.score = 0
        self.step = 0
        self.state = "waiting"      # waiting, animating, falling, gameover, win
        self.safe_side = random.choice(["left", "right"])
        self.player_x = PLAYER_START_X
        self.player_y = PLAYER_START_Y
        self.target_x = PLAYER_START_X
        self.target_y = PLAYER_START_Y
        self.shards = []
        self.fall_vy = 0
        self.fall = False
        self.anim_progress = 0
        self.anim_start_x = PLAYER_START_X
        self.anim_start_y = PLAYER_START_Y
        self.mouse_on_left = False
        self.mouse_on_right = False
        self.danger_flash = 0
        self.hints_left = MAX_HINTS
        self.hint_timer = 0         # 提示剩余时间（帧数），0表示未激活

    def handle_choice(self, side):
        if self.state != "waiting": return
        correct = (side == self.safe_side)
        if correct:
            self.state = "animating"
            if side == "left":
                self.target_x = LEFT_GLASS_X + GLASS_WIDTH//2
                self.target_y = GLASS_Y - 35
            else:
                self.target_x = RIGHT_GLASS_X + GLASS_WIDTH//2
                self.target_y = GLASS_Y - 35
            self.anim_start_x = self.player_x
            self.anim_start_y = self.player_y
            self.anim_progress = 0
        else:
            self.state = "falling"
            glass_x = LEFT_GLASS_X if side == "left" else RIGHT_GLASS_X
            for _ in range(35):
                self.shards.append(Shard(glass_x + random.randint(0, GLASS_WIDTH),
                                         GLASS_Y + random.randint(0, GLASS_HEIGHT),
                                         GLASS_DANGER[:3]))
            self.fall = True
            self.fall_vy = 0
            self.player_x = glass_x + GLASS_WIDTH//2
            self.player_y = GLASS_Y - 10
            self.danger_flash = 30

    def activate_hint(self):
        if self.state == "waiting" and self.hints_left > 0 and self.hint_timer == 0:
            self.hints_left -= 1
            self.hint_timer = HINT_DURATION

    def update(self):
        for shard in self.shards[:]:
            shard.update()
            if shard.life <= 0:
                self.shards.remove(shard)

        # 动画更新
        if self.state == "animating":
            self.anim_progress += 0.07
            if self.anim_progress >= 1.0:
                self.anim_progress = 1.0
                self.player_x = self.target_x
                self.player_y = self.target_y
                self.score += 1
                self.step += 1
                if self.step >= STEP_COUNT:
                    self.state = "win"
                else:
                    self.state = "waiting"
                    self.safe_side = random.choice(["left", "right"])
                    self.player_x = PLAYER_START_X
                    self.player_y = PLAYER_START_Y
                    self.target_x = PLAYER_START_X
                    self.target_y = PLAYER_START_Y
            else:
                t = self.anim_progress
                self.player_x = self.anim_start_x + (self.target_x - self.anim_start_x) * t
                peak = -100
                self.player_y = self.anim_start_y + (self.target_y - self.anim_start_y) * t + peak * 4 * t * (1 - t)

        if self.fall:
            self.fall_vy += 0.7
            self.player_y += self.fall_vy
            if self.player_y > HEIGHT + 80:
                self.fall = False
                self.state = "gameover"

        if self.danger_flash > 0:
            self.danger_flash -= 1

        if self.hint_timer > 0:
            self.hint_timer -= 1

        # 鼠标检测
        if self.state == "waiting":
            mx, my = pygame.mouse.get_pos()
            self.mouse_on_left = (LEFT_GLASS_X <= mx <= LEFT_GLASS_X + GLASS_WIDTH and
                                  GLASS_Y <= my <= GLASS_Y + GLASS_HEIGHT)
            self.mouse_on_right = (RIGHT_GLASS_X <= mx <= RIGHT_GLASS_X + GLASS_WIDTH and
                                   GLASS_Y <= my <= GLASS_Y + GLASS_HEIGHT)

    def draw_background(self):
        screen.fill(BG_DEEP)
        # 观众剪影
        for i in range(0, WIDTH, 40):
            h = random.randint(30, 60)
            pygame.draw.rect(screen, (8, 5, 10), (i, HEIGHT-30-h, 25, h))
        # 深渊
        for y in range(GLASS_Y+GLASS_HEIGHT+15, HEIGHT, 20):
            alpha = max(10, 150 - (y - GLASS_Y))
            pygame.draw.line(screen, (10, 5, 10, alpha), (0, y), (WIDTH, y), 3)

    def draw_glasses(self):
        left_rect = pygame.Rect(LEFT_GLASS_X, GLASS_Y, GLASS_WIDTH, GLASS_HEIGHT)
        right_rect = pygame.Rect(RIGHT_GLASS_X, GLASS_Y, GLASS_WIDTH, GLASS_HEIGHT)

        if self.state in ("waiting", "animating"):
            # 正常状态
            for rect, hover in [(left_rect, self.mouse_on_left), (right_rect, self.mouse_on_right)]:
                border = CYAN if hover else (120,120,140)
                # 如果提示激活，安全玻璃边框闪烁金色
                if self.hint_timer > 0:
                    if (rect == left_rect and self.safe_side == "left") or (rect == right_rect and self.safe_side == "right"):
                        border = GOLD
                draw_glass(screen, rect, GLASS_NEUTRAL, border, border_width=3)
        elif self.state in ("falling", "gameover"):
            safe_rect = left_rect if self.safe_side == "left" else right_rect
            danger_rect = right_rect if self.safe_side == "left" else left_rect
            draw_glass(screen, safe_rect, GLASS_SAFE, (80,255,120), border_width=3)
            draw_glass(screen, danger_rect, (80,30,30,150), (220,60,60), border_width=2, cracked=True)
        elif self.state == "win":
            for rect in [left_rect, right_rect]:
                draw_glass(screen, rect, GLASS_SAFE, (80,255,120), border_width=3)

        # 危险闪烁
        if self.danger_flash > 0 and self.danger_flash % 4 < 2:
            flash_surf = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            flash_surf.fill((255,0,0, 40))
            screen.blit(flash_surf, (0,0))

    def draw_player(self):
        if self.state == "gameover" and not self.fall:
            return
        color = PLAYER_GREEN if not self.fall else (120, 30, 30)
        # 影子
        pygame.draw.ellipse(screen, (0,0,0,100), (self.player_x-14, self.player_y+2, 28, 8))
        # 头
        pygame.draw.circle(screen, (255,220,180), (int(self.player_x), int(self.player_y-24)), 13)
        pygame.draw.circle(screen, BLACK, (int(self.player_x), int(self.player_y-24)), 13, 2)
        # 眼睛
        eye_y = self.player_y - 27
        pygame.draw.circle(screen, BLACK, (self.player_x-5, eye_y), 3)
        pygame.draw.circle(screen, BLACK, (self.player_x+5, eye_y), 3)
        # 衣服
        body_rect = pygame.Rect(self.player_x-13, self.player_y-11, 26, 30)
        pygame.draw.rect(screen, color, body_rect, border_radius=8)
        pygame.draw.rect(screen, BLACK, body_rect, 2, border_radius=8)
        num = font_small.render("456", True, WHITE)
        screen.blit(num, (self.player_x - num.get_width()//2, self.player_y - 4))
        arm_y = self.player_y - 5
        pygame.draw.line(screen, color, (self.player_x-13, arm_y), (self.player_x-22, arm_y-10), 7)
        pygame.draw.line(screen, color, (self.player_x+13, arm_y), (self.player_x+22, arm_y-10), 7)

    def draw_platform(self):
        plat_rect = pygame.Rect(PLAYER_START_X-100, PLAYER_START_Y+15, 200, 30)
        pygame.draw.rect(screen, (60,60,70), plat_rect, border_radius=10)
        pygame.draw.rect(screen, WHITE, plat_rect, 3, border_radius=10)
        txt = font_small.render("START", True, WHITE)
        screen.blit(txt, (PLAYER_START_X - txt.get_width()//2, PLAYER_START_Y+18))

    def draw_ui(self):
        # 步数
        step_txt = font_step.render(f"{self.step} / {STEP_COUNT}", True, WHITE)
        screen.blit(step_txt, (WIDTH//2 - step_txt.get_width()//2, 50))
        # 提示次数
        hint_txt = font_small.render(f"Hints: {self.hints_left}  (Press H)", True, GOLD)
        screen.blit(hint_txt, (WIDTH//2 - hint_txt.get_width()//2, 120))

        if self.state == "waiting":
            hint_msg = font_small.render("Choose a glass panel", True, GOLD)
            screen.blit(hint_msg, (WIDTH//2 - hint_msg.get_width()//2, 150))
        elif self.state == "gameover":
            over_txt = font_big.render("ELIMINATED", True, RED)
            screen.blit(over_txt, (WIDTH//2 - over_txt.get_width()//2, HEIGHT//2-70))
            restart = font_small.render("Press SPACE to retry", True, WHITE)
            screen.blit(restart, (WIDTH//2 - restart.get_width()//2, HEIGHT//2+20))
        elif self.state == "win":
            win_txt = font_big.render("YOU SURVIVED!", True, GOLD)
            screen.blit(win_txt, (WIDTH//2 - win_txt.get_width()//2, HEIGHT//2-70))
            restart = font_small.render("Press SPACE to play again", True, WHITE)
            screen.blit(restart, (WIDTH//2 - restart.get_width()//2, HEIGHT//2+20))

    def run(self):
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    if self.state == "waiting":
                        mx, my = pygame.mouse.get_pos()
                        if self.mouse_on_left:
                            self.handle_choice("left")
                        elif self.mouse_on_right:
                            self.handle_choice("right")
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE and self.state in ("gameover", "win"):
                        self.reset()
                    if event.key == pygame.K_LEFT and self.state == "waiting":
                        self.handle_choice("left")
                    if event.key == pygame.K_RIGHT and self.state == "waiting":
                        self.handle_choice("right")
                    if event.key == pygame.K_h:
                        self.activate_hint()

            self.update()

            self.draw_background()
            self.draw_platform()
            self.draw_glasses()
            for shard in self.shards:
                shard.draw(screen)
            self.draw_player()
            self.draw_ui()

            pygame.display.flip()
            clock.tick(60)

        pygame.quit()
        sys.exit()

if __name__ == "__main__":
    game = GlassBridge()
    game.run()