raise exception on choice/battle constrained update/delete

This commit is contained in:
Maxime Réaux 2026-03-19 11:25:40 +01:00
parent 4396b15c3a
commit f5ad45f671
2 changed files with 67 additions and 22 deletions

View file

@ -47,15 +47,6 @@ class Pairing:
raise DomainError( raise DomainError(
"There are not enough sectors for all participants to battle" "There are not enough sectors for all participants to battle"
) )
for pid, choice in round.choices.items():
if choice is not None and not choice.priority_sector_id:
raise ForbiddenOperation(
f"Missing priority choice for participant {pid}"
)
if choice is not None and not choice.secondary_sector_id:
raise ForbiddenOperation(
f"Missing secondary choice for participant {pid}"
)
def cleanup() -> None: def cleanup() -> None:
for bat in round.battles.values(): for bat in round.battles.values():
@ -74,6 +65,15 @@ class Pairing:
"Do you want to continue?", "Do you want to continue?",
action=cleanup, action=cleanup,
) )
for pid, choice in round.choices.items():
if choice is not None and not choice.priority_sector_id:
raise ForbiddenOperation(
f"Missing priority choice for participant {pid}"
)
if choice is not None and not choice.secondary_sector_id:
raise ForbiddenOperation(
f"Missing secondary choice for participant {pid}"
)
@staticmethod @staticmethod
def assign_battles_to_participants( def assign_battles_to_participants(
@ -226,10 +226,6 @@ class Pairing:
) )
or len(active) <= places or len(active) <= places
): ):
print(
f"Natural or acceptable draw for sector {sector_id} with participants:\n",
context.participants,
)
war.events.append( war.events.append(
TieResolved( TieResolved(
None, None,
@ -246,10 +242,6 @@ class Pairing:
bids = bids_map[current_context.key()] bids = bids_map[current_context.key()]
# confirmed draw if current bids are 0 # confirmed draw if current bids are 0
if bids is not None and not any(bids.values()): 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( war.events.append(
TieResolved( TieResolved(
None, None,

View file

@ -5,7 +5,11 @@ from typing import Any, Dict, List, TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from warchron.model.campaign import Campaign from warchron.model.campaign import Campaign
from warchron.model.war import War from warchron.model.war import War
from warchron.model.exception import ForbiddenOperation from warchron.model.exception import (
ForbiddenOperation,
DomainError,
RequiresConfirmation,
)
from warchron.model.choice import Choice from warchron.model.choice import Choice
from warchron.model.battle import Battle from warchron.model.battle import Battle
@ -95,7 +99,9 @@ class Round:
if self.is_over: if self.is_over:
# TODO catch me if you can # TODO catch me if you can
raise ForbiddenOperation("Can't update choice in a closed round.") raise ForbiddenOperation("Can't update choice in a closed round.")
# TODO prevent if battles already assigned if self.has_battle_with_participant(participant_id):
# TODO catch me if you can (inner)
raise ForbiddenOperation("Can't update choice already assigned to battle.")
choice = self.get_choice(participant_id) choice = self.get_choice(participant_id)
if choice: if choice:
choice.set_priority(priority_sector_id) choice.set_priority(priority_sector_id)
@ -120,7 +126,9 @@ class Round:
if self.is_over: if self.is_over:
# TODO catch me if you can (inner) # TODO catch me if you can (inner)
raise ForbiddenOperation("Can't remove choice in a closed round.") raise ForbiddenOperation("Can't remove choice in a closed round.")
# TODO prevent if battles already assigned if self.has_battle_with_participant(participant_id):
# TODO catch me if you can (inner)
raise ForbiddenOperation("Can't remove choice already assigned to battle.")
self.war.revert_choice_ties( self.war.revert_choice_ties(
self.id, self.id,
participants=[self.campaign.campaign_to_war_part_id(participant_id)], participants=[self.campaign.campaign_to_war_part_id(participant_id)],
@ -185,12 +193,16 @@ class Round:
victory_condition: str | None, victory_condition: str | None,
comment: str | None, comment: str | None,
) -> None: ) -> None:
from warchron.model.pairing import Pairing
if self.is_over: if self.is_over:
# TODO catch me if you can # TODO catch me if you can
raise ForbiddenOperation("Can't update battle in a closed round.") raise ForbiddenOperation("Can't update battle in a closed round.")
bat = self.get_battle(sector_id) bat = self.get_battle(sector_id)
# TODO require confirmation if there was choice tie to clear it if not bat:
if bat: raise DomainError(f"No battle found for sector {sector_id}")
def apply_update() -> None:
bat.set_player_1(player_1_id) bat.set_player_1(player_1_id)
bat.set_player_2(player_2_id) bat.set_player_2(player_2_id)
bat.set_winner(winner_id) bat.set_winner(winner_id)
@ -198,6 +210,47 @@ class Round:
bat.set_victory_condition(victory_condition) bat.set_victory_condition(victory_condition)
bat.set_comment(comment) bat.set_comment(comment)
if bat.player_1_id == player_1_id and bat.player_2_id == player_2_id:
apply_update()
return
affected_choices: List[Choice] = []
affected_players: List[str | None] = list(
{
player_1_id,
player_2_id,
bat.player_1_id,
bat.player_2_id,
}
- {None}
)
for choice in self.choices.values():
for player in affected_players:
if (
player
and self.has_choice_with_participant(player)
and Pairing.participant_spent_token(
self.war,
self.id,
sector_id,
self.campaign.campaign_to_war_part_id(player),
)
):
affected_choices.append(choice)
if not affected_choices:
apply_update()
return
def cleanup_and_update() -> None:
self.clear_sector_references(sector_id)
apply_update()
raise RequiresConfirmation(
"Changing the player(s) of this sector will affect choices.\n"
"Choices will be cleared and their tokens and tie-breaks will be deleted.\n"
"Do you want to continue?",
action=cleanup_and_update,
)
def clear_participant_references(self, participant_id: str) -> None: def clear_participant_references(self, participant_id: str) -> None:
for battle in self.battles.values(): for battle in self.battles.values():
trigger_revert_ties = False trigger_revert_ties = False