diff --git a/__init__.py b/__init__.py index dc6ee3d3..2bd319b9 100755 --- a/__init__.py +++ b/__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() diff --git a/game/event/antiaastrike.py b/game/event/antiaastrike.py index 4ff8b839..538480fe 100644 --- a/game/event/antiaastrike.py +++ b/game/event/antiaastrike.py @@ -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) diff --git a/game/event/capture.py b/game/event/capture.py index d5020f03..d111a595 100644 --- a/game/event/capture.py +++ b/game/event/capture.py @@ -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()) diff --git a/game/event/event.py b/game/event/event.py index f3bc78e7..8186d1f8 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -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): diff --git a/game/event/groundintercept.py b/game/event/groundintercept.py index 0508e6e7..4aed5f69 100644 --- a/game/event/groundintercept.py +++ b/game/event/groundintercept.py @@ -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) diff --git a/game/event/intercept.py b/game/event/intercept.py index 3758832b..6a6862a2 100644 --- a/game/event/intercept.py +++ b/game/event/intercept.py @@ -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 diff --git a/game/event/navalintercept.py b/game/event/navalintercept.py index be543e6e..55ef552a 100644 --- a/game/event/navalintercept.py +++ b/game/event/navalintercept.py @@ -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) diff --git a/game/game.py b/game/game.py index c475cf10..1b586279 100644 --- a/game/game.py +++ b/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() diff --git a/game/operation/capture.py b/game/operation/capture.py index d8cbdfea..9991065f 100644 --- a/game/operation/capture.py +++ b/game/operation/capture.py @@ -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 diff --git a/game/settings.py b/game/settings.py index 35109dcc..412e6e88 100644 --- a/game/settings.py +++ b/game/settings.py @@ -4,3 +4,4 @@ class Settings: enemy_skill = "Average" only_player_takeoff = False night_disabled = False + multiplier = 1 diff --git a/theater/base.py b/theater/base.py index e682e755..39da431e 100644 --- a/theater/base.py +++ b/theater/base.py @@ -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()) diff --git a/theater/start_generator.py b/theater/start_generator.py index 2ef76ec6..596a6b69 100644 --- a/theater/start_generator.py +++ b/theater/start_generator.py @@ -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)) diff --git a/ui/newgamemenu.py b/ui/newgamemenu.py index cf87e9a9..1a90f3e2 100644 --- a/ui/newgamemenu.py +++ b/ui/newgamemenu.py @@ -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()))