From 126d70792fd84482a34d54ae7aef7e86241d8451 Mon Sep 17 00:00:00 2001 From: Raffson Date: Sat, 21 Sep 2024 22:22:07 +0200 Subject: [PATCH] Another attempt to improve DEAD autoplanner --- game/commander/tasks/compound/degradeiads.py | 14 +++++++++ game/commander/tasks/packageplanningtask.py | 32 ++++++++++++++------ game/commander/theaterstate.py | 5 +++ 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/game/commander/tasks/compound/degradeiads.py b/game/commander/tasks/compound/degradeiads.py index a40ae8e9..d8cb9df9 100644 --- a/game/commander/tasks/compound/degradeiads.py +++ b/game/commander/tasks/compound/degradeiads.py @@ -4,6 +4,7 @@ from typing import Union from game.commander.tasks.primitive.antiship import PlanAntiShip from game.commander.tasks.primitive.dead import PlanDead from game.commander.theaterstate import TheaterState +from game.data.groups import GroupTask from game.htn import CompoundTask, Method from game.theater.theatergroundobject import IadsGroundObject, NavalGroundObject @@ -12,6 +13,19 @@ class DegradeIads(CompoundTask[TheaterState]): def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]: for air_defense in state.threatening_air_defenses: yield [self.plan_against(air_defense)] + + prioritized_air_defenses = sorted( + [ + tgo + for tgo in state.enemy_air_defenses + if tgo.task in [GroupTask.LORAD, GroupTask.MERAD] + ], + key=lambda x: (state.priority_cp.distance_to(x) if state.priority_cp else 0) + - x.max_threat_range().meters, + ) + + for air_defense in prioritized_air_defenses: + yield [self.plan_against(air_defense)] for detector in state.detecting_air_defenses: yield [self.plan_against(detector)] diff --git a/game/commander/tasks/packageplanningtask.py b/game/commander/tasks/packageplanningtask.py index a56e54bf..6780e64e 100644 --- a/game/commander/tasks/packageplanningtask.py +++ b/game/commander/tasks/packageplanningtask.py @@ -130,15 +130,7 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]): if range_type is RangeType.Detection: target_range = target.max_detection_range() elif range_type is RangeType.Threat: - settings = state.context.coalition.game.settings - margin = 100 - ( - settings.ownfor_autoplanner_aggressiveness - if state.context.coalition.player - else settings.opfor_autoplanner_aggressiveness - ) - target_range = target.max_threat_range() * (margin / 100) - corrective_factor = self.corrective_factor_for_type(target) - target_range *= corrective_factor + target_range = target.max_threat_range() else: raise ValueError(f"Unknown RangeType: {range_type}") if not target_range: @@ -194,11 +186,31 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]): if not ignore_iads: for iads_threat in self.iter_iads_threats(state): - threatened = True + weighted = self._get_weighted_threat_range(iads_threat, state) + if weighted < meters(0): + threatened = True if iads_threat not in state.threatening_air_defenses: state.threatening_air_defenses.append(iads_threat) return not threatened + def _get_weighted_threat_range( + self, + iads_threat: Union[IadsGroundObject | NavalGroundObject], + state: TheaterState, + ) -> Distance: + distance = meters(iads_threat.distance_to(self.target)) + settings = state.context.coalition.game.settings + margin = 100 - ( + settings.ownfor_autoplanner_aggressiveness + if state.context.coalition.player + else settings.opfor_autoplanner_aggressiveness + ) + threat_range = iads_threat.max_threat_range() * (margin / 100) + corrective_factor = self.corrective_factor_for_type(iads_threat) + threat_range *= corrective_factor + distance_to_threat = distance - threat_range + return distance_to_threat + def get_flight_size(self) -> int: settings = self.target.coalition.game.settings weights = [ diff --git a/game/commander/theaterstate.py b/game/commander/theaterstate.py index 3d57b224..e3ca334e 100644 --- a/game/commander/theaterstate.py +++ b/game/commander/theaterstate.py @@ -64,6 +64,7 @@ class TheaterState(WorldState["TheaterState"]): threat_zones: ThreatZones vulnerable_control_points: list[ControlPoint] control_point_priority_queue: list[ControlPoint] + priority_cp: Optional[ControlPoint] def _rebuild_threat_zones(self) -> None: """Recreates the theater's threat zones based on the current planned state.""" @@ -139,6 +140,7 @@ class TheaterState(WorldState["TheaterState"]): detecting_air_defenses=self.detecting_air_defenses, vulnerable_control_points=self.vulnerable_control_points, control_point_priority_queue=self.control_point_priority_queue, + priority_cp=self.priority_cp, ) @classmethod @@ -201,4 +203,7 @@ class TheaterState(WorldState["TheaterState"]): threat_zones=game.threat_zone_for(not player), vulnerable_control_points=vulnerable_control_points, control_point_priority_queue=ordered_capturable_points, + priority_cp=ordered_capturable_points[0] + if ordered_capturable_points + else None, )