aissia/docs/calcul-menace.md
StillHammer ba42b6d9c7 Update CDC with hybrid architecture (WarFactory + multi-target)
- Add hybrid deployment modes: local_dev (MVP) and production_pwa (optional)
- Integrate WarFactory engine reuse with hot-reload 0.4ms
- Define multi-target compilation strategy (DLL/SO/WASM)
- Detail both deployment modes with cost analysis
- Add progressive roadmap: Phase 1 (local), Phase 2 (POC WASM), Phase 3 (cloud)
- Budget clarified: $10-20/mois (local) vs $13-25/mois (cloud)
- Document open questions for technical validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 11:49:09 +08:00

753 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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