- 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>
753 lines
21 KiB
Markdown
753 lines
21 KiB
Markdown
# 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
|