# Calcul de Menace Contextuelle

## Vue d'Ensemble

Le système de calcul de menace évalue la **dangerosité qu'une entité représente pour une autre** en analysant non seulement les forces brutes, mais aussi les capacités défensives, la qualité des équipements, et la production industrielle.

### Principes Fondamentaux

- **Contextuel** : Menace calculée selon capacités **des deux parties**
- **Asymétrique** : A menace B ≠ B menace A
- **Sword & Shield** : Qualité défenses peut annuler supériorité numérique
- **Production** : Capacité industrielle = menace future
- **Multi-domaines** : Terre, air, mer évalués séparément puis agrégés

## Échelle de Menace

**Valeurs** : `0` à `2 000 000+` (pas de maximum strict, type `int32_t`)

**Ordres de grandeur** :
- `0` : Aucune menace
- `100 - 1 000` : PMC petit
- `5 000 - 50 000` : Company moyenne
- `100 000` : État petit
- `500 000` : État moyen (France, UK, Allemagne)
- `900 000` : Superpower (USA, Chine, Russie)
- `1 000 000+` : Menace existentielle

## Architecture Calcul

### Formule Globale

```cpp
int calculateThreat(Entity attacker, Entity defender) {
    auto params = attacker.getThreatParams();

    // Composantes
    int current_military = evaluateCurrentForces(attacker, defender);
    int production_capacity = evaluateProduction(attacker, defender, params.projection_months);

    // Pondération configurable par entité
    return current_military * params.current_weight +
           production_capacity * params.production_weight;
}

struct ThreatCalculationParams {
    int projection_months = 12;      // Horizon projection (défaut 12 mois)
    float current_weight = 0.6f;     // Poids forces actuelles (60%)
    float production_weight = 0.4f;  // Poids production (40%)
};
```

**Personnalisation par entité** :
- Company **agressive** : `current: 0.8, production: 0.2` (focus court-terme)
- State **prudent** : `current: 0.4, production: 0.6` (focus long-terme)
- PMC **réactif** : `current: 0.9, production: 0.1` (menace immédiate prioritaire)

## Évaluation Forces Actuelles

### Principe : Sword & Shield

Pour chaque domaine (terre, air, mer), on évalue :
1. **Sword** (attaquant) : Capacités offensives
2. **Shield** (défenseur) : Capacités défensives
3. **Effectiveness** : Dans quelle mesure le shield arrête le sword

```cpp
int evaluateCurrentForces(Entity attacker, Entity defender) {
    int land_threat = evaluateLandThreat(attacker, defender);
    int air_threat = evaluateAirThreat(attacker, defender);
    int naval_threat = evaluateNavalThreat(attacker, defender);

    return land_threat + air_threat + naval_threat;
}
```

### Évaluation Domaine Terrestre

#### Inventaire Forces

**Attaquant** :
```cpp
struct LandForces {
    std::vector<Tank> tanks;
    std::vector<IFV> ifvs;
    std::vector<APC> apcs;
    std::vector<Artillery> artillery;
    std::vector<Infantry> infantry;
};
```

**Défenseur** :
```cpp
struct LandDefenses {
    std::vector<ATSystem> anti_tank;      // Systèmes anti-char
    std::vector<Tank> counter_tanks;      // Tanks défensifs
    std::vector<Infantry> anti_tank_inf;  // Infanterie AT
    std::vector<Fortification> fortifications;
};
```

#### Couples Équipement ↔ Contre-mesures

**Principe** : Chaque type d'équipement offensif a des contre-mesures spécifiques.

```cpp
struct EquipmentCounters {
    std::map<EquipmentType, std::vector<CounterType>> counters = {
        {TANK, {AT_MISSILE, AT_GUN, COUNTER_TANK, AT_INFANTRY}},
        {IFV, {AT_MISSILE, AT_GUN, AUTOCANNON}},
        {APC, {AUTOCANNON, MACHINE_GUN, RPG}},
        {INFANTRY, {MACHINE_GUN, ARTILLERY, AUTOCANNON}},
        {ARTILLERY, {COUNTER_BATTERY, AIR_STRIKE}}
    };
};
```

#### Évaluation Sword vs Shield

**Étape 1 : Match-making**

Pour chaque équipement offensif, identifier contre-mesures défensives applicables :

```cpp
std::vector<Defense> findApplicableDefenses(
    Equipment sword,
    std::vector<Defense> available_defenses
) {
    std::vector<Defense> applicable;

    auto counters = EquipmentCounters::counters[sword.type];

    for (auto& defense : available_defenses) {
        // Vérifier si défense peut contrer cet équipement
        if (std::find(counters.begin(), counters.end(), defense.type) != counters.end()) {
            // Vérifier compatibilité génération/qualité
            if (canCounter(defense, sword)) {
                applicable.push_back(defense);
            }
        }
    }

    return applicable;
}

bool canCounter(Defense defense, Equipment sword) {
    // Exemple : AT missile Gen2 ne peut pas contrer tank Gen4 avec armure avancée
    if (defense.generation < sword.generation - 1) {
        return false;  // Trop ancien
    }

    // Vérifier spécificités
    if (sword.has_reactive_armor && defense.type == AT_MISSILE_OLD) {
        return false;  // ERA bloque missiles anciens
    }

    return true;
}
```

**Étape 2 : Calcul Defensive Effectiveness**

```cpp
float calculateDefensiveEffectiveness(
    std::vector<Equipment> swords,
    std::vector<Defense> shields
) {
    float total_sword_value = 0;
    float neutralized_value = 0;

    for (auto& sword : swords) {
        float sword_value = sword.quantity * sword.quality;
        total_sword_value += sword_value;

        // Trouver défenses applicables
        auto applicable_shields = findApplicableDefenses(sword, shields);

        // Calculer valeur défensive totale contre ce sword
        float shield_value = 0;
        for (auto& shield : applicable_shields) {
            float shield_effectiveness = calculateShieldEffectiveness(shield, sword);
            shield_value += shield.quantity * shield.quality * shield_effectiveness;
        }

        // Neutralisation proportionnelle
        float neutralization = min(1.0f, shield_value / sword_value);
        neutralized_value += sword_value * neutralization;
    }

    return total_sword_value > 0 ? (neutralized_value / total_sword_value) : 0.0f;
}
```

**Étape 3 : Score Final**

```cpp
int evaluateLandThreat(Entity attacker, Entity defender) {
    auto swords = attacker.getLandForces();
    auto shields = defender.getLandDefenses();

    // Menace brute (sans défenses)
    int raw_threat = 0;
    for (auto& sword : swords) {
        raw_threat += sword.quantity * sword.combat_value;
    }

    // Réduction par défenses
    float defensive_effectiveness = calculateDefensiveEffectiveness(swords, shields);

    // Menace finale
    int final_threat = raw_threat * (1.0f - defensive_effectiveness);

    return final_threat;
}
```

### Exemples Concrets Terre

#### Exemple 1 : Qualité Domine Quantité

**Attaquant** :
- 20 tanks Gen4 (Leopard 2A7)
  - Armure composite avancée
  - Génération 4
  - Combat value : 1000/tank
  - Menace brute : 20 × 1000 = 20 000

**Défenseur** :
- 100 000 AT missiles Gen2
  - Anciens, inefficaces contre armure Gen4
  - `canCounter()` retourne `false`
  - Défense applicable : 0

**Résultat** :
```
defensive_effectiveness = 0 / 20000 = 0%
final_threat = 20000 × (1 - 0) = 20 000
```
→ **Menace élevée** : Défenses obsolètes inefficaces

#### Exemple 2 : Quantité + Qualité Écrasent

**Attaquant** :
- 1000 tanks Gen2
  - Armure standard
  - Combat value : 400/tank
  - Menace brute : 1000 × 400 = 400 000

**Défenseur** :
- 500 AT missiles Gen4 (Javelin)
  - Top-attack, très efficaces
  - Combat value : 800/missile
  - `canCounter()` retourne `true`
  - Shield effectiveness : 0.9 (très efficace)
  - Shield value : 500 × 800 × 0.9 = 360 000

**Résultat** :
```
defensive_effectiveness = 360000 / 400000 = 90%
final_threat = 400000 × (1 - 0.9) = 40 000
```
→ **Menace faible** : Défenses qualitatives réduisent massavement

#### Exemple 3 : Masse Insuffisante

**Attaquant** :
- 1000 tanks Gen2
  - Combat value : 400/tank
  - Menace brute : 400 000

**Défenseur** :
- 20 AT missiles Gen4
  - Très efficaces mais **pas assez nombreux**
  - Shield value : 20 × 800 × 0.9 = 14 400

**Résultat** :
```
defensive_effectiveness = 14400 / 400000 = 3.6%
final_threat = 400000 × (1 - 0.036) = 385 440
```
→ **Menace reste élevée** : Pas assez de défenses pour couvrir la masse

### Évaluation Domaine Aérien

#### Spécificités Air

**Complexité supplémentaire** :
- **Qualité prime** : Quelques jets furtifs Gen4 dominent des centaines AA Gen2
- **ECM/ECCM** : Guerre électronique critique
- **Compatibilité stricte** : AA anti-hélicoptère ne touche pas jets

```cpp
struct AirForces {
    std::vector<Fighter> fighters;
    std::vector<Bomber> bombers;
    std::vector<Helicopter> helicopters;
    std::vector<Drone> drones;

    // Capacités spéciales
    bool has_stealth;
    bool has_ecm;           // Electronic Counter-Measures
    int electronic_warfare_level;
};

struct AirDefenses {
    std::vector<AAMissile> aa_missiles;
    std::vector<AAGun> aa_guns;
    std::vector<Fighter> interceptors;

    // Capacités
    bool has_eccm;          // Electronic Counter-Counter-Measures
    int radar_quality;
    std::map<AASystem, TargetCapability> capabilities;  // Quoi peut toucher quoi
};

enum TargetCapability {
    HELICOPTER_ONLY,        // Seulement hélicoptères
    LOW_ALTITUDE,           // Avions basse altitude
    HIGH_ALTITUDE,          // Avions haute altitude
    ALL_AIRCRAFT            // Tous types
};
```

#### Compatibilité Systèmes

```cpp
bool canEngageAircraft(AASystem aa, Aircraft aircraft) {
    // Vérifier compatibilité type
    switch (aa.capability) {
        case HELICOPTER_ONLY:
            return aircraft.type == HELICOPTER;

        case LOW_ALTITUDE:
            return aircraft.altitude < 5000;  // mètres

        case HIGH_ALTITUDE:
            return aircraft.altitude > 5000;

        case ALL_AIRCRAFT:
            return true;
    }

    // Vérifier guerre électronique
    if (aircraft.has_ecm && !aa.has_eccm) {
        // ECM peut brouiller AA sans ECCM
        float jam_probability = aircraft.ecm_power / (aa.radar_quality + 1);
        if (randomFloat() < jam_probability) {
            return false;  // Brouillé
        }
    }

    // Vérifier furtivité
    if (aircraft.has_stealth) {
        float detection_range = aa.radar_range * (1.0f - aircraft.stealth_rating);
        if (distance(aa, aircraft) > detection_range) {
            return false;  // Pas détecté
        }
    }

    return true;
}
```

#### Exemple Air : Furtivité Domine

**Attaquant** :
- 20 jets furtifs Gen4 (F-35)
  - Stealth rating : 0.9 (réduit détection 90%)
  - ECM avancé
  - Combat value : 2000/jet
  - Menace brute : 40 000

**Défenseur** :
- 100 000 AA missiles Gen2
  - Radar standard
  - Pas ECCM
  - Seulement 5% peuvent détecter/engager les furtifs
  - Shield value effectif : 100000 × 0.05 × 300 = 1 500 000... mais avec ECM :
  - Shield value final : 1 500 000 × 0.1 (jam rate) = 150 000

```
defensive_effectiveness = 150000 / 40000 = ... wait, > 1.0 !
→ Plafonné à min(1.0, value)
defensive_effectiveness = min(1.0, 150000/40000) = 1.0...

ERREUR dans mon calcul !
```

**Correction** : Le shield value doit être calculé par aircraft, pas globalement.

```cpp
// Pour chaque jet
for (auto& jet : jets) {
    float jet_value = jet.combat_value;

    // Combien de AA peuvent l'engager ?
    int applicable_aa = 0;
    for (auto& aa : aa_systems) {
        if (canEngageAircraft(aa, jet)) {
            applicable_aa++;
        }
    }

    // Shield value pour ce jet spécifique
    float shield_value = applicable_aa * aa_combat_value;
    float neutralization = min(1.0f, shield_value / jet_value);

    threat_reduced += jet_value * neutralization;
}
```

**Résultat corrigé** :
- 5000 AA peuvent engager (sur 100k)
- Pour 1 jet : shield = 5000 × 300 = 1 500 000 vs jet = 2000
- Neutralization = 100% par jet
- Mais ils peuvent pas tous tirer simultanément !

**Contrainte simultanéité** :

```cpp
// Limite engagement simultané
int max_simultaneous = min(applicable_aa, ENGAGEMENT_LIMIT);
// Exemple : Max 100 missiles simultanés par cible

float shield_value = max_simultaneous * aa_combat_value;
```

Avec limite 100 simultanés :
- Shield = 100 × 300 = 30 000 vs jet = 2000
- Neutralization = 100% par jet
- Mais 20 jets → seulement 2000 engagements simultanés total
- Si AA rate coordination : menace reste

**C'est complexe !** Donc en pratique :

```cpp
float calculateAirDefenseEffectiveness(
    std::vector<Aircraft> aircraft,
    std::vector<AASystem> aa_systems
) {
    float total_threat = 0;
    float neutralized = 0;

    for (auto& ac : aircraft) {
        total_threat += ac.combat_value;

        // Compter AA applicables
        int applicable_count = 0;
        for (auto& aa : aa_systems) {
            if (canEngageAircraft(aa, ac)) {
                applicable_count++;
            }
        }

        // Engagement limité
        int engaged = min(applicable_count, MAX_SIMULTANEOUS_PER_TARGET);

        // Probabilité kill
        float kill_probability = engaged / float(ENGAGEMENTS_NEEDED_FOR_KILL);
        kill_probability = min(1.0f, kill_probability);

        neutralized += ac.combat_value * kill_probability;
    }

    return total_threat > 0 ? (neutralized / total_threat) : 0.0f;
}
```

### Évaluation Domaine Naval

**Similaire à terrestre/aérien** mais avec spécificités :
- **Torpilles vs sonars** (submersibles)
- **Anti-ship missiles vs CIWS** (Close-In Weapon Systems)
- **Portée extrême** : Naval combat à 100+ km

Structure identique avec couples spécifiques.

## Évaluation Production

### Principe

La menace ne vient pas seulement des forces actuelles, mais aussi de la **capacité à produire** plus d'équipements.

```cpp
int evaluateProduction(Entity attacker, Entity defender, int projection_months) {
    int production_threat = 0;

    // Pour chaque type d'équipement
    for (auto& equipment_type : all_equipment_types) {
        // Taux production attaquant
        int attacker_rate = attacker.getProductionRate(equipment_type);  // unités/mois

        // Taux production défenses défenseur
        int defender_rate = defender.getProductionRate(getCounterType(equipment_type));

        // Projection future
        int attacker_produced = attacker_rate * projection_months;
        int defender_produced = defender_rate * projection_months;

        // Menace nette production
        int net_production = attacker_produced - defender_produced;
        if (net_production > 0) {
            int equipment_value = getEquipmentValue(equipment_type);
            production_threat += net_production * equipment_value;
        }
    }

    return production_threat;
}
```

### Exemple Production

**État A** :
- Production actuelle : 50 tanks/mois
- Projection 12 mois : 600 tanks
- Combat value : 400/tank
- Production threat : 600 × 400 = 240 000

**État B** (défenseur) :
- Production AT : 100 missiles/mois
- Projection 12 mois : 1200 missiles
- Combat value : 300/missile
- Défense production : 1200 × 300 = 360 000

**Net production threat** :
```
Attacker gain : 240 000
Defender gain : 360 000
Net : 240 000 - 360 000 = -120 000 (négatif = défenseur gagne)

production_threat = max(0, net) = 0
```

→ État B a **meilleure production**, donc menace production de A est nulle.

**Si inverse** :

**État A** :
- Production : 200 tanks/mois → 2400 tanks/an
- Threat : 2400 × 400 = 960 000

**État B** :
- Production AT : 50 missiles/mois → 600 missiles/an
- Défense : 600 × 300 = 180 000

**Net** : 960 000 - 180 000 = 780 000

→ État A a **production écrasante**, menace industrielle massive.

## Agrégation Finale

### Formule Complète

```cpp
int calculateThreat(Entity attacker, Entity defender) {
    auto params = attacker.getThreatParams();

    // Forces actuelles (sword & shield par domaine)
    int land_threat = evaluateLandThreat(attacker, defender);
    int air_threat = evaluateAirThreat(attacker, defender);
    int naval_threat = evaluateNavalThreat(attacker, defender);

    int current_military = land_threat + air_threat + naval_threat;

    // Production future
    int production_threat = evaluateProduction(
        attacker,
        defender,
        params.projection_months
    );

    // Pondération finale
    int total_threat = current_military * params.current_weight +
                       production_threat * params.production_weight;

    return total_threat;
}
```

### Exemples Complets

#### Superpower vs État Moyen

**USA vs France**

**USA forces** :
- Tanks : 8000 (Gen3-4) → 3 200 000
- Aircraft : 2000 (Gen4, furtifs) → 4 000 000
- Naval : 500 ships → 2 500 000
- **Total brut** : 9 700 000

**France défenses** :
- AT systems : 3000 (Gen3) → Shield 50% tanks
- AA systems : 1500 (Gen3) → Shield 30% aircraft
- Naval defenses : 200 → Shield 40% naval

**Après sword & shield** :
- Land : 3 200 000 × 0.5 = 1 600 000
- Air : 4 000 000 × 0.7 = 2 800 000
- Naval : 2 500 000 × 0.6 = 1 500 000
- **Current threat** : 5 900 000

**Production (12 mois)** :
- USA : +600 tanks, +100 aircraft → 360 000
- France : +100 tanks, +50 aircraft → 70 000
- **Net production** : 290 000

**Total (60% current, 40% prod)** :
```
5 900 000 × 0.6 + 290 000 × 0.4 = 3 656 000
```

→ **Menace colossale**, mais France peut tenir avec alliances

#### PMC vs Company

**PMC_Alpha vs RheinmetallCorp**

**PMC forces** :
- Infantry : 500 (léger armement)
- Vehicles : 20 APCs
- **Total** : 50 000

**Rheinmetall défenses** :
- Security : 100 guards
- Fortifications : minimal
- **Shield** : 5%

**Threat** : 50 000 × 0.95 = 47 500

→ PMC peut menacer installations Company, mais pas capacités production

## Cas Spéciaux

### Menace Économique Pure

Pour Companies sans capacités militaires :

```cpp
int calculateEconomicThreat(Company attacker, Company defender) {
    // Part de marché
    float market_dominance = attacker.market_share / (defender.market_share + 0.01f);

    // Capacité production
    float production_ratio = attacker.production_capacity / defender.production_capacity;

    // Qualité produits
    float quality_advantage = attacker.avg_product_quality / defender.avg_product_quality;

    // Menace économique
    int economic_threat = (market_dominance * 100000) +
                          (production_ratio * 80000) +
                          (quality_advantage * 50000);

    return economic_threat;
}
```

### Menace Géographique

Distance géographique module menace :

```cpp
float getGeographicModifier(Entity attacker, Entity defender) {
    float distance_km = calculateDistance(attacker.position, defender.position);

    // Projection power diminue avec distance
    if (distance_km < 500) {
        return 1.0f;  // Menace pleine
    }
    else if (distance_km < 2000) {
        return 0.7f;  // 30% réduction
    }
    else if (distance_km < 5000) {
        return 0.4f;  // 60% réduction
    }
    else {
        return 0.1f;  // 90% réduction (trop loin)
    }
}
```

## Performance et Optimisation

### Cache Threat

```cpp
class ThreatCache {
private:
    struct CachedThreat {
        int value;
        int timestamp;
        int ttl = 3600;  // 1 heure
    };

    std::map<std::pair<EntityId, EntityId>, CachedThreat> cache;

public:
    int getThreat(EntityId attacker, EntityId defender) {
        auto key = std::make_pair(attacker, defender);

        if (cache.contains(key)) {
            auto& cached = cache[key];
            if (getCurrentTime() - cached.timestamp < cached.ttl) {
                return cached.value;
            }
        }

        // Recalculer
        int threat = calculateThreat(attacker, defender);
        cache[key] = {threat, getCurrentTime()};
        return threat;
    }

    void invalidate(EntityId entity) {
        // Invalider tous les caches impliquant cette entité
        for (auto it = cache.begin(); it != cache.end();) {
            if (it->first.first == entity || it->first.second == entity) {
                it = cache.erase(it);
            } else {
                ++it;
            }
        }
    }
};
```

### Invalidation Cache

Événements invalidant cache :
- Production nouvelle unité
- Perte unité au combat
- Nouvelle recherche technologique
- Changement doctrine militaire

### Calcul Lazy

```cpp
// Ne calculer que si demandé par IA
int getThreatOnDemand(EntityId attacker, EntityId defender) {
    return threatCache.getThreat(attacker, defender);
}

// Pas de recalcul automatique chaque tick
```

## Références Croisées

- `systeme-diplomatique.md` : Utilisation menace dans relations diplomatiques
- `ai-framework.md` : Menace influence décisions IA (achats, alliances)
- `systeme-militaire.md` : Valeurs combat équipements, générations
- `economie-logistique.md` : Production rates, capacités industrielles
