mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
multiplier new game setting (unit amounts option); tweaked commisions
This commit is contained in:
parent
1a491bb814
commit
25e2681665
14
__init__.py
14
__init__.py
@ -27,7 +27,7 @@ game = persistency.restore_game()
|
||||
if not game:
|
||||
new_game_menu = None # type: NewGameMenu
|
||||
|
||||
def start_new_game(player_name: str, enemy_name: str, terrain: str, sams: bool):
|
||||
def start_new_game(player_name: str, enemy_name: str, terrain: str, sams: bool, multiplier: float):
|
||||
if terrain == "persiangulf":
|
||||
conflicttheater = theater.persiangulf.PersianGulfTheater()
|
||||
elif terrain == "nevada":
|
||||
@ -35,10 +35,14 @@ if not game:
|
||||
else:
|
||||
conflicttheater = theater.caucasus.CaucasusTheater()
|
||||
|
||||
start_generator.generate_initial(conflicttheater, enemy_name, sams)
|
||||
proceed_to_main_menu(Game(player_name=player_name,
|
||||
enemy_name=enemy_name,
|
||||
theater=conflicttheater))
|
||||
start_generator.generate_initial(conflicttheater, enemy_name, sams, multiplier)
|
||||
game = Game(player_name=player_name,
|
||||
enemy_name=enemy_name,
|
||||
theater=conflicttheater)
|
||||
game.budget = int(game.budget * multiplier)
|
||||
game.settings.multiplier = multiplier
|
||||
|
||||
proceed_to_main_menu(game)
|
||||
|
||||
new_game_menu = ui.newgamemenu.NewGameMenu(w, start_new_game)
|
||||
new_game_menu.display()
|
||||
|
||||
@ -79,7 +79,7 @@ class AntiAAStrikeEvent(Event):
|
||||
to_cp=self.to_cp
|
||||
)
|
||||
|
||||
strikegroup = self.from_cp.base.scramble_cas()
|
||||
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
op.setup(target=self.targets,
|
||||
strikegroup=strikegroup,
|
||||
interceptors=interceptors)
|
||||
|
||||
@ -21,7 +21,7 @@ class CaptureEvent(Event):
|
||||
@property
|
||||
def threat_description(self):
|
||||
descr = "{} aircraft + CAS, {} vehicles".format(
|
||||
self.enemy_cp.base.scramble_count(),
|
||||
self.enemy_cp.base.scramble_count(self.game.settings.multiplier),
|
||||
self.enemy_cp.base.assemble_count()
|
||||
)
|
||||
|
||||
@ -57,9 +57,9 @@ class CaptureEvent(Event):
|
||||
self.to_cp.captured = False
|
||||
|
||||
def player_defending(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
|
||||
cas = self.from_cp.base.scramble_cas()
|
||||
escort = self.from_cp.base.scramble_sweep()
|
||||
attackers = self.from_cp.base.assemble_cap()
|
||||
cas = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
escort = self.from_cp.base.scramble_sweep(self.game.settings.multiplier)
|
||||
attackers = self.from_cp.base.armor
|
||||
|
||||
op = CaptureOperation(game=self.game,
|
||||
attacker_name=self.attacker_name,
|
||||
@ -79,9 +79,6 @@ class CaptureEvent(Event):
|
||||
self.operation = op
|
||||
|
||||
def player_attacking(self, cas: db.PlaneDict, escort: db.PlaneDict, armor: db.ArmorDict, clients: db.PlaneDict):
|
||||
# TODO: also include CAS planes
|
||||
interceptors = self.to_cp.base.scramble_sweep()
|
||||
|
||||
op = CaptureOperation(game=self.game,
|
||||
attacker_name=self.attacker_name,
|
||||
defender_name=self.defender_name,
|
||||
@ -90,11 +87,13 @@ class CaptureEvent(Event):
|
||||
from_cp=self.from_cp,
|
||||
to_cp=self.to_cp)
|
||||
|
||||
defenders = self.to_cp.base.scramble_sweep(self.game.settings.multiplier)
|
||||
defenders.update(self.to_cp.base.scramble_cas(self.game.settings.multiplier))
|
||||
|
||||
op.setup(cas=cas,
|
||||
escort=escort,
|
||||
attack=armor,
|
||||
intercept=interceptors,
|
||||
# TODO: should strength affect this?
|
||||
intercept=defenders,
|
||||
defense=self.to_cp.base.armor,
|
||||
aa=self.to_cp.base.assemble_aa())
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ class Event:
|
||||
is_awacs_enabled = False
|
||||
operation = None # type: Operation
|
||||
difficulty = 1 # type: int
|
||||
game = None # type: Game
|
||||
BONUS_BASE = 0
|
||||
|
||||
def __init__(self, attacker_name: str, defender_name: str, from_cp: ControlPoint, to_cp: ControlPoint, game):
|
||||
|
||||
@ -88,7 +88,7 @@ class GroundInterceptEvent(Event):
|
||||
to_cp=self.to_cp
|
||||
)
|
||||
|
||||
strikegroup = self.from_cp.base.scramble_cas()
|
||||
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
op.setup(target=self.targets,
|
||||
strikegroup=strikegroup,
|
||||
interceptors=interceptors)
|
||||
|
||||
@ -25,7 +25,7 @@ class InterceptEvent(Event):
|
||||
|
||||
@property
|
||||
def threat_description(self):
|
||||
return "{} aircraft".format(self.enemy_cp.base.scramble_count())
|
||||
return "{} aircraft".format(self.enemy_cp.base.scramble_count(self.game.settings.multiplier))
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
units_destroyed = debriefing.destroyed_units[self.defender_name].get(self.transport_unit, 0)
|
||||
@ -55,7 +55,7 @@ class InterceptEvent(Event):
|
||||
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
|
||||
|
||||
def player_attacking(self, interceptors: db.PlaneDict, clients: db.PlaneDict):
|
||||
escort = self.to_cp.base.scramble_sweep()
|
||||
escort = self.to_cp.base.scramble_sweep(self.game.settings.multiplier)
|
||||
|
||||
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name))
|
||||
assert self.transport_unit is not None
|
||||
@ -77,7 +77,7 @@ class InterceptEvent(Event):
|
||||
self.operation = op
|
||||
|
||||
def player_defending(self, escort: db.PlaneDict, clients: db.PlaneDict):
|
||||
interceptors = self.from_cp.base.scramble_interceptors()
|
||||
interceptors = self.from_cp.base.scramble_interceptors(self.game.settings.multiplier)
|
||||
|
||||
self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name))
|
||||
assert self.transport_unit is not None
|
||||
|
||||
@ -30,7 +30,7 @@ class NavalInterceptEvent(Event):
|
||||
def threat_description(self):
|
||||
s = "{} ship(s)".format(self._targets_count())
|
||||
if not self.from_cp.captured:
|
||||
s += ", {} aircraft".format(self.from_cp.base.scramble_count())
|
||||
s += ", {} aircraft".format(self.from_cp.base.scramble_count(self.game.settings.multiplier))
|
||||
return s
|
||||
|
||||
def is_successfull(self, debriefing: Debriefing):
|
||||
@ -100,7 +100,7 @@ class NavalInterceptEvent(Event):
|
||||
to_cp=self.to_cp
|
||||
)
|
||||
|
||||
strikegroup = self.from_cp.base.scramble_cas()
|
||||
strikegroup = self.from_cp.base.scramble_cas(self.game.settings.multiplier)
|
||||
op.setup(strikegroup=strikegroup,
|
||||
interceptors=interceptors,
|
||||
targets=self.targets)
|
||||
|
||||
221
game/game.py
221
game/game.py
@ -12,38 +12,34 @@ from . import db
|
||||
from .settings import Settings
|
||||
from .event import *
|
||||
|
||||
COMMISION_LIMITS_SCALE = 2
|
||||
COMMISION_LIMITS_SCALE = 1.5
|
||||
COMMISION_LIMITS_FACTORS = {
|
||||
PinpointStrike: 2,
|
||||
CAS: 1,
|
||||
CAP: 3,
|
||||
AirDefence: 1,
|
||||
PinpointStrike: 10,
|
||||
CAS: 5,
|
||||
CAP: 8,
|
||||
AirDefence: 2,
|
||||
}
|
||||
|
||||
COMMISION_AMOUNTS_SCALE = 2
|
||||
COMMISION_AMOUNTS_SCALE = 1.5
|
||||
COMMISION_UNIT_VARIETY = 4
|
||||
COMMISION_AMOUNTS_FACTORS = {
|
||||
PinpointStrike: 0.6,
|
||||
CAS: 0.3,
|
||||
CAP: 0.5,
|
||||
PinpointStrike: 2,
|
||||
CAS: 1,
|
||||
CAP: 2,
|
||||
AirDefence: 0.3,
|
||||
}
|
||||
|
||||
|
||||
ENEMY_INTERCEPT_PROBABILITY_BASE = 5
|
||||
ENEMY_CAPTURE_PROBABILITY_BASE = 4
|
||||
ENEMY_GROUNDINTERCEPT_PROBABILITY_BASE = 5
|
||||
ENEMY_NAVALINTERCEPT_PROBABILITY_BASE = 5
|
||||
ENEMY_ANTIAASTRIKE_PROBABILITY_BASE = 5
|
||||
ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE = 5
|
||||
|
||||
PLAYER_INTERCEPT_PROBABILITY_BASE = 35
|
||||
PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 35
|
||||
PLAYER_NAVALINTERCEPT_PROBABILITY_BASE = 35
|
||||
PLAYER_ANTIAASTRIKE_PROBABILITY_BASE = 35
|
||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 25
|
||||
PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2
|
||||
EVENT_PROBABILITIES = {
|
||||
CaptureEvent: [100, 4],
|
||||
InterceptEvent: [35, 5],
|
||||
GroundInterceptEvent: [35, 5],
|
||||
NavalInterceptEvent: [35, 5],
|
||||
AntiAAStrikeEvent: [35, 5],
|
||||
}
|
||||
|
||||
PLAYER_BASE_STRENGTH_RECOVERY = 0.2
|
||||
PLAYER_BUDGET_INITIAL = 120
|
||||
PLAYER_BUDGET_BASE = 30
|
||||
PLAYER_BUDGET_IMPORTANCE_LOG = 2
|
||||
@ -68,119 +64,6 @@ class Game:
|
||||
def _roll(self, prob, mult):
|
||||
return random.randint(0, 100) <= prob * mult
|
||||
|
||||
def _fill_cap_events(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if to_cp not in [x.to_cp for x in self.events]:
|
||||
self.events.append(CaptureEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
|
||||
def _generate_enemy_caps(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if from_cp.base.total_planes == 0 or from_cp.base.total_armor == 0:
|
||||
continue
|
||||
|
||||
if to_cp in self.ignored_cps:
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_CAPTURE_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(CaptureEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_interceptions(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if from_cp.base.total_units(CAP) == 0:
|
||||
continue
|
||||
|
||||
if to_cp in self.ignored_cps:
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_INTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(InterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
if to_cp in self.theater.conflicts(False):
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE, 1):
|
||||
for from_cp, _ in self.theater.conflicts(False):
|
||||
if from_cp.base.total_units(CAP) > 0:
|
||||
self.events.append(InterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if self._roll(PLAYER_INTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(InterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_groundinterceptions(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if self._roll(PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(GroundInterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if to_cp in self.ignored_cps:
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_GROUNDINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(GroundInterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_navalinterceptions(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if to_cp.radials == LAND:
|
||||
continue
|
||||
|
||||
if self._roll(PLAYER_NAVALINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(NavalInterceptEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if to_cp.radials == LAND:
|
||||
continue
|
||||
|
||||
if to_cp in self.ignored_cps:
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_NAVALINTERCEPT_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(NavalInterceptEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_globalinterceptions(self):
|
||||
global_count = len([x for x in self.theater.player_points() if x.is_global])
|
||||
for from_cp in [x for x in self.theater.player_points() if x.is_global]:
|
||||
@ -195,52 +78,61 @@ class Game:
|
||||
game=self))
|
||||
break
|
||||
|
||||
def _generate_aastrikes(self):
|
||||
for from_cp, to_cp in self.theater.conflicts(True):
|
||||
if to_cp.base.total_aa == 0:
|
||||
def _generate_events(self):
|
||||
enemy_cap_generated = False
|
||||
for player_cp, enemy_cp in self.theater.conflicts(True):
|
||||
if player_cp.is_global or enemy_cp.is_global:
|
||||
continue
|
||||
|
||||
if self._roll(PLAYER_ANTIAASTRIKE_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(AntiAAStrikeEvent(attacker_name=self.player,
|
||||
defender_name=self.enemy,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
for event_class, (player_probability, enemy_probability) in EVENT_PROBABILITIES.items():
|
||||
if self._roll(player_probability, player_cp.base.strength):
|
||||
if event_class == NavalInterceptEvent:
|
||||
if enemy_cp.radials == LAND:
|
||||
continue
|
||||
|
||||
for from_cp, to_cp in self.theater.conflicts(False):
|
||||
if to_cp in self.ignored_cps:
|
||||
continue
|
||||
self.events.append(event_class(self.player, self.enemy, player_cp, enemy_cp, self))
|
||||
elif self._roll(enemy_probability, enemy_cp.base.strength):
|
||||
if player_cp in self.ignored_cps:
|
||||
continue
|
||||
|
||||
if to_cp.base.total_aa == 0:
|
||||
continue
|
||||
if enemy_cp.base.total_planes == 0:
|
||||
continue
|
||||
|
||||
if self._roll(ENEMY_ANTIAASTRIKE_PROBABILITY_BASE, from_cp.base.strength):
|
||||
self.events.append(AntiAAStrikeEvent(attacker_name=self.enemy,
|
||||
defender_name=self.player,
|
||||
from_cp=from_cp,
|
||||
to_cp=to_cp,
|
||||
game=self))
|
||||
break
|
||||
if event_class == NavalInterceptEvent:
|
||||
if player_cp.radials == LAND:
|
||||
continue
|
||||
elif event_class == CaptureEvent:
|
||||
if enemy_cap_generated:
|
||||
continue
|
||||
if enemy_cp.base.total_armor == 0:
|
||||
continue
|
||||
enemy_cap_generated = True
|
||||
elif event_class == AntiAAStrikeEvent:
|
||||
if player_cp.base.total_aa == 0:
|
||||
continue
|
||||
|
||||
self.events.append(event_class(self.enemy, self.player, enemy_cp, player_cp, self))
|
||||
|
||||
def _commision_units(self, cp: ControlPoint):
|
||||
for for_task in [PinpointStrike, CAS, CAP, AirDefence]:
|
||||
limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_LIMITS_SCALE)
|
||||
limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_LIMITS_SCALE) * self.settings.multiplier
|
||||
missing_units = limit - cp.base.total_units(for_task)
|
||||
if missing_units > 0:
|
||||
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_AMOUNTS_SCALE)
|
||||
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
|
||||
points_to_spend = cp.base.append_commision_points(for_task, awarded_points)
|
||||
if points_to_spend > 0:
|
||||
importance_factor = (cp.importance - IMPORTANCE_LOW) / (IMPORTANCE_HIGH - IMPORTANCE_LOW)
|
||||
unittypes = db.choose_units(for_task, importance_factor, COMMISION_UNIT_VARIETY, self.enemy)
|
||||
cp.base.commision_units({random.choice(unittypes): points_to_spend})
|
||||
d = {random.choice(unittypes): points_to_spend}
|
||||
print("Commision {}: {}".format(cp, d))
|
||||
cp.base.commision_units(d)
|
||||
|
||||
@property
|
||||
def budget_reward_amount(self):
|
||||
if len(self.theater.player_points()) > 0:
|
||||
total_importance = sum([x.importance for x in self.theater.player_points()])
|
||||
total_strength = sum([x.base.strength for x in self.theater.player_points()]) / len(self.theater.player_points())
|
||||
return math.ceil(math.log(total_importance * total_strength + 1, PLAYER_BUDGET_IMPORTANCE_LOG) * PLAYER_BUDGET_BASE)
|
||||
return math.ceil(math.log(total_importance * total_strength + 1, PLAYER_BUDGET_IMPORTANCE_LOG) * PLAYER_BUDGET_BASE * self.settings.multiplier)
|
||||
else:
|
||||
return 0
|
||||
|
||||
@ -287,17 +179,14 @@ class Game:
|
||||
self._budget_player()
|
||||
for cp in self.theater.enemy_points():
|
||||
self._commision_units(cp)
|
||||
for cp in self.theater.player_points():
|
||||
cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY)
|
||||
|
||||
self.ignored_cps = []
|
||||
if ignored_cps:
|
||||
self.ignored_cps = ignored_cps
|
||||
|
||||
self.events = [] # type: typing.List[Event]
|
||||
self._fill_cap_events()
|
||||
self._generate_enemy_caps()
|
||||
self._generate_interceptions()
|
||||
self._generate_events()
|
||||
self._generate_globalinterceptions()
|
||||
self._generate_groundinterceptions()
|
||||
self._generate_navalinterceptions()
|
||||
self._generate_aastrikes()
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ from gen.visualgen import *
|
||||
|
||||
from .operation import Operation
|
||||
|
||||
|
||||
class CaptureOperation(Operation):
|
||||
cas = None # type: db.PlaneDict
|
||||
escort = None # type: db.PlaneDict
|
||||
|
||||
@ -4,3 +4,4 @@ class Settings:
|
||||
enemy_skill = "Average"
|
||||
only_player_takeoff = False
|
||||
night_disabled = False
|
||||
multiplier = 1
|
||||
|
||||
@ -9,10 +9,9 @@ from dcs.planes import *
|
||||
from dcs.vehicles import *
|
||||
from dcs.task import *
|
||||
|
||||
PLANES_IN_GROUP = 2
|
||||
|
||||
PLANES_SCRAMBLE_MIN = 4
|
||||
PLANES_SCRAMBLE_MAX = 8
|
||||
STRENGTH_AA_ASSEMBLE_MIN = 0.2
|
||||
PLANES_SCRAMBLE_MIN_BASE = 4
|
||||
PLANES_SCRAMBLE_MAX_BASE = 8
|
||||
PLANES_SCRAMBLE_FACTOR = 0.5
|
||||
|
||||
|
||||
@ -84,12 +83,6 @@ class Base:
|
||||
def _find_best_armor(self, for_type: Task, count: int) -> typing.Dict[Armor, int]:
|
||||
return self._find_best_unit(self.armor, for_type, count)
|
||||
|
||||
def _group_sizes(self, total_planes: int) -> typing.List[int]:
|
||||
total_scrambled = 0
|
||||
for _ in range(math.ceil(total_planes / PLANES_IN_GROUP)):
|
||||
total_scrambled += PLANES_IN_GROUP
|
||||
yield total_scrambled < total_planes and PLANES_IN_GROUP or total_planes - total_scrambled
|
||||
|
||||
def append_commision_points(self, for_type, points: float) -> int:
|
||||
self.commision_points[for_type] = self.commision_points.get(for_type, 0) + points
|
||||
points = self.commision_points[for_type]
|
||||
@ -147,24 +140,27 @@ class Base:
|
||||
elif self.strength < 0:
|
||||
self.strength = 0.001
|
||||
|
||||
def scramble_count(self) -> int:
|
||||
def scramble_count(self, multiplier: float) -> int:
|
||||
count = int(self.total_planes * PLANES_SCRAMBLE_FACTOR * self.strength)
|
||||
return min(min(max(count, PLANES_SCRAMBLE_MIN), PLANES_SCRAMBLE_MAX), self.total_planes)
|
||||
return min(min(max(count, PLANES_SCRAMBLE_MIN_BASE), int(PLANES_SCRAMBLE_MAX_BASE * multiplier)), self.total_planes)
|
||||
|
||||
def assemble_count(self):
|
||||
return int(self.total_armor * self.strength)
|
||||
|
||||
def assemble_aa_count(self) -> int:
|
||||
return int(self.total_aa * (self.strength > 0.2 and self.strength or 0))
|
||||
if self.strength > STRENGTH_AA_ASSEMBLE_MIN:
|
||||
return self.total_aa
|
||||
else:
|
||||
return 0
|
||||
|
||||
def scramble_sweep(self) -> typing.Dict[PlaneType, int]:
|
||||
return self._find_best_planes(CAP, self.scramble_count())
|
||||
def scramble_sweep(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||
return self._find_best_planes(CAP, self.scramble_count(multiplier))
|
||||
|
||||
def scramble_cas(self) -> typing.Dict[PlaneType, int]:
|
||||
return self._find_best_planes(CAS, self.scramble_count())
|
||||
def scramble_cas(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||
return self._find_best_planes(CAS, self.scramble_count(multiplier))
|
||||
|
||||
def scramble_interceptors(self) -> typing.Dict[PlaneType, int]:
|
||||
return self._find_best_planes(CAP, self.scramble_count())
|
||||
def scramble_interceptors(self, multiplier: float) -> typing.Dict[PlaneType, int]:
|
||||
return self._find_best_planes(CAP, self.scramble_count(multiplier))
|
||||
|
||||
def assemble_cap(self) -> typing.Dict[Armor, int]:
|
||||
return self._find_best_armor(PinpointStrike, self.assemble_count())
|
||||
|
||||
@ -5,16 +5,17 @@ from theater.conflicttheater import *
|
||||
|
||||
UNIT_VARIETY = 3
|
||||
UNIT_AMOUNT_FACTOR = 16
|
||||
UNIT_COUNT_IMPORTANCE_LOG = 1.3
|
||||
|
||||
COUNT_BY_TASK = {
|
||||
PinpointStrike: 24,
|
||||
CAP: 16,
|
||||
CAS: 8,
|
||||
AirDefence: 0.5,
|
||||
PinpointStrike: 12,
|
||||
CAP: 8,
|
||||
CAS: 4,
|
||||
AirDefence: 2,
|
||||
}
|
||||
|
||||
|
||||
def generate_initial(theater: ConflictTheater, enemy: str, sams: bool):
|
||||
def generate_initial(theater: ConflictTheater, enemy: str, sams: bool, multiplier: float):
|
||||
for cp in theater.enemy_points():
|
||||
if cp.captured:
|
||||
continue
|
||||
@ -30,7 +31,8 @@ def generate_initial(theater: ConflictTheater, enemy: str, sams: bool):
|
||||
if not sams:
|
||||
unittypes = [x for x in unittypes if x not in db.SAM_BAN]
|
||||
|
||||
count = max(COUNT_BY_TASK[task] * importance_factor, 1)
|
||||
count_log = math.log(cp.importance + 0.01, UNIT_COUNT_IMPORTANCE_LOG)
|
||||
count = max(COUNT_BY_TASK[task] * multiplier * (1+count_log), 1)
|
||||
count_per_type = max(int(float(count) / len(unittypes)), 1)
|
||||
for unit_type in unittypes:
|
||||
print("{} - {} {}".format(cp.name, db.unit_type_name(unit_type), count_per_type))
|
||||
|
||||
@ -7,7 +7,8 @@ from ui.window import *
|
||||
class NewGameMenu(Menu):
|
||||
selected_country = None # type: IntVar
|
||||
selected_terrain = None # type: IntVar
|
||||
sams = True
|
||||
sams = None
|
||||
multiplier = None
|
||||
|
||||
def __init__(self, window: Window, callback: typing.Callable):
|
||||
super(NewGameMenu, self).__init__(window, None, None)
|
||||
@ -23,6 +24,9 @@ class NewGameMenu(Menu):
|
||||
self.sams = BooleanVar()
|
||||
self.sams.set(1)
|
||||
|
||||
self.multiplier = StringVar()
|
||||
self.multiplier.set("1")
|
||||
|
||||
@property
|
||||
def player_country_name(self):
|
||||
if self.selected_country.get() == 0:
|
||||
@ -61,7 +65,14 @@ class NewGameMenu(Menu):
|
||||
Label(self.frame, text="Options").grid(row=1, column=2)
|
||||
Checkbutton(self.frame, text="SAMs", variable=self.sams).grid(row=1, column=2)
|
||||
|
||||
Button(self.frame, text="Proceed", command=self.proceed).grid(row=4, column=0, columnspan=3)
|
||||
Label(self.frame, text="Multiplier").grid(row=0, column=3)
|
||||
Entry(self.frame, textvariable=self.multiplier).grid(row=1, column=3)
|
||||
|
||||
Button(self.frame, text="Proceed", command=self.proceed).grid(row=5, column=0, columnspan=4)
|
||||
|
||||
def proceed(self):
|
||||
self.callback(self.player_country_name, self.enemy_country_name, self.terrain_name, bool(self.sams.get()))
|
||||
self.callback(self.player_country_name,
|
||||
self.enemy_country_name,
|
||||
self.terrain_name,
|
||||
bool(self.sams.get()),
|
||||
float(self.multiplier.get()))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user