From 1c67a2e4cf7d4f1c48772538b7f3a022bea8afc3 Mon Sep 17 00:00:00 2001 From: Vasiliy Horbachenko Date: Wed, 13 Jun 2018 03:33:08 +0300 Subject: [PATCH] number of minor fixes --- __init__.py | 8 -------- game/db.py | 30 ++++++++++++++++++++++++++++-- game/event.py | 15 ++++++++++----- game/game.py | 16 ++++++++-------- game/operation.py | 15 +++++++++++++-- gen/__init__.py | 4 ---- gen/aaa.py | 24 ++++++++++++++++++++++++ gen/shipgen.py | 4 ++-- theater/caucasus.py | 1 + theater/controlpoint.py | 7 +++---- theater/start_generator.py | 9 +++++---- ui/eventmenu.py | 2 +- ui/eventresultsmenu.py | 2 +- userdata/persistency.py | 13 ++++++++----- 14 files changed, 104 insertions(+), 46 deletions(-) diff --git a/__init__.py b/__init__.py index 2b376f4f..ac81e178 100755 --- a/__init__.py +++ b/__init__.py @@ -9,14 +9,6 @@ from game.game import Game from theater import start_generator from userdata import persistency -from dcs.lua.parse import loads - -with open("/Users/sp/Downloads/won_cap.log", "r") as f: - s = f.read() - print(loads(s)) - -#sys.exit(0) - game = persistency.restore_game() if not game: theater = theater.caucasus.CaucasusTheater() diff --git a/game/db.py b/game/db.py index 89cf2b7c..49476504 100644 --- a/game/db.py +++ b/game/db.py @@ -2,6 +2,7 @@ import typing from dcs.vehicles import * from dcs.unitgroup import * +from dcs.ships import * from dcs.planes import * from dcs.task import * from dcs.unittype import * @@ -51,11 +52,36 @@ UNIT_BY_TASK = { CAP: [Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, Armor.APC_BTR_80, ], AirDefence: [AirDefence.AAA_ZU_23_on_Ural_375, AirDefence.SAM_Avenger_M1097 ], Transport: [IL_76MD, S_3B_Tanker, ], + Carriage: [CVN_74_John_C__Stennis, CV_1143_5_Admiral_Kuznetsov, ], } UNIT_BY_COUNTRY = { - "Russia": [Su_25T, Su_27, Su_33, Su_25, MiG_15bis, MiG_21Bis, MiG_29A, AirDefence.AAA_ZU_23_on_Ural_375, Armor.APC_BTR_80, Armor.MBT_T_90, Armor.MBT_T_80U, Armor.MBT_T_55, IL_76MD, ], - "USA": [F_15C, A_10C, F_A_18C, AV8BNA, Armor.MBT_M1A2_Abrams, Armor.MBT_M60A3_Patton, Armor.ATGM_M1134_Stryker, S_3B_Tanker, AirDefence.SAM_Avenger_M1097], + "Russia": [ + Su_25T, + Su_27, + Su_33, + Su_25, + MiG_15bis, + MiG_21Bis, + MiG_29A, + AirDefence.AAA_ZU_23_on_Ural_375, + Armor.APC_BTR_80, + Armor.MBT_T_90, + Armor.MBT_T_80U, + Armor.MBT_T_55, + IL_76MD, + CV_1143_5_Admiral_Kuznetsov], + + "USA": [F_15C, + A_10C, + F_A_18C, + AV8BNA, + Armor.MBT_M1A2_Abrams, + Armor.MBT_M60A3_Patton, + Armor.ATGM_M1134_Stryker, + S_3B_Tanker, + AirDefence.SAM_Avenger_M1097, + CVN_74_John_C__Stennis], } UnitsDict = typing.Dict[UnitType, int] diff --git a/game/event.py b/game/event.py index ee691e7a..e435bd68 100644 --- a/game/event.py +++ b/game/event.py @@ -91,7 +91,8 @@ class GroundInterceptEvent(Event): typecount = max(math.floor(self.difficulty * self.TARGET_AMOUNT_FACTOR), 1) self.targets = {unittype: typecount for unittype in unittypes} - op = GroundInterceptOperation(attacker_name=self.attacker_name, + op = GroundInterceptOperation(theater=self.theater, + attacker_name=self.attacker_name, defender_name=self.defender_name, attacker_clients=clients, defender_clients={}, @@ -145,7 +146,8 @@ class InterceptEvent(Event): airdefense_unit = db.find_unittype(AirDefence, self.defender_name)[0] - op = InterceptOperation(attacker_name=self.attacker_name, + op = InterceptOperation(theater=self.theater, + attacker_name=self.attacker_name, defender_name=self.defender_name, attacker_clients=clients, defender_clients={}, @@ -164,7 +166,8 @@ class InterceptEvent(Event): self.transport_unit = random.choice(db.find_unittype(Transport, self.defender_name)) assert self.transport_unit is not None - op = InterceptOperation(attacker_name=self.attacker_name, + op = InterceptOperation(theater=self.theater, + attacker_name=self.attacker_name, defender_name=self.defender_name, attacker_clients={}, defender_clients=clients, @@ -216,7 +219,8 @@ class CaptureEvent(Event): escort = self.from_cp.base.scramble_sweep(self.to_cp) attackers = self.from_cp.base.assemble_cap(self.to_cp) - op = CaptureOperation(attacker_name=self.attacker_name, + op = CaptureOperation(theater=self.theater, + attacker_name=self.attacker_name, defender_name=self.defender_name, attacker_clients={}, defender_clients=clients, @@ -235,7 +239,8 @@ class CaptureEvent(Event): def player_attacking(self, cas: db.PlaneDict, escort: db.PlaneDict, armor: db.ArmorDict, clients: db.PlaneDict): interceptors = self.to_cp.base.scramble_sweep(for_target=self.to_cp) - op = CaptureOperation(attacker_name=self.attacker_name, + op = CaptureOperation(theater=self.theater, + attacker_name=self.attacker_name, defender_name=self.defender_name, attacker_clients=clients, defender_clients={}, diff --git a/game/game.py b/game/game.py index 7e635dab..37961a84 100644 --- a/game/game.py +++ b/game/game.py @@ -17,31 +17,31 @@ COMMISION_AMOUNTS_FACTORS = { } -ENEMY_INTERCEPT_PROBABILITY_BASE = 10 +ENEMY_INTERCEPT_PROBABILITY_BASE = 5 ENEMY_INTERCEPT_GLOBAL_PROBABILITY_BASE = 1 ENEMY_CAPTURE_PROBABILITY_BASE = 3 -PLAYER_INTERCEPT_PROBABILITY_BASE = 100 -PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 100 -PLAYER_GLOBALINTERCEPT_PROBABILITY_BASE = 100 +PLAYER_INTERCEPT_PROBABILITY_BASE = 30 +PLAYER_GROUNDINTERCEPT_PROBABILITY_BASE = 30 PLAYER_INTERCEPT_GLOBAL_PROBABILITY_BASE = 50 PLAYER_INTERCEPT_GLOBAL_PROBABILITY_LOG = 2 -PLAYER_BUDGET_BASE = 25 +PLAYER_BUDGET_INITIAL = 60 +PLAYER_BUDGET_BASE = 20 PLAYER_BUDGET_IMPORTANCE_LOG = 2 class Game: - budget = 45 + budget = PLAYER_BUDGET_INITIAL events = None # type: typing.List[Event] pending_transfers = None # type: typing.Dict[] def __init__(self, theater: ConflictTheater): self.events = [] self.theater = theater - self.player = "Russia" - self.enemy = "USA" + self.player = "USA" + self.enemy = "Russia" def _roll(self, prob, mult): return random.randint(0, 100) <= prob * mult diff --git a/game/operation.py b/game/operation.py index 52c92127..bd2fa753 100644 --- a/game/operation.py +++ b/game/operation.py @@ -19,12 +19,14 @@ class Operation: shipgen = None # type: ShipGenerator def __init__(self, + theater: ConflictTheater, attacker_name: str, defender_name: str, attacker_clients: db.PlaneDict, defender_clients: db.PlaneDict, from_cp: ControlPoint, to_cp: ControlPoint = None): + self.theater = theater self.attacker_name = attacker_name self.defender_name = defender_name self.attacker_clients = attacker_clients @@ -41,11 +43,15 @@ class Operation: self.aagen = AAConflictGenerator(mission, conflict) self.shipgen = ShipGenerator(mission, conflict) + player_name = self.from_cp.captured and self.attacker_name or self.defender_name + enemy_name = self.from_cp.captured and self.defender_name or self.attacker_name + self.extra_aagen = ExtraAAConflictGenerator(mission, conflict, self.theater, player_name, enemy_name) + def prepare(self, is_quick: bool): self.starting_position = is_quick and self.from_cp.at or None def generate(self): - pass + self.extra_aagen.generate() def units_of(self, country_name: str) -> typing.Collection[UnitType]: return [] @@ -86,6 +92,7 @@ class CaptureOperation(Operation): mission.country(self.defender_name))) def generate(self): + super(CaptureOperation, self).generate() self.armorgen.generate(self.attack, self.defense) self.aagen.generate(self.aa) self.airgen.generate_defense(self.intercept, clients=self.defender_clients) @@ -129,12 +136,15 @@ class InterceptOperation(Operation): conflict=conflict) def generate(self): + super(InterceptOperation, self).generate() self.airgen.generate_transport(self.transport, self.to_cp.at) self.airgen.generate_transport_escort(self.escort, clients=self.defender_clients) self.aagen.generate(self.airdefense) if self.from_cp.is_global: - self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.shipgen.generate(self.from_cp.at)) + ship = self.shipgen.generate(type=db.find_unittype(Carriage, self.attacker_name)[0], + at=self.from_cp.at) + self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=ship) else: self.airgen.generate_interception(self.interceptors, clients=self.attacker_clients, at=self.starting_position) @@ -163,5 +173,6 @@ class GroundInterceptOperation(Operation): conflict=conflict) def generate(self): + super(GroundInterceptOperation, self).generate() self.airgen.generate_cas(self.strikegroup, clients=self.attacker_clients, at=self.starting_position) self.armorgen.generate({}, self.target) diff --git a/gen/__init__.py b/gen/__init__.py index 6d3d2097..858820db 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -1,6 +1,2 @@ import dcs -from .armor import * -from .aircraft import * -from .aaa import * - diff --git a/gen/aaa.py b/gen/aaa.py index 596a558c..ab93c373 100644 --- a/gen/aaa.py +++ b/gen/aaa.py @@ -1,11 +1,13 @@ from game import db +from theater.conflicttheater import ConflictTheater from .conflictgen import * from .naming import * from dcs.mission import * DISTANCE_FACTOR = 4, 5 +EXTRA_AA_MIN_DISTANCE = 70000 class AAConflictGenerator: def __init__(self, mission: Mission, conflict: Conflict): @@ -25,3 +27,25 @@ class AAConflictGenerator: position=p, group_size=1) + +class ExtraAAConflictGenerator: + def __init__(self, mission: Mission, conflict: Conflict, theater: ConflictTheater, player_name: Country, enemy_name: Country): + self.mission = mission + self.theater = theater + self.conflict = conflict + self.player_name = player_name + self.enemy_name = enemy_name + + def generate(self): + for cp in self.theater.controlpoints: + if cp.position.distance_to_point(self.conflict.position) > EXTRA_AA_MIN_DISTANCE: + country_name = cp.captured and self.player_name or self.enemy_name + + self.mission.vehicle_group( + country=self.mission.country(country_name), + name=namegen.next_ground_group_name(), + _type=random.choice(db.find_unittype(AirDefence, country_name)), + position=cp.position, + group_size=2 + ) + diff --git a/gen/shipgen.py b/gen/shipgen.py index eb62ab7d..d4763cf7 100644 --- a/gen/shipgen.py +++ b/gen/shipgen.py @@ -11,9 +11,9 @@ class ShipGenerator: self.m = mission self.conflict = conflict - def generate(self, at: Point) -> ShipGroup: + def generate(self, type: ShipType, at: Point) -> ShipGroup: return self.m.ship_group( country=self.conflict.attackers_side, name=namegen.next_transport_group_name(), - _type=dcs.ships.CVN_74_John_C__Stennis, + _type=type, position=at) diff --git a/theater/caucasus.py b/theater/caucasus.py index 055287f3..759cb013 100644 --- a/theater/caucasus.py +++ b/theater/caucasus.py @@ -1,4 +1,5 @@ from dcs.terrain import caucasus +from dcs import mapping from .conflicttheater import * from .base import * diff --git a/theater/controlpoint.py b/theater/controlpoint.py index 762dd50c..72bbf0f7 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -1,11 +1,10 @@ import typing -import dcs -import math from dcs.mapping import * from dcs.country import * +from dcs.terrain import Airport -from gen.conflictgen import * +from gen.conflictgen import Conflict class ControlPoint: @@ -18,7 +17,7 @@ class ControlPoint: def __init__(self, name: str, position: Point, at, radials: typing.Collection[int], size: int, importance: int): import theater.base - self.name = name + self.name = name.split("-")[0] self.position = position self.at = at diff --git a/theater/start_generator.py b/theater/start_generator.py index 4784b291..db07b3bb 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -2,7 +2,7 @@ from theater.base import * from theater.conflicttheater import * UNIT_VARIETY = 2 -UNIT_AMOUNT_FACTOR = 1 +UNIT_AMOUNT_FACTOR = 0.25 def generate_initial(theater: ConflictTheater, enemy: str): @@ -14,15 +14,16 @@ def generate_initial(theater: ConflictTheater, enemy: str): suitable_unittypes = db.find_unittype(task, enemy) suitable_unittypes.sort(key=lambda x: db.PRICES[x], reverse=True) - importance = IMPORTANCE_HIGH * 10 - cp.importance * 10 - units_idx_start = int(importance) + importance = cp.importance * 10 + reversed_importance = IMPORTANCE_HIGH * 10 - cp.importance * 10 + units_idx_start = int(reversed_importance) units_idx_end = units_idx_start + UNIT_VARIETY - print("{} - {}-{}".format(cp.name, units_idx_start, units_idx_end)) range_start = min(len(suitable_unittypes)-1, units_idx_start) range_end = min(len(suitable_unittypes), units_idx_end) unittypes = suitable_unittypes[range_start:range_end] typecount = max(math.floor(importance * UNIT_AMOUNT_FACTOR), 1) + #print("{} - {}-{} {}, {}".format(cp.name, units_idx_start, units_idx_end, unittypes, typecount)) units = {unittype: typecount for unittype in unittypes} cp.base.commision_units(units) diff --git a/ui/eventmenu.py b/ui/eventmenu.py index 57620e71..e2cf8920 100644 --- a/ui/eventmenu.py +++ b/ui/eventmenu.py @@ -64,7 +64,7 @@ class EventMenu(Menu): label("Aircraft") label("Amount", row, 1) label("Client slots", row, 2) - row+=1 + row += 1 for unit_type, count in base.aircraft.items(): scrable_row(unit_type, count) diff --git a/ui/eventresultsmenu.py b/ui/eventresultsmenu.py index b8507023..711aae88 100644 --- a/ui/eventresultsmenu.py +++ b/ui/eventresultsmenu.py @@ -69,7 +69,7 @@ class EventResultsMenu(Menu): def simulate_result(self, player_factor: float, enemy_factor: float): def action(): - debriefing = Debriefing() + debriefing = Debriefing({}) def count_planes(groups: typing.List[FlyingGroup], mult: float) -> typing.Dict[UnitType, int]: result = {} diff --git a/userdata/persistency.py b/userdata/persistency.py index 94144e0b..9b99cbaa 100644 --- a/userdata/persistency.py +++ b/userdata/persistency.py @@ -1,3 +1,4 @@ +import typing import pickle import os import shutil @@ -17,14 +18,15 @@ def _save_file_exists() -> bool: return os.path.exists(_save_file()) -def restore_game() -> Game: +def restore_game() -> typing.Optional[Game]: if not _save_file_exists(): return None try: with open(_save_file(), "rb") as f: return pickle.load(f) - except: + except Exception as e: + print(e) return None @@ -32,7 +34,8 @@ def save_game(game: Game) -> bool: try: with open(_temporary_save_file(), "wb") as f: pickle.dump(game, f) - shutil.copy(_temporary_save_file(), _save_file()) - return True - except: + shutil.copy(_temporary_save_file(), _save_file()) + return True + except Exception as e: + print(e) return False