display effective ranking in campaign participants table
This commit is contained in:
parent
60992c22df
commit
0bfe27e0d3
13 changed files with 176 additions and 8 deletions
|
|
@ -3,7 +3,6 @@ from typing import List
|
|||
|
||||
from warchron.constants import ContextType
|
||||
from warchron.model.exception import ForbiddenOperation
|
||||
from warchron.model.result_checker import ResultChecker
|
||||
from warchron.model.war_event import InfluenceGained
|
||||
from warchron.model.war import War
|
||||
from warchron.model.campaign import Campaign
|
||||
|
|
@ -26,6 +25,8 @@ class ClosureService:
|
|||
|
||||
@staticmethod
|
||||
def apply_battle_outcomes(war: War, campaign: Campaign, battle: Battle) -> None:
|
||||
from warchron.model.result_checker import ResultChecker
|
||||
|
||||
already_granted = any(
|
||||
isinstance(e, InfluenceGained)
|
||||
and e.context_id == f"battle:{battle.sector_id}"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
from __future__ import annotations
|
||||
from typing import List, Tuple, Dict, TYPE_CHECKING
|
||||
from collections import defaultdict
|
||||
|
||||
from warchron.constants import ContextType
|
||||
from warchron.model.war import War
|
||||
from warchron.model.war_event import TieResolved
|
||||
from warchron.model.tie_manager import TieResolver
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from warchron.model.score_service import ParticipantScore
|
||||
|
||||
|
||||
class ResultChecker:
|
||||
|
|
@ -22,3 +30,41 @@ class ResultChecker:
|
|||
return ev.participant_id # None if confirmed draw
|
||||
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_effective_ranking(
|
||||
war: War,
|
||||
context_type: ContextType,
|
||||
context_id: str,
|
||||
scores: Dict[str, ParticipantScore],
|
||||
) -> List[Tuple[int, List[str]]]:
|
||||
vp_buckets: Dict[int, List[str]] = defaultdict(list)
|
||||
for pid, score in scores.items():
|
||||
vp_buckets[score.victory_points].append(pid)
|
||||
sorted_vps = sorted(vp_buckets.keys(), reverse=True)
|
||||
ranking: List[Tuple[int, List[str]]] = []
|
||||
current_rank = 1
|
||||
for vp in sorted_vps:
|
||||
participants = vp_buckets[vp]
|
||||
# no tie
|
||||
if len(participants) == 1:
|
||||
ranking.append((current_rank, participants))
|
||||
current_rank += 1
|
||||
continue
|
||||
tie_id = f"{context_id}:score:{vp}"
|
||||
# tie unresolved → shared rank (theoretically impossible)
|
||||
if not TieResolver.is_tie_resolved(war, context_type, tie_id):
|
||||
ranking.append((current_rank, participants))
|
||||
current_rank += 1
|
||||
continue
|
||||
# apply token ranking
|
||||
groups = TieResolver.rank_by_tokens(
|
||||
war,
|
||||
context_type,
|
||||
tie_id,
|
||||
participants,
|
||||
)
|
||||
for group in groups:
|
||||
ranking.append((current_rank, group))
|
||||
current_rank += 1
|
||||
return ranking
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from typing import Dict, Iterator
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from warchron.model.result_checker import ResultChecker
|
||||
from warchron.constants import ContextType
|
||||
from warchron.model.war import War
|
||||
from warchron.model.battle import Battle
|
||||
|
|
@ -44,6 +43,8 @@ class ScoreService:
|
|||
def compute_scores(
|
||||
war: War, context_type: ContextType, context_id: str
|
||||
) -> Dict[str, ParticipantScore]:
|
||||
from warchron.model.result_checker import ResultChecker
|
||||
|
||||
scores = {
|
||||
pid: ParticipantScore(
|
||||
narrative_points={obj_id: 0 for obj_id in war.objectives}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue