#include <iostream>
#include <vector>
#include <cmath>

// 二维点/向量结构体
struct Vector2 {
    float x, y;
    
    Vector2(float x = 0, float y = 0) : x(x), y(y) {}
    
    // 计算两点间距离
    float Distance(const Vector2& other) const {
        float dx = x - other.x;
        float dy = y - other.y;
        return std::sqrt(dx * dx + dy * dy);
    }
};

// 受击圈类
class HitCircle {
private:
    Vector2 center;     // 圆心位置
    float radius;       // 圆半径
    float damage;       // 伤害值
    
public:
    HitCircle(const Vector2& center, float radius, float damage)
        : center(center), radius(radius), damage(damage) {}
    
    // 检测点是否在受击范围内
    bool IsPointInRange(const Vector2& point) const {
        return center.Distance(point) <= radius;
    }
    
    // 检测与其他受击圈的碰撞
    bool CheckCollision(const HitCircle& other) const {
        float distance = center.Distance(other.center);
        return distance <= (radius + other.radius);
    }
    
    // 修复受击范围（确保不会与其他受击圈重叠）
    void FixCollision(HitCircle& other) {
        Vector2 direction = Vector2(other.center.x - center.x, 
                                  other.center.y - center.y);
        float distance = center.Distance(other.center);
        
        if (distance < (radius + other.radius) && distance > 0) {
            // 计算需要移动的距离
            float overlap = (radius + other.radius) - distance;
            float moveDistance = overlap / 2.0f;
            
            // 归一化方向向量
            Vector2 normalizedDir = Vector2(direction.x / distance, 
                                          direction.y / distance);
            
            // 调整两个圆的位置
            center.x -= normalizedDir.x * moveDistance;
            center.y -= normalizedDir.y * moveDistance;
            other.center.x += normalizedDir.x * moveDistance;
            other.center.y += normalizedDir.y * moveDistance;
        }
    }
    
    // 应用伤害到目标
    void ApplyDamage(const Vector2& targetPos) const {
        if (IsPointInRange(targetPos)) {
            std::cout << "对目标位置(" << targetPos.x << ", " << targetPos.y 
                      << ") 造成 " << damage << " 点伤害" << std::endl;
        }
    }
    
    // 获取和设置方法
    Vector2 GetCenter() const { return center; }
    float GetRadius() const { return radius; }
    float GetDamage() const { return damage; }
    
    void SetCenter(const Vector2& newCenter) { center = newCenter; }
    void SetRadius(float newRadius) { radius = newRadius; }
};

// 受击圈管理器
class HitCircleManager {
private:
    std::vector<HitCircle> circles;
    
public:
    // 添加受击圈
    void AddCircle(const HitCircle& circle) {
        circles.push_back(circle);
    }
    
    // 修复所有受击圈的碰撞
    void FixAllCollisions() {
        for (size_t i = 0; i < circles.size(); ++i) {
            for (size_t j = i + 1; j < circles.size(); ++j) {
                circles[i].FixCollision(circles[j]);
            }
        }
    }
    
    // 检测并应用伤害
    void CheckAndApplyDamage(const Vector2& targetPos) {
        for (const auto& circle : circles) {
            circle.ApplyDamage(targetPos);
        }
    }
    
    // 显示所有受击圈信息
    void DisplayCircles() const {
        std::cout << "当前受击圈数量: " << circles.size() << std::endl;
        for (size_t i = 0; i < circles.size(); ++i) {
            Vector2 center = circles[i].GetCenter();
            std::cout << "受击圈 " << i << ": 位置(" << center.x << ", " 
                      << center.y << "), 半径: " << circles[i].GetRadius() 
                      << ", 伤害: " << circles[i].GetDamage() << std::endl;
        }
    }
};

// 示例使用
int main() {
    HitCircleManager manager;
    
    // 创建几个测试用的受击圈
    manager.AddCircle(HitCircle(Vector2(0, 0), 5.0f, 50.0f));
    manager.AddCircle(HitCircle(Vector2(3, 0), 4.0f, 30.0f));  // 这个会与第一个重叠
    manager.AddCircle(HitCircle(Vector2(10, 10), 3.0f, 20.0f));
    
    std::cout << "修复前的受击圈状态:" << std::endl;
    manager.DisplayCircles();
    
    // 修复碰撞
    manager.FixAllCollisions();
    
    std::cout << "\n修复后的受击圈状态:" << std::endl;
    manager.DisplayCircles();
    
    // 测试伤害应用
    std::cout << "\n测试伤害应用:" << std::endl;
    manager.CheckAndApplyDamage(Vector2(2, 1));
    manager.CheckAndApplyDamage(Vector2(10, 10));
    
    return 0;
}