fix war tie ranking with bonus campaign ranking

This commit is contained in:
Maxime Réaux 2026-02-26 14:57:47 +01:00
parent 3fe3bb331c
commit e7d3b962ca
2 changed files with 66 additions and 1 deletions

View file

@ -133,7 +133,6 @@ class WarController:
RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war_id RefreshScope.WARS_TREE, item_type=ItemType.WAR, item_id=war_id
) )
# TODO fix ignored campaign tie-breaks
def resolve_ties( def resolve_ties(
self, war: War, contexts: List[TieContext] self, war: War, contexts: List[TieContext]
) -> Dict[Tuple[ContextType, str, int | None], Dict[str, bool]]: ) -> Dict[Tuple[ContextType, str, int | None], Dict[str, bool]]:
@ -150,6 +149,7 @@ class WarController:
for pid in active for pid in active
] ]
counters = [war.get_influence_tokens(pid) for pid in active] counters = [war.get_influence_tokens(pid) for pid in active]
# TODO fix sorted participants included in tie-break after campaign ranking
dialog = TieDialog( dialog = TieDialog(
parent=self.app.view, parent=self.app.view,
players=players, players=players,

View file

@ -45,6 +45,39 @@ class ResultChecker:
current_rank = 1 current_rank = 1
for vp in sorted_vps: for vp in sorted_vps:
participants = vp_buckets[vp] participants = vp_buckets[vp]
if context_type == ContextType.WAR and len(participants) > 1:
subgroups = ResultChecker._secondary_sorting_war(war, participants)
for subgroup in subgroups:
# no tie if campaigns' rank is enough to sort
if len(subgroup) == 1:
ranking.append(
(current_rank, subgroup, {pid: 0 for pid in subgroup})
)
current_rank += 1
continue
# normal tie-break if tie persists
if not TieResolver.is_tie_resolved(
war, context_type, context_id, vp
):
ranking.append(
(current_rank, subgroup, {pid: 0 for pid in subgroup})
)
current_rank += 1
continue
groups = TieResolver.rank_by_tokens(
war,
context_type,
context_id,
subgroup,
)
tokens_spent = TieResolver.tokens_spent_map(
war, context_type, context_id, subgroup
)
for group in groups:
group_tokens = {pid: tokens_spent[pid] for pid in group}
ranking.append((current_rank, group, group_tokens))
current_rank += 1
continue
# no tie # no tie
if len(participants) == 1 or not TieResolver.is_tie_resolved( if len(participants) == 1 or not TieResolver.is_tie_resolved(
war, context_type, context_id, vp war, context_type, context_id, vp
@ -69,3 +102,35 @@ class ResultChecker:
ranking.append((current_rank, group, group_tokens)) ranking.append((current_rank, group, group_tokens))
current_rank += 1 current_rank += 1
return ranking return ranking
@staticmethod
def _secondary_sorting_war(
war: War,
participants: List[str],
) -> List[List[str]]:
from warchron.model.score_service import ScoreService
rank_map: Dict[str, Tuple[int, ...]] = {}
for pid in participants:
ranks: List[int] = []
for campaign in war.campaigns:
scores = ScoreService.compute_scores(
war, ContextType.CAMPAIGN, campaign.id
)
ranking = ResultChecker.get_effective_ranking(
war, ContextType.CAMPAIGN, campaign.id, scores
)
for rank, group, _ in ranking:
if pid in group:
ranks.append(rank)
break
rank_map[pid] = tuple(ranks)
sorted_items = sorted(rank_map.items(), key=lambda x: x[1])
groups: List[List[str]] = []
current_tuple = None
for pid, rank_tuple in sorted_items:
if rank_tuple != current_tuple:
groups.append([])
current_tuple = rank_tuple
groups[-1].append(pid)
return groups