Another attempt to improve DEAD autoplanner

This commit is contained in:
Raffson 2024-09-21 22:22:07 +02:00
parent 9d2345ea3a
commit 126d70792f
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
3 changed files with 41 additions and 10 deletions

View File

@ -4,6 +4,7 @@ from typing import Union
from game.commander.tasks.primitive.antiship import PlanAntiShip from game.commander.tasks.primitive.antiship import PlanAntiShip
from game.commander.tasks.primitive.dead import PlanDead from game.commander.tasks.primitive.dead import PlanDead
from game.commander.theaterstate import TheaterState from game.commander.theaterstate import TheaterState
from game.data.groups import GroupTask
from game.htn import CompoundTask, Method from game.htn import CompoundTask, Method
from game.theater.theatergroundobject import IadsGroundObject, NavalGroundObject 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]]: def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]:
for air_defense in state.threatening_air_defenses: for air_defense in state.threatening_air_defenses:
yield [self.plan_against(air_defense)] 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: for detector in state.detecting_air_defenses:
yield [self.plan_against(detector)] yield [self.plan_against(detector)]

View File

@ -130,15 +130,7 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
if range_type is RangeType.Detection: if range_type is RangeType.Detection:
target_range = target.max_detection_range() target_range = target.max_detection_range()
elif range_type is RangeType.Threat: elif range_type is RangeType.Threat:
settings = state.context.coalition.game.settings target_range = target.max_threat_range()
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
else: else:
raise ValueError(f"Unknown RangeType: {range_type}") raise ValueError(f"Unknown RangeType: {range_type}")
if not target_range: if not target_range:
@ -194,11 +186,31 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
if not ignore_iads: if not ignore_iads:
for iads_threat in self.iter_iads_threats(state): 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: if iads_threat not in state.threatening_air_defenses:
state.threatening_air_defenses.append(iads_threat) state.threatening_air_defenses.append(iads_threat)
return not threatened 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: def get_flight_size(self) -> int:
settings = self.target.coalition.game.settings settings = self.target.coalition.game.settings
weights = [ weights = [

View File

@ -64,6 +64,7 @@ class TheaterState(WorldState["TheaterState"]):
threat_zones: ThreatZones threat_zones: ThreatZones
vulnerable_control_points: list[ControlPoint] vulnerable_control_points: list[ControlPoint]
control_point_priority_queue: list[ControlPoint] control_point_priority_queue: list[ControlPoint]
priority_cp: Optional[ControlPoint]
def _rebuild_threat_zones(self) -> None: def _rebuild_threat_zones(self) -> None:
"""Recreates the theater's threat zones based on the current planned state.""" """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, detecting_air_defenses=self.detecting_air_defenses,
vulnerable_control_points=self.vulnerable_control_points, vulnerable_control_points=self.vulnerable_control_points,
control_point_priority_queue=self.control_point_priority_queue, control_point_priority_queue=self.control_point_priority_queue,
priority_cp=self.priority_cp,
) )
@classmethod @classmethod
@ -201,4 +203,7 @@ class TheaterState(WorldState["TheaterState"]):
threat_zones=game.threat_zone_for(not player), threat_zones=game.threat_zone_for(not player),
vulnerable_control_points=vulnerable_control_points, vulnerable_control_points=vulnerable_control_points,
control_point_priority_queue=ordered_capturable_points, control_point_priority_queue=ordered_capturable_points,
priority_cp=ordered_capturable_points[0]
if ordered_capturable_points
else None,
) )