resolve pairing WIP

This commit is contained in:
Maxime Réaux 2026-03-11 11:44:57 +01:00
parent 0c6014e946
commit 241d7f10f5
11 changed files with 302 additions and 11 deletions

View file

@ -58,6 +58,7 @@ class AppController:
)
self.view.endCampaignBtn.clicked.connect(self.campaigns.close_campaign)
self.view.endRoundBtn.clicked.connect(self.rounds.close_round)
self.view.resolvePairingBtn.clicked.connect(self.rounds.resolve_pairing)
self.view.on_add_item = self.add_item
self.view.on_edit_item = self.edit_item
self.view.on_delete_item = self.delete_item

View file

@ -7,6 +7,7 @@ from warchron.model.campaign import Campaign
from warchron.model.round import Round
from warchron.model.closure_service import ClosureService
from warchron.model.tie_manager import TieResolver
from warchron.model.pairing import Pairing
class ClosureWorkflow:
@ -94,3 +95,21 @@ class WarClosureWorkflow(ClosureWorkflow):
objective_id,
)
ClosureService.finalize_war(war)
class RoundPairingWorkflow:
def __init__(self, controller: "AppController"):
self.app = controller
def start(self, war: War, round: Round) -> None:
Pairing.check_round_pairable(round)
ties = TieResolver.find_choice_ties(war, round.id)
while ties:
bids_map = self.app.rounds.resolve_ties(war, ties)
for tie in ties:
bids = bids_map[tie.key()]
TieResolver.apply_bids(war, tie, bids)
TieResolver.resolve_tie_state(war, tie, bids)
ties = TieResolver.find_choice_ties(war, round.id)
Pairing.assign_battles_to_participants(war, round)

View file

@ -5,7 +5,11 @@ from PyQt6.QtWidgets import QMessageBox
from PyQt6.QtGui import QIcon
from warchron.constants import ItemType, RefreshScope, Icons, IconName, ContextType
from warchron.model.exception import ForbiddenOperation, DomainError
from warchron.model.exception import (
ForbiddenOperation,
DomainError,
RequiresConfirmation,
)
from warchron.model.tie_manager import TieResolver, TieContext
from warchron.model.result_checker import ResultChecker
from warchron.model.round import Round
@ -20,7 +24,10 @@ from warchron.controller.dtos import (
ChoiceDTO,
BattleDTO,
)
from warchron.controller.closure_workflow import RoundClosureWorkflow
from warchron.controller.closure_workflow import (
RoundClosureWorkflow,
RoundPairingWorkflow,
)
from warchron.view.choice_dialog import ChoiceDialog
from warchron.view.battle_dialog import BattleDialog
from warchron.view.tie_dialog import TieDialog
@ -176,6 +183,39 @@ class RoundController:
RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=round_id
)
def resolve_pairing(self) -> None:
round_id = self.app.navigation.selected_round_id
if not round_id:
return
rnd = self.app.model.get_round(round_id)
war = self.app.model.get_war_by_round(round_id)
workflow = RoundPairingWorkflow(self.app)
try:
workflow.start(war, rnd)
except DomainError as e:
QMessageBox.warning(
self.app.view,
"Closure forbidden",
str(e),
)
return
except RequiresConfirmation as e:
reply = QMessageBox.question(
self.app.view,
"Confirm pairing",
str(e),
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
)
if reply == QMessageBox.StandardButton.Yes:
e.action()
else:
return
self.app.is_dirty = True
self.app.navigation.refresh(RefreshScope.CURRENT_SELECTION_DETAILS)
self.app.navigation.refresh_and_select(
RefreshScope.WARS_TREE, item_type=ItemType.ROUND, item_id=round_id
)
def resolve_ties(
self, war: War, contexts: List[TieContext]
) -> Dict[tuple[str, str, int | None], Dict[str, bool]]: