import pygame
import sys
import math
import random

# 初始化 Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 900, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("🎯 飞镖模拟器")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
DARK_RED = (180, 0, 0)
GREEN = (0, 200, 0)
DARK_GREEN = (0, 150, 0)
BLUE = (50, 50, 255)
GOLD = (255, 215, 0)
GRAY = (150, 150, 150)
DARK_GRAY = (80, 80, 80)
BROWN = (139, 69, 19)
LIGHT_BROWN = (200, 150, 100)
YELLOW = (255, 255, 0)
ORANGE = (255, 165, 0)

# 帧率控制
clock = pygame.time.Clock()
FPS = 60

# 中文字体
def get_chinese_font(size):
    font_names = ["SimHei", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei"]
    for name in font_names:
        try:
            return pygame.font.SysFont(name, size)
        except:
            continue
    return pygame.font.Font(None, size)

font = get_chinese_font(28)
small_font = get_chinese_font(20)

# 飞镖类
class Dart:
    def __init__(self, x, y, target_x, target_y, power):
        self.x = x
        self.y = y
        self.target_x = target_x
        self.target_y = target_y
        self.power = power
        self.speed = 8 + power * 2
        self.dx = 0
        self.dy = 0
        self.trail = []
        self.active = True
        self.score = 0
        self.landed = False
        
        # 计算飞行方向
        dx = target_x - x
        dy = target_y - y
        distance = math.hypot(dx, dy)
        if distance > 0:
            self.dx = (dx / distance) * self.speed
            self.dy = (dy / distance) * self.speed
        
        # 随机微小偏移（模拟手抖）
        self.dx += random.uniform(-0.5, 0.5)
        self.dy += random.uniform(-0.5, 0.5)
    
    def update(self, target_x, target_y):
        if not self.active:
            return
        
        # 记录轨迹
        self.trail.append((self.x, self.y))
        if len(self.trail) > 15:
            self.trail.pop(0)
        
        # 移动
        self.x += self.dx
        self.y += self.dy
        
        # 空气阻力（减速）
        self.dx *= 0.998
        self.dy *= 0.998
        
        # 重力影响
        self.dy += 0.08
        
        # 检查是否到达目标区域
        distance = math.hypot(self.x - target_x, self.y - target_y)
        if distance < 15 or self.x < 0 or self.x > WIDTH or self.y > HEIGHT:
            self.active = False
            self.landed = True
            # 计算得分
            self.score = calculate_score(self.x, self.y, target_x, target_y)
    
    def draw(self, surface):
        # 绘制轨迹
        for i, pos in enumerate(self.trail):
            alpha = int(255 * (i / len(self.trail)))
            color = (200, 100, 100, alpha)
            pygame.draw.circle(surface, (200, 100, 100), (int(pos[0]), int(pos[1])), 2)
        
        if not self.active:
            # 已着地的飞镖
            pygame.draw.circle(surface, DARK_GRAY, (int(self.x), int(self.y)), 5)
            pygame.draw.line(surface, DARK_GRAY, 
                           (int(self.x - 8), int(self.y - 8)),
                           (int(self.x + 8), int(self.y + 8)), 2)
            pygame.draw.line(surface, DARK_GRAY,
                           (int(self.x + 8), int(self.y - 8)),
                           (int(self.x - 8), int(self.y + 8)), 2)
            return
        
        # 飞行中的飞镖
        # 镖身
        angle = math.atan2(self.dy, self.dx)
        # 镖头
        tip_x = self.x + 15 * math.cos(angle)
        tip_y = self.y + 15 * math.sin(angle)
        # 镖尾
        tail_x = self.x - 10 * math.cos(angle)
        tail_y = self.y - 10 * math.sin(angle)
        
        pygame.draw.line(surface, DARK_GRAY, (tail_x, tail_y), (tip_x, tip_y), 4)
        pygame.draw.circle(surface, DARK_GRAY, (int(self.x), int(self.y)), 4)
        # 镖翼
        wing1_x = self.x - 6 * math.cos(angle + math.pi/4)
        wing1_y = self.y - 6 * math.sin(angle + math.pi/4)
        wing2_x = self.x - 6 * math.cos(angle - math.pi/4)
        wing2_y = self.y - 6 * math.sin(angle - math.pi/4)
        pygame.draw.line(surface, RED, (tail_x, tail_y), (wing1_x, wing1_y), 2)
        pygame.draw.line(surface, RED, (tail_x, tail_y), (wing2_x, wing2_y), 2)

# 计算得分
def calculate_score(x, y, center_x, center_y):
    distance = math.hypot(x - center_x, y - center_y)
    if distance <= 20:
        return 10  # 靶心
    elif distance <= 40:
        return 8
    elif distance <= 60:
        return 6
    elif distance <= 80:
        return 4
    elif distance <= 100:
        return 2
    elif distance <= 130:
        return 1
    else:
        return 0

# 绘制靶子
def draw_target(surface, center_x, center_y):
    # 外靶
    rings = [
        (130, GRAY, 1),
        (100, BLUE, 2),
        (80, RED, 4),
        (60, GREEN, 6),
        (40, YELLOW, 8),
        (20, DARK_RED, 10),
    ]
    
    for radius, color, score in rings:
        pygame.draw.circle(surface, color, (center_x, center_y), radius, 2 if radius > 40 else 0)
        if radius > 40:
            pygame.draw.circle(surface, color, (center_x, center_y), radius, 2)
        else:
            pygame.draw.circle(surface, color, (center_x, center_y), radius)
    
    # 靶心
    pygame.draw.circle(surface, DARK_RED, (center_x, center_y), 20)
    pygame.draw.circle(surface, RED, (center_x, center_y), 10)
    
    # 十字线
    pygame.draw.line(surface, BLACK, (center_x - 130, center_y), (center_x + 130, center_y), 1)
    pygame.draw.line(surface, BLACK, (center_x, center_y - 130), (center_x, center_y + 130), 1)
    
    # 分数标签
    score_labels = [
        (20, "10"),
        (40, "8"),
        (60, "6"),
        (80, "4"),
        (100, "2"),
        (130, "1"),
    ]
    for radius, label in score_labels:
        text = small_font.render(label, True, BLACK)
        surface.blit(text, (center_x + radius + 5, center_y - 10))

# 绘制力量条
def draw_power_bar(surface, power, max_power):
    bar_x, bar_y = 20, HEIGHT - 150
    bar_width, bar_height = 30, 120
    
    # 背景
    pygame.draw.rect(surface, DARK_GRAY, (bar_x, bar_y, bar_width, bar_height))
    pygame.draw.rect(surface, BLACK, (bar_x, bar_y, bar_width, bar_height), 2)
    
    # 力量填充
    fill_height = (power / max_power) * bar_height
    color = GREEN
    if power / max_power > 0.6:
        color = ORANGE
    if power / max_power > 0.8:
        color = RED
    
    pygame.draw.rect(surface, color, 
                    (bar_x + 2, bar_y + bar_height - fill_height + 2, 
                     bar_width - 4, fill_height - 4))
    
    # 文字
    power_text = font.render(f"{int(power)}%", True, BLACK)
    surface.blit(power_text, (bar_x - 5, bar_y - 35))
    
    label = small_font.render("力量", True, BLACK)
    surface.blit(label, (bar_x + 2, bar_y - 60))

# 主游戏类
class DartGame:
    def __init__(self):
        self.target_x = WIDTH // 2 + 50
        self.target_y = HEIGHT // 2 - 30
        self.darts = []
        self.score = 0
        self.dart_count = 0
        self.max_darts = 5
        self.power = 0
        self.charging = False
        self.game_over = False
        self.message = ""
        self.message_timer = 0
        self.round_score = 0
        self.throws = []
        
        # 瞄准线
        self.aim_x = WIDTH // 2
        self.aim_y = HEIGHT // 2
    
    def update(self, keys, mouse_pos):
        if self.game_over:
            return
        
        # 更新瞄准位置
        self.aim_x, self.aim_y = mouse_pos
        
        # 蓄力
        if keys[pygame.K_SPACE] or pygame.mouse.get_pressed()[0]:
            if not self.charging and self.dart_count < self.max_darts:
                self.charging = True
            if self.charging:
                self.power = min(self.power + 1.5, 100)
        else:
            if self.charging and self.power > 5:
                # 投掷飞镖
                self.throw_dart()
            self.charging = False
            self.power = 0
        
        # 重置游戏
        if keys[pygame.K_r]:
            self.reset()
        
        # 更新飞镖
        for dart in self.darts:
            dart.update(self.target_x, self.target_y)
    
    def throw_dart(self):
        start_x = 80
        start_y = HEIGHT - 80
        
        dart = Dart(start_x, start_y, self.aim_x, self.aim_y, self.power / 50)
        self.darts.append(dart)
        self.dart_count += 1
        
        if self.dart_count >= self.max_darts:
            self.game_over = True
            self.calculate_total_score()
    
    def calculate_total_score(self):
        total = 0
        for dart in self.darts:
            total += dart.score
        self.score = total
        
        # 评级
        if total >= 40:
            self.message = "🏆 完美！飞镖大师！"
        elif total >= 30:
            self.message = "🌟 优秀！"
        elif total >= 20:
            self.message = "👍 不错！"
        elif total >= 10:
            self.message = "💪 继续练习！"
        else:
            self.message = "😅 再试一次！"
        self.message_timer = 180
    
    def reset(self):
        self.darts = []
        self.score = 0
        self.dart_count = 0
        self.power = 0
        self.charging = False
        self.game_over = False
        self.message = ""
        self.message_timer = 0
    
    def draw(self, surface):
        # 绘制背景
        surface.fill(WHITE)
        
        # 绘制墙面纹理（简单装饰）
        for i in range(0, WIDTH, 40):
            for j in range(0, HEIGHT, 40):
                if (i // 40 + j // 40) % 2 == 0:
                    pygame.draw.rect(surface, (245, 240, 235), (i, j, 40, 40))
        
        # 绘制靶子
        draw_target(surface, self.target_x, self.target_y)
        
        # 绘制瞄准线（如果不在蓄力状态）
        if not self.charging and self.dart_count < self.max_darts:
            pygame.draw.line(surface, (255, 0, 0, 100), 
                           (80, HEIGHT - 80), 
                           (self.aim_x, self.aim_y), 1)
            # 瞄准点
            pygame.draw.circle(surface, RED, (self.aim_x, self.aim_y), 4, 1)
        
        # 绘制飞镖
        for dart in self.darts:
            dart.draw(surface)
        
        # 绘制力量条
        if self.charging or self.power > 0:
            draw_power_bar(surface, self.power, 100)
        
        # 绘制UI信息
        info_y = 20
        # 得分
        score_text = font.render(f"得分: {self.score}", True, BLACK)
        surface.blit(score_text, (20, info_y))
        
        # 剩余飞镖
        darts_left = self.max_darts - self.dart_count
        darts_text = font.render(f"剩余: {darts_left} 支", True, BLACK)
        surface.blit(darts_text, (20, info_y + 40))
        
        # 当前飞镖得分
        if self.darts and self.darts[-1].landed:
            last_score = self.darts[-1].score
            score_color = RED if last_score >= 8 else BLACK
            last_text = font.render(f"上次: {last_score}分", True, score_color)
            surface.blit(last_text, (20, info_y + 80))
        
        # 操作提示
        if not self.game_over:
            if self.dart_count < self.max_darts:
                if not self.charging:
                    hint = small_font.render("按住 空格/鼠标左键 蓄力，松开投掷 | R键重置", True, DARK_GRAY)
                else:
                    hint = small_font.render(f"蓄力中... {int(self.power)}%", True, ORANGE)
                surface.blit(hint, (20, HEIGHT - 40))
            else:
                hint = small_font.render("按 R 键重新开始", True, DARK_GRAY)
                surface.blit(hint, (20, HEIGHT - 40))
        
        # 显示结束消息
        if self.game_over and self.message:
            # 半透明背景
            overlay = pygame.Surface((WIDTH, 80))
            overlay.set_alpha(200)
            overlay.fill(WHITE)
            surface.blit(overlay, (0, HEIGHT // 2 - 40))
            
            msg = font.render(self.message, True, RED)
            msg_rect = msg.get_rect(center=(WIDTH // 2, HEIGHT // 2))
            surface.blit(msg, msg_rect)
            
            score_msg = font.render(f"总分: {self.score}", True, BLACK)
            score_rect = score_msg.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 50))
            surface.blit(score_msg, score_rect)
        
        # 显示每个飞镖的得分
        for i, dart in enumerate(self.darts):
            if dart.landed and dart.score > 0:
                text = small_font.render(str(dart.score), True, RED)
                surface.blit(text, (dart.x + 10, dart.y - 10))
        
        # 标题
        title = get_chinese_font(36).render("🎯 飞镖模拟器", True, DARK_GRAY)
        surface.blit(title, (WIDTH // 2 - 100, 10))

# 创建游戏实例
game = DartGame()

# 主循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:
                game.reset()
    
    # 获取输入
    keys = pygame.key.get_pressed()
    mouse_pos = pygame.mouse.get_pos()
    
    # 更新游戏
    game.update(keys, mouse_pos)
    
    # 绘制
    game.draw(screen)
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
sys.exit()