Let the TheaterCommander manage front line stance.

This improves the AI behavior by choosing the stances non-randomly:

* Breakthrough will be used if the base is expected to be capturable and
  the coalition outnumbers the enemy by 20%.
* Elimination will be used if the coalition has at least as many units
  as the enemy.
* Defensive will be used if the coalition has at least half as many
  units as the enemy.
* Retreat will be used if the coalition is significantly outnumbers.

This also exposes the option to the player.
This commit is contained in:
Dan Albert
2021-07-12 20:31:38 -07:00
parent 575aca5886
commit 0a416ab758
35 changed files with 361 additions and 57 deletions

View File

@@ -86,43 +86,19 @@ class GroundConflictGenerator:
player_planned_combat_groups: List[CombatGroup],
enemy_planned_combat_groups: List[CombatGroup],
player_stance: CombatStance,
enemy_stance: CombatStance,
unit_map: UnitMap,
) -> None:
self.mission = mission
self.conflict = conflict
self.enemy_planned_combat_groups = enemy_planned_combat_groups
self.player_planned_combat_groups = player_planned_combat_groups
self.player_stance = CombatStance(player_stance)
self.enemy_stance = self._enemy_stance()
self.player_stance = player_stance
self.enemy_stance = enemy_stance
self.game = game
self.unit_map = unit_map
self.jtacs: List[JtacInfo] = []
def _enemy_stance(self) -> CombatStance:
"""Picks the enemy stance according to the number of planned groups on the frontline for each side"""
if len(self.enemy_planned_combat_groups) > len(
self.player_planned_combat_groups
):
return random.choice(
[
CombatStance.AGGRESSIVE,
CombatStance.AGGRESSIVE,
CombatStance.AGGRESSIVE,
CombatStance.ELIMINATION,
CombatStance.BREAKTHROUGH,
]
)
else:
return random.choice(
[
CombatStance.DEFENSIVE,
CombatStance.DEFENSIVE,
CombatStance.DEFENSIVE,
CombatStance.AMBUSH,
CombatStance.AGGRESSIVE,
]
)
def generate(self) -> None:
position = Conflict.frontline_position(
self.conflict.front_line, self.game.theater