# 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 réduit menace, jamais totalement - **Baseline 20%** : Toute arme reste dangereuse à minimum 20% effectiveness - **Production** : Capacité industrielle = menace future - **Multi-domaines** : Terre, air, mer évalués séparément puis agrégés - **Perte coûteuse** : Perdre unité chère = désastre stratégique même avec victoire ### Distinction Menace vs Victoire Tactique **CRITIQUE** : La menace mesure la **capacité de nuisance stratégique**, pas l'issue du combat tactique. **Exemple** : 20 tanks modernes peuvent être détruits par saturation, MAIS avant destruction ils peuvent : - Percer défenses et atteindre objectifs profonds - Détruire infrastructure critique (QG, dépôts, ponts) - Infliger pertes massives - Forcer mobilisation coûteuse → Menace élevée même si tanks finalement détruits → Perte d'un Leopard 2A7 (8M€) = toujours désastre stratégique ## É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 avec Effectiveness Float Pour chaque domaine (terre, air, mer), on évalue : 1. **Sword** (attaquant) : Capacités offensives 2. **Shield** (défenseur) : Capacités défensives 3. **Effectiveness** : Ratio pénétration/armure avec baseline 20% minimum ```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; } ``` ## Système Armor vs Penetration ### Référence de Base Chaque équipement possède des valeurs mesurables : ```cpp struct Tank { float armor_average; // Moyenne armure (mm RHA equivalent) int combat_value; // Valeur au combat int quantity; // Exemple Leopard 2A7: // - Frontal: 950mm RHA // - Flancs: 200mm RHA // - Arrière: 100mm RHA // - Average (pondéré surface): ~400mm }; struct ATWeapon { float penetration; // Pénétration max (mm RHA) int combat_value; int quantity; // Exemples: // - RPG-7: 260mm // - Milan Gen2: 530mm // - Javelin Gen3 (top-attack): 800mm // - Kornet Gen4+ (tandem): 1200mm }; ``` ### Calcul Effectiveness (Float) **Formule baseline 20%** : Toute arme reste dangereuse (flancs, arrière, chance) ```cpp float calculateCounterEffectiveness(ATWeapon weapon, Tank tank) { float pen_ratio = weapon.penetration / tank.armor_average; // BASELINE 20% : TOUJOURS dangereux const float BASE_EFFECTIVENESS = 0.20f; if (pen_ratio >= 1.0f) { // Arme peut percer : scaling jusqu'à 90% max float bonus = (pen_ratio - 1.0f) * 0.5f; return min(0.90f, BASE_EFFECTIVENESS + bonus); } else { // Arme sous-dimensionnée : reste à 20% (flancs, arrière, chance) return BASE_EFFECTIVENESS; } } ``` ### Exemples Effectiveness ```cpp // Leopard 2A7 (armor_avg = 400mm) vs différentes armes RPG-7 (260mm) : pen_ratio = 260 / 400 = 0.65 effectiveness = 20% → 100 RPG-7 needed = 20 "équivalents kill" → Coût: 100 × 500€ = 50k€ vs Leopard 8M€ = 0.625% ratio → Menace présente mais faible, économiquement viable en masse Milan Gen2 (530mm) : pen_ratio = 530 / 400 = 1.325 effectiveness = 20% + (0.325 × 0.5) = 36.25% → ~3 missiles = 1 kill probable → Menace sérieuse Javelin Gen3 (800mm top-attack) : pen_ratio = 800 / 400 = 2.0 effectiveness = 20% + (1.0 × 0.5) = 70% → ~1.5 missiles = 1 kill probable → Menace très élevée Kornet Gen4+ (1200mm tandem) : pen_ratio = 1200 / 400 = 3.0 effectiveness = 20% + (2.0 × 0.5) = 90% (plafonné) → ~1.1 missiles = 1 kill quasi-certain → Menace maximale ``` ## Évaluation Domaine Terrestre ### Inventaire Forces **Attaquant** : ```cpp struct LandForces { std::vector tanks; std::vector ifvs; std::vector apcs; std::vector artillery; std::vector infantry; }; ``` **Défenseur** : ```cpp struct LandDefenses { std::vector anti_tank; // Systèmes anti-char std::vector counter_tanks; // Tanks défensifs std::vector anti_tank_inf; // Infanterie AT std::vector fortifications; }; ``` ### Couples Équipement ↔ Contre-mesures **Principe** : Chaque type d'équipement offensif a des contre-mesures spécifiques. ```cpp struct EquipmentCounters { std::map> 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}} }; }; ``` ### Calcul Defensive Effectiveness ```cpp float calculateDefensiveEffectiveness( std::vector swords, std::vector shields ) { float total_sword_value = 0; float neutralized_value = 0; for (auto& sword : swords) { float sword_value = sword.quantity * sword.combat_value; 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) { // ✅ EFFECTIVENESS FLOAT (20%-90%) float effectiveness = calculateCounterEffectiveness(shield, sword); shield_value += shield.quantity * shield.combat_value * 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; } ``` ### Score Final avec Menace Résiduelle ```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 RÉSIDUELLE : Jamais totalement nulle si attaquant existe float residual_multiplier = max(0.05f, 1.0f - defensive_effectiveness); int final_threat = raw_threat * residual_multiplier; return final_threat; } ``` ## Exemples Concrets Terre ### Exemple 1 : Tech Obsolète Viable en Masse **Attaquant** : - 20 tanks Gen4 (Leopard 2A7) - armor_average : 400mm RHA - combat_value : 1000/tank - Menace brute : 20 000 - Valeur totale : 20 × 8M€ = 160M€ **Défenseur** : - 5000 RPG-7 (Gen1, ancien) - penetration : 260mm - pen_ratio : 260/400 = 0.65 - effectiveness : 20% (baseline) - combat_value : 50/RPG - shield_value : 5000 × 50 × 0.20 = 50 000 - Coût : 5000 × 500€ = 2.5M€ **Résultat** : ``` defensive_effectiveness = min(1.0, 50000 / 20000) = 100% residual_multiplier = max(0.05, 1.0 - 1.0) = 5% final_threat = 20000 × 0.05 = 1 000 → Menace quasi-neutralisée (5% résiduel) → Nécessite 5000 RPG-7 (masse logistique) → Ratio coût défenseur/attaquant = 2.5M€ / 160M€ = 1.56% → Défense économiquement viable ✅ → MAIS perte Leopard reste désastre (8M€ + prestige + formation) ``` ### Exemple 2 : Tech Moderne Efficace **Attaquant** : - 20 tanks Gen4 (Leopard 2A7) - armor_average : 400mm - Menace brute : 20 000 **Défenseur** : - 100 missiles Javelin Gen3 - penetration : 800mm (top-attack) - pen_ratio : 800/400 = 2.0 - effectiveness : 70% - combat_value : 300/missile - shield_value : 100 × 300 × 0.70 = 21 000 - Coût : 100 × 200k€ = 20M€ **Résultat** : ``` defensive_effectiveness = min(1.0, 21000 / 20000) = 100% residual_multiplier = 5% final_threat = 20000 × 0.05 = 1 000 → Menace quasi-neutralisée → Ratio coût : 20M€ / 160M€ = 12.5% → Plus cher que RPG-7 mais logistique simplifiée (100 vs 5000) ``` ### Exemple 3 : Défense Insuffisante **Attaquant** : - 20 tanks Gen4 - Menace brute : 20 000 **Défenseur** : - 500 RPG-7 - effectiveness : 20% - shield_value : 500 × 50 × 0.20 = 5 000 **Résultat** : ``` defensive_effectiveness = 5000 / 20000 = 25% residual_multiplier = max(0.05, 0.75) = 75% final_threat = 20000 × 0.75 = 15 000 → Menace reste élevée (75%) → Défense insuffisante ``` ### Exemple 4 : Défense Mixte Économique **Attaquant** : - 20 tanks Gen4 - Menace brute : 20 000 **Défenseur** : - 30 Javelin Gen3 : shield = 30 × 300 × 0.70 = 6 300 - 1000 RPG-7 : shield = 1000 × 50 × 0.20 = 10 000 - **Shield total** : 16 300 - **Coût total** : 30 × 200k€ + 1000 × 500€ = 6.5M€ **Résultat** : ``` defensive_effectiveness = 16300 / 20000 = 81.5% residual_multiplier = max(0.05, 0.185) = 18.5% final_threat = 20000 × 0.185 = 3 700 → Menace réduite à 18.5% (acceptable) → Défense mixte optimise coût-efficacité → Ratio coût : 6.5M€ / 160M€ = 4.06% ``` ### Exemple 5 : Système de Conception Modulaire - Retrofit Anti-AT **Attaquant** : - 20 tanks Leopard 2A7 **retrofittés Gen5** - Chassis Gen4 base - **APS Trophy Gen5** : intercepte 80% missiles avant impact - **ERA Gen5** : neutralise pénétration Gen2-3 - armor_effective : 400mm × 2.5 (ERA bonus) = 1000mm equivalent - Menace brute : 20 000 **Défenseur** : - 1000 missiles Milan Gen2 - penetration : 530mm - pen_ratio : 530/1000 = 0.53 (sous-dimensionné avec ERA) - effectiveness : 20% (baseline) - **APS reduction** : 20% × (1 - 0.80) = 4% effectiveness finale - shield_value : 1000 × 300 × 0.04 = 12 000 **Résultat** : ``` defensive_effectiveness = 12000 / 20000 = 60% residual_multiplier = max(0.05, 0.40) = 40% final_threat = 20000 × 0.40 = 8 000 → Menace reste significative (40%) → APS + ERA réduisent drastiquement effectiveness Gen2 → Système de conception permet adaptation doctrine → Joueur peut designer tanks spécifiquement anti-saturation ``` ## Évaluation Domaine Aérien ### Spécificités Air **Complexité supplémentaire** : - **Qualité prime** : Furtivité et ECM dominent - **ECM/ECCM** : Guerre électronique critique - **Compatibilité stricte** : AA anti-hélicoptère ne touche pas jets ```cpp struct AirForces { std::vector fighters; std::vector bombers; std::vector helicopters; std::vector drones; // Capacités spéciales bool has_stealth; bool has_ecm; // Electronic Counter-Measures int electronic_warfare_level; }; struct AirDefenses { std::vector aa_missiles; std::vector aa_guns; std::vector interceptors; // Capacités bool has_eccm; // Electronic Counter-Counter-Measures int radar_quality; std::map capabilities; }; enum TargetCapability { HELICOPTER_ONLY, // Seulement hélicoptères LOW_ALTITUDE, // Avions basse altitude HIGH_ALTITUDE, // Avions haute altitude ALL_AIRCRAFT // Tous types }; ``` ### Effectiveness Air avec Stealth/ECM ```cpp float calculateAirDefenseEffectiveness(Aircraft aircraft, AASystem aa) { // Base effectiveness selon pénétration radar vs stealth float base_eff = calculateCounterEffectiveness(aa, aircraft); // Multiplicateurs tech float stealth_reduction = 1.0f; if (aircraft.has_stealth && !aa.has_advanced_radar) { stealth_reduction = 1.0f - aircraft.stealth_rating; // Ex: 0.1 si 90% stealth } float ecm_reduction = 1.0f; if (aircraft.has_ecm && !aa.has_eccm) { ecm_reduction = 1.0f - (aircraft.ecm_power / (aa.radar_quality + 1)); } // Effectiveness finale (baseline 20% toujours appliqué) float final_eff = max(0.20f, base_eff * stealth_reduction * ecm_reduction); return final_eff; } ``` ### Exemple Air : Furtivité + ECM **Attaquant** : - 20 jets furtifs Gen4 (F-35) - stealth_rating : 0.90 (réduit détection 90%) - ecm_power : 8 - combat_value : 2000/jet - Menace brute : 40 000 **Défenseur** : - 1000 missiles AA Gen3 (Patriot) - radar_quality : 6 - has_eccm : false - base_effectiveness : 70% (tech Gen3 vs Gen4) - stealth_reduction : 1.0 - 0.90 = 0.10 - ecm_reduction : 1.0 - (8/7) = -0.14 → 0.0 (plancher) - final_effectiveness : max(0.20, 0.70 × 0.10 × 0.0) = 20% (baseline) - shield_value : 1000 × 400 × 0.20 = 80 000 **Résultat** : ``` defensive_effectiveness = min(1.0, 80000 / 40000) = 100% residual_multiplier = 5% final_threat = 40000 × 0.05 = 2 000 → Furtivité + ECM ramènent effectiveness au baseline 20% → Nécessite masse importante (1000 missiles) pour compenser → F-35 peuvent accomplir raid avant saturation (menace 5% résiduelle) ``` ## É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 (penetration vs armor pour missiles anti-navire). ## É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 - Effectiveness moyenne : 40% - Défense production : 1200 × 300 × 0.40 = 144 000 **Net production threat** : ``` Attacker gain : 240 000 Defender gain : 144 000 Net : 240 000 - 144 000 = 96 000 production_threat = 96 000 → État A a avantage production malgré défenses ``` ## 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, eff 60%) → Shield 60% tanks - AA systems : 1500 (Gen3, eff 40% vs furtifs) → Shield 40% aircraft - Naval defenses : 200 (eff 50%) → Shield 50% naval **Après sword & shield** : - Land : 3 200 000 × max(0.05, 0.40) = 1 280 000 - Air : 4 000 000 × max(0.05, 0.60) = 2 400 000 - Naval : 2 500 000 × max(0.05, 0.50) = 1 250 000 - **Current threat** : 4 930 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)** : ``` 4 930 000 × 0.6 + 290 000 × 0.4 = 3 074 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 (effectiveness 30%) - Fortifications : minimal - **Shield** : 15% **Threat** : ``` residual = max(0.05, 1.0 - 0.15) = 85% final_threat = 50000 × 0.85 = 42 500 → PMC peut menacer installations Company ``` ## 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) } } ``` ## Implications Stratégiques ### 1. Coût-Efficacité Défensive ```cpp struct DefenseCostAnalysis { float threat_neutralized; float cost; float cost_efficiency; // menace neutralisée par € }; // Neutraliser 20 Leopard 2A7 (160M€ total) Option A - RPG-7 masse (effectiveness 20%) : - Quantité nécessaire : 100 RPG × 20 tanks = 2000 RPG - Coût : 2000 × 500€ = 1M€ - Ratio : 1M€ / 160M€ = 0.625% - Avantage : Très économique - Inconvénient : Logistique massive Option B - Javelin Gen3 (effectiveness 70%) : - Quantité nécessaire : 1.5 Javelin × 20 tanks = 30 Javelin - Coût : 30 × 200k€ = 6M€ - Ratio : 6M€ / 160M€ = 3.75% - Avantage : Logistique légère - Inconvénient : Plus cher → RPG-7 est 6× plus cost-efficient, mais logistique 67× plus lourde → Choix stratégique selon capacités logistiques ``` ### 2. Perte Asymétrique ```cpp // Exemple bataille : Menace neutralisée mais pertes coûteuses Attaquant : 20 Leopard 2A7 (160M€) Défenseur : 5000 RPG-7 (2.5M€) Outcome tactique : - Tous Leopards détruits (saturation) - 2000 RPG-7 utilisés effectivement Bilan stratégique : Attaquant pertes : - 160M€ équipement - 20 crews élites (formation coûteuse) - Prestige international - Capacités offensives réduites Défenseur pertes : - 1M€ munitions consommées (2000 RPG effectifs) - +Victoire propagande - +Moral défensif → Victoire tactique défenseur = victoire stratégique → Système menace reflète cette asymétrie via residual 5% → Perdre Leopard = toujours désastre même si menace "neutralisée" ``` ## Performance et Optimisation ### Cache Threat ```cpp class ThreatCache { private: struct CachedThreat { int value; int timestamp; int ttl = 3600; // 1 heure }; std::map, 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 - Retrofit/upgrade équipement ### 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, système conception modulaire - `economie-logistique.md` : Production rates, capacités industrielles