diff --git a/src/warchron/constants.py b/src/warchron/constants.py index ead7600..a79e5fc 100644 --- a/src/warchron/constants.py +++ b/src/warchron/constants.py @@ -41,34 +41,7 @@ class IconName(str, Enum): WARCHRON = "warchron" TOKEN = "token" TOKENS = "tokens" - VP1ST = "vp1st" - VP2ND = "vp2nd" - VP3RD = "vp3rd" - VPNTH = "vpnth" - NP1ST = "np1st" - NP2ND = "np2nd" - NP3RD = "np3rd" TIEBREAK_TOKEN = auto() - VP1STDRAW = auto() - VP1STBREAK = auto() - VP1STTIEDRAW = auto() - VP2NDDRAW = auto() - VP2NDBREAK = auto() - VP2NDTIEDRAW = auto() - VP3RDDRAW = auto() - VP3RDBREAK = auto() - VP3RDTIEDRAW = auto() - VPNTHDRAW = auto() - VPNTHBREAK = auto() - VPNTHTIEDRAW = auto() - - -RANK_TO_ICON = { - 1: IconName.VP1ST, - 2: IconName.VP2ND, - 3: IconName.VP3RD, - 4: IconName.VPNTH, -} class Icons: @@ -101,13 +74,6 @@ class Icons: IconName.WARCHRON: "warchron_logo_background.png", IconName.TOKEN: "point.png", IconName.TOKENS: "points.png", - IconName.VP1ST: "trophy.png", - IconName.VP2ND: "trophy-silver.png", - IconName.VP3RD: "trophy-bronze.png", - IconName.VPNTH: "ribbon.png", - IconName.NP1ST: "medal.png", - IconName.NP2ND: "medal-silver.png", - IconName.NP3RD: "medal-bronze.png", } @classmethod @@ -126,70 +92,6 @@ class Icons: cls.get_pixmap(IconName.TIEBREAK), cls.get_pixmap(IconName.TOKEN), ) - elif name == IconName.VP1STDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VP1ST), - cls.get_pixmap(IconName.DRAW), - ) - elif name == IconName.VP1STBREAK: - pix = cls._compose( - cls.get_pixmap(IconName.VP1ST), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VP1STTIEDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VP1ST), - cls.get_pixmap(IconName.DRAW), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VP2NDDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VP2ND), - cls.get_pixmap(IconName.DRAW), - ) - elif name == IconName.VP2NDBREAK: - pix = cls._compose( - cls.get_pixmap(IconName.VP2ND), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VP2NDTIEDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VP2ND), - cls.get_pixmap(IconName.DRAW), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VP3RDDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VP3RD), - cls.get_pixmap(IconName.DRAW), - ) - elif name == IconName.VP3RDBREAK: - pix = cls._compose( - cls.get_pixmap(IconName.VP3RD), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VP3RDTIEDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VP3RD), - cls.get_pixmap(IconName.DRAW), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VPNTHDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VPNTH), - cls.get_pixmap(IconName.DRAW), - ) - elif name == IconName.VPNTHBREAK: - pix = cls._compose( - cls.get_pixmap(IconName.VPNTH), - cls.get_pixmap(IconName.TOKEN), - ) - elif name == IconName.VPNTHTIEDRAW: - pix = cls._compose( - cls.get_pixmap(IconName.VPNTH), - cls.get_pixmap(IconName.DRAW), - cls.get_pixmap(IconName.TOKEN), - ) else: path = RESOURCES_DIR / cls._paths[name] pix = QPixmap(path.as_posix()) @@ -197,20 +99,14 @@ class Icons: return pix @staticmethod - def _compose(*pixmaps: QPixmap) -> QPixmap: - if not pixmaps: - return QPixmap() - if len(pixmaps) == 1: - return pixmaps[0] - w = sum(p.width() for p in pixmaps) - h = max(p.height() for p in pixmaps) + def _compose(left: QPixmap, right: QPixmap) -> QPixmap: + w = left.width() + right.width() + h = max(left.height(), right.height()) result = QPixmap(w, h) result.fill(Qt.GlobalColor.transparent) painter = QPainter(result) - x = 0 - for p in pixmaps: - painter.drawPixmap(x, (h - p.height()) // 2, p) - x += p.width() + painter.drawPixmap(0, (h - left.height()) // 2, left) + painter.drawPixmap(left.width(), (h - right.height()) // 2, right) painter.end() return result diff --git a/src/warchron/controller/campaign_controller.py b/src/warchron/controller/campaign_controller.py index 89805db..9447058 100644 --- a/src/warchron/controller/campaign_controller.py +++ b/src/warchron/controller/campaign_controller.py @@ -1,16 +1,8 @@ from typing import List, Dict, TYPE_CHECKING from PyQt6.QtWidgets import QMessageBox, QDialog -from PyQt6.QtGui import QIcon -from warchron.constants import ( - RefreshScope, - ContextType, - ItemType, - Icons, - IconName, - RANK_TO_ICON, -) +from warchron.constants import RefreshScope, ContextType, ItemType if TYPE_CHECKING: from warchron.controller.app_controller import AppController @@ -28,11 +20,10 @@ from warchron.model.campaign_participant import CampaignParticipant from warchron.model.sector import Sector from warchron.model.tie_manager import TieContext, TieResolver from warchron.model.score_service import ScoreService -from warchron.model.result_checker import ResultChecker -from warchron.controller.closure_workflow import CampaignClosureWorkflow from warchron.view.campaign_dialog import CampaignDialog from warchron.view.campaign_participant_dialog import CampaignParticipantDialog from warchron.view.sector_dialog import SectorDialog +from warchron.controller.closure_workflow import CampaignClosureWorkflow from warchron.view.tie_dialog import TieDialog @@ -40,39 +31,6 @@ class CampaignController: def __init__(self, app: "AppController"): self.app = app - def _compute_campaign_ranking_icons( - self, war: War, campaign: Campaign - ) -> Dict[str, QIcon]: - scores = ScoreService.compute_scores( - war, - ContextType.CAMPAIGN, - campaign.id, - ) - ranking = ResultChecker.get_effective_ranking( - war, ContextType.CAMPAIGN, campaign.id, scores - ) - icon_map = {} - for rank, group, token_map in ranking: - base_icon = RANK_TO_ICON.get(rank, IconName.VPNTH) - tie_id = f"{campaign.id}:score:{scores[group[0]].victory_points}" - tie_resolved = TieResolver.is_tie_resolved( - war, ContextType.CAMPAIGN, tie_id - ) - for pid in group: - spent = token_map.get(pid, 0) - if not tie_resolved and spent == 0: - icon_name = getattr(IconName, f"{base_icon.name}DRAW") - elif tie_resolved and spent == 0 and len(group) > 1: - icon_name = getattr(IconName, f"{base_icon.name}DRAW") - elif tie_resolved and spent > 0 and len(group) == 1: - icon_name = getattr(IconName, f"{base_icon.name}BREAK") - elif tie_resolved and spent > 0 and len(group) > 1: - icon_name = getattr(IconName, f"{base_icon.name}TIEDRAW") - else: - icon_name = base_icon - icon_map[pid] = QIcon(Icons.get_pixmap(icon_name)) - return icon_map - def _fill_campaign_details(self, campaign_id: str) -> None: camp = self.app.model.get_campaign(campaign_id) self.app.view.show_campaign_details(name=camp.name, month=camp.month) @@ -94,9 +52,6 @@ class CampaignController: self.app.view.display_campaign_sectors(sectors_for_display) scores = ScoreService.compute_scores(war, ContextType.CAMPAIGN, campaign_id) rows: List[CampaignParticipantScoreDTO] = [] - icon_map = {} - if camp.is_over: - icon_map = self._compute_campaign_ranking_icons(war, camp) for camp_part in camp.get_all_campaign_participants(): war_part_id = camp_part.war_participant_id war_part = war.get_war_participant(war_part_id) @@ -111,7 +66,6 @@ class CampaignController: theme=camp_part.theme or "", victory_points=score.victory_points, narrative_points=dict(score.narrative_points), - rank_icon=icon_map.get(war_part_id), ) ) objectives = [ diff --git a/src/warchron/controller/dtos.py b/src/warchron/controller/dtos.py index 4668ff7..7d52aaf 100644 --- a/src/warchron/controller/dtos.py +++ b/src/warchron/controller/dtos.py @@ -1,4 +1,4 @@ -from typing import List, Dict +from typing import List from dataclasses import dataclass from PyQt6.QtGui import QIcon @@ -112,7 +112,7 @@ class ParticipantScoreDTO: participant_id: str player_name: str victory_points: int - narrative_points: Dict[str, int] + narrative_points: dict[str, int] @dataclass(frozen=True, slots=True) @@ -123,5 +123,4 @@ class CampaignParticipantScoreDTO: leader: str theme: str victory_points: int - narrative_points: Dict[str, int] - rank_icon: QIcon | None = None + narrative_points: dict[str, int] diff --git a/src/warchron/model/closure_service.py b/src/warchron/model/closure_service.py index 6f62997..3816e5c 100644 --- a/src/warchron/model/closure_service.py +++ b/src/warchron/model/closure_service.py @@ -3,6 +3,7 @@ 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 @@ -25,8 +26,6 @@ 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}" diff --git a/src/warchron/model/result_checker.py b/src/warchron/model/result_checker.py index 978b0ce..de07440 100644 --- a/src/warchron/model/result_checker.py +++ b/src/warchron/model/result_checker.py @@ -1,14 +1,6 @@ -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: @@ -30,44 +22,3 @@ 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], Dict[str, int]]]: - 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], Dict[str, int]]] = [] - current_rank = 1 - for vp in sorted_vps: - participants = vp_buckets[vp] - tie_id = f"{context_id}:score:{vp}" - # no tie - if len(participants) == 1 or not TieResolver.is_tie_resolved( - war, context_type, tie_id - ): - ranking.append( - (current_rank, participants, {pid: 0 for pid in participants}) - ) - current_rank += 1 - continue - # apply token ranking - groups = TieResolver.rank_by_tokens( - war, - context_type, - tie_id, - participants, - ) - tokens_spent = TieResolver.tokens_spent_map( - war, context_type, tie_id, participants - ) - for group in groups: - group_tokens = {pid: tokens_spent[pid] for pid in group} - ranking.append((current_rank, group, group_tokens)) - current_rank += 1 - return ranking diff --git a/src/warchron/model/score_service.py b/src/warchron/model/score_service.py index 0fb98b5..16da0ab 100644 --- a/src/warchron/model/score_service.py +++ b/src/warchron/model/score_service.py @@ -1,6 +1,7 @@ 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 @@ -43,8 +44,6 @@ 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} diff --git a/src/warchron/model/tie_manager.py b/src/warchron/model/tie_manager.py index 12b291f..fd678d7 100644 --- a/src/warchron/model/tie_manager.py +++ b/src/warchron/model/tie_manager.py @@ -131,24 +131,6 @@ class TieResolver: groups[-1].append(pid) return groups - @staticmethod - def tokens_spent_map( - war: War, - context_type: ContextType, - context_id: str, - participants: List[str], - ) -> Dict[str, int]: - spent = {pid: 0 for pid in participants} - for ev in war.events: - if ( - isinstance(ev, InfluenceSpent) - and ev.context_type == context_type - and ev.context_id == context_id - and ev.participant_id in spent - ): - spent[ev.participant_id] += ev.amount - return spent - @staticmethod def get_active_participants( war: War, diff --git a/src/warchron/view/resources/medal-bronze.png b/src/warchron/view/resources/medal-bronze.png deleted file mode 100644 index 3f3ff99..0000000 Binary files a/src/warchron/view/resources/medal-bronze.png and /dev/null differ diff --git a/src/warchron/view/resources/medal-silver.png b/src/warchron/view/resources/medal-silver.png deleted file mode 100644 index c578e3a..0000000 Binary files a/src/warchron/view/resources/medal-silver.png and /dev/null differ diff --git a/src/warchron/view/resources/medal.png b/src/warchron/view/resources/medal.png deleted file mode 100644 index 2f82d8b..0000000 Binary files a/src/warchron/view/resources/medal.png and /dev/null differ diff --git a/src/warchron/view/resources/ribbon.png b/src/warchron/view/resources/ribbon.png deleted file mode 100644 index 2bdafcd..0000000 Binary files a/src/warchron/view/resources/ribbon.png and /dev/null differ diff --git a/src/warchron/view/resources/trophy-bronze.png b/src/warchron/view/resources/trophy-bronze.png deleted file mode 100644 index fae6fe5..0000000 Binary files a/src/warchron/view/resources/trophy-bronze.png and /dev/null differ diff --git a/src/warchron/view/resources/trophy-silver.png b/src/warchron/view/resources/trophy-silver.png deleted file mode 100644 index 6a65909..0000000 Binary files a/src/warchron/view/resources/trophy-silver.png and /dev/null differ diff --git a/src/warchron/view/view.py b/src/warchron/view/view.py index fd65300..aae2527 100644 --- a/src/warchron/view/view.py +++ b/src/warchron/view/view.py @@ -475,11 +475,8 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow): table.setColumnCount(len(headers)) table.setHorizontalHeaderLabels(headers) table.setRowCount(len(participants)) - table.setIconSize(QSize(48, 16)) for row, part in enumerate(participants): name_item = QtWidgets.QTableWidgetItem(part.player_name) - if part.rank_icon: - name_item.setIcon(part.rank_icon) lead_item = QtWidgets.QTableWidgetItem(part.leader) theme_item = QtWidgets.QTableWidgetItem(part.theme) VP_item = QtWidgets.QTableWidgetItem(str(part.victory_points)) @@ -557,7 +554,7 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow): table = self.battlesTable table.clearContents() table.setRowCount(len(sectors)) - table.setIconSize(QSize(32, 16)) + self.battlesTable.setIconSize(QSize(32, 16)) for row, battle in enumerate(sectors): sector_item = QtWidgets.QTableWidgetItem(battle.sector_name) if battle.state_icon: