from typing import TYPE_CHECKING if TYPE_CHECKING: from warchron.controller.app_controller import AppController from warchron.constants import ContextType from warchron.model.exception import ForbiddenOperation from warchron.model.war_event import TieResolved from warchron.model.war import War from warchron.model.campaign import Campaign from warchron.model.battle import Battle from warchron.model.round import Round from warchron.model.closure_service import ClosureService from warchron.model.tie_manager import TieResolver from warchron.controller.dtos import TieContext class ClosureWorkflow: def __init__(self, controller: "AppController"): self.app = controller class RoundClosureWorkflow(ClosureWorkflow): def start(self, war: War, campaign: Campaign, round: Round) -> None: ClosureService.check_round_closable(round) ties = TieResolver.find_round_ties(round, war) while ties: contexts = [ RoundClosureWorkflow.build_battle_context(campaign, b) for b in ties ] resolvable = [] for ctx in contexts: if TieResolver.can_tie_be_resolved(war, ctx.participants): resolvable.append(ctx) else: war.events.append( TieResolved( participant_id=None, context_type=ctx.context_type, context_id=ctx.context_id, ) ) if not resolvable: break bids_map = self.app.rounds.resolve_ties(war, contexts) for ctx in contexts: bids = bids_map[ctx.context_id] TieResolver.apply_bids( war, ctx.context_type, ctx.context_id, bids, ) TieResolver.try_tie_break( war, ctx.context_type, ctx.context_id, ctx.participants, ) ties = TieResolver.find_round_ties(round, war) for battle in round.battles.values(): ClosureService.apply_battle_outcomes(war, campaign, battle) ClosureService.finalize_round(round) @staticmethod def build_battle_context(campaign: Campaign, battle: Battle) -> TieContext: if battle.player_1_id is None or battle.player_2_id is None: raise ForbiddenOperation("Missing player(s) in this battle context.") p1 = campaign.participants[battle.player_1_id].war_participant_id p2 = campaign.participants[battle.player_2_id].war_participant_id return TieContext( context_type=ContextType.BATTLE, context_id=battle.sector_id, participants=[p1, p2], )