display pairing results in choice table

This commit is contained in:
Maxime Réaux 2026-03-19 09:02:22 +01:00
parent 9e602e8ca4
commit 4396b15c3a
9 changed files with 194 additions and 12 deletions

View file

@ -1,10 +1,11 @@
from __future__ import annotations
from typing import Dict, List, Callable, Tuple
from dataclasses import dataclass
from uuid import uuid4
import random
from warchron.constants import ContextType, ScoreKind
from warchron.constants import ContextType, ScoreKind, ChoiceStatus, AllocationType
from warchron.model.exception import (
DomainError,
ForbiddenOperation,
@ -15,7 +16,7 @@ from warchron.model.round import Round
from warchron.model.battle import Battle
from warchron.model.score_service import ScoreService
from warchron.model.tie_manager import TieResolver, TieContext
from warchron.model.war_event import TieResolved
from warchron.model.war_event import TieResolved, InfluenceSpent
from warchron.model.score_service import ParticipantScore
ResolveTiesCallback = Callable[
@ -24,6 +25,13 @@ ResolveTiesCallback = Callable[
]
@dataclass(frozen=True, slots=True)
class AllocationResult:
priority: ChoiceStatus
secondary: ChoiceStatus
fallback: bool
class Pairing:
@staticmethod
@ -218,6 +226,10 @@ class Pairing:
)
or len(active) <= places
):
print(
f"Natural or acceptable draw for sector {sector_id} with participants:\n",
context.participants,
)
war.events.append(
TieResolved(
None,
@ -234,6 +246,10 @@ class Pairing:
bids = bids_map[current_context.key()]
# confirmed draw if current bids are 0
if bids is not None and not any(bids.values()):
print(
f"Confirmed draw for sector {sector_id} with participants:\n",
context.participants,
)
war.events.append(
TieResolved(
None,
@ -278,3 +294,100 @@ class Pairing:
remaining.remove(pid)
continue
raise DomainError(f"Ambiguous fallback for participant {pid}")
@staticmethod
def get_allocation_kind(
war: War,
round_id: str,
participant_id: str,
sector_id: str,
) -> AllocationType:
round = war.get_round(round_id)
choice = round.choices.get(participant_id)
if not choice:
raise DomainError(f"No choice found for participant {participant_id}")
if choice.priority_sector_id == sector_id:
return AllocationType.PRIORITY
if choice.secondary_sector_id == sector_id:
return AllocationType.SECONDARY
return AllocationType.FALLBACK
@staticmethod
def participant_spent_token(
war: War,
round_id: str,
sector_id: str | None,
war_participant_id: str,
) -> bool:
if sector_id is None:
return False
for ev in war.events:
if not isinstance(ev, InfluenceSpent):
continue
if ev.context_type != ContextType.CHOICE:
continue
if ev.context_id != round_id:
continue
if ev.sector_id != sector_id:
continue
if ev.participant_id == war_participant_id:
return True
return False
@staticmethod
def get_round_allocation(
war: War,
round: Round,
campaign_participant_id: str,
) -> AllocationResult:
choice = round.choices[campaign_participant_id]
campaign = war.get_campaign_by_round(round.id)
if campaign is None:
raise DomainError(f"No campaign found for round {round.id}")
war_pid = campaign.campaign_to_war_part_id(campaign_participant_id)
token_priority = Pairing.participant_spent_token(
war,
round.id,
choice.priority_sector_id,
war_pid,
)
token_secondary = Pairing.participant_spent_token(
war,
round.id,
choice.secondary_sector_id,
war_pid,
)
battle = round.get_battle_for_participant(campaign_participant_id)
allocation = AllocationType.FALLBACK
if battle:
allocation = Pairing.get_allocation_kind(
war,
round.id,
campaign_participant_id,
battle.sector_id,
)
priority_status = ChoiceStatus.NONE
secondary_status = ChoiceStatus.NONE
fallback = allocation == AllocationType.FALLBACK
if allocation == AllocationType.PRIORITY:
priority_status = (
ChoiceStatus.ALLOCATEDTOKEN
if token_priority
else ChoiceStatus.ALLOCATED
)
elif token_priority:
priority_status = ChoiceStatus.TOKEN
if allocation == AllocationType.SECONDARY:
secondary_status = (
ChoiceStatus.ALLOCATEDTOKEN
if token_secondary
else ChoiceStatus.ALLOCATED
)
elif token_secondary:
secondary_status = ChoiceStatus.TOKEN
return AllocationResult(
priority=priority_status,
secondary=secondary_status,
fallback=fallback,
)