From fb5a5b0608564b717cbc271a6676c8e67120e45b Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Sat, 18 Apr 2026 16:31:21 +0200 Subject: [PATCH] add FFA handling --- .../pages/TournamentDetailsPage.py | 23 +-- .../pages/TournamentTreePage.py | 172 ++++++++++-------- 2 files changed, 104 insertions(+), 91 deletions(-) diff --git a/src/ezgg_lan_manager/pages/TournamentDetailsPage.py b/src/ezgg_lan_manager/pages/TournamentDetailsPage.py index 1cabee9..13314b3 100644 --- a/src/ezgg_lan_manager/pages/TournamentDetailsPage.py +++ b/src/ezgg_lan_manager/pages/TournamentDetailsPage.py @@ -13,7 +13,7 @@ from src.ezgg_lan_manager.components.TournamentDetailsInfoRow import TournamentD from src.ezgg_lan_manager.types.DateUtil import weekday_to_display_text from src.ezgg_lan_manager.types.Team import Team, TeamStatus from src.ezgg_lan_manager.types.Tournament import Tournament -from src.ezgg_lan_manager.types.TournamentBase import TournamentStatus, tournament_status_to_display_text, tournament_format_to_display_texts, ParticipantType +from src.ezgg_lan_manager.types.TournamentBase import TournamentStatus, tournament_status_to_display_text, tournament_format_to_display_texts, ParticipantType, TournamentFormat from src.ezgg_lan_manager.types.User import User from src.ezgg_lan_manager.types.UserSession import UserSession @@ -215,16 +215,17 @@ class TournamentDetailsPage(Component): tournament_status_color = self.session.theme.danger_color elif self.tournament.status == TournamentStatus.ONGOING or self.tournament.status == TournamentStatus.COMPLETED: tournament_status_color = self.session.theme.warning_color - tree_button = Button( - content="Turnierbaum anzeigen", - shape="rectangle", - style="minor", - color="hud", - margin_left=4, - margin_right=4, - margin_top=1, - on_press=self.tree_button_clicked - ) + if self.tournament.format != TournamentFormat.FFA: + tree_button = Button( + content="Turnierbaum anzeigen", + shape="rectangle", + style="minor", + color="hud", + margin_left=4, + margin_right=4, + margin_top=1, + on_press=self.tree_button_clicked + ) ids_of_participants = [p.id for p in self.tournament.participants] color_key: Literal["hud", "danger"] = "hud" diff --git a/src/ezgg_lan_manager/pages/TournamentTreePage.py b/src/ezgg_lan_manager/pages/TournamentTreePage.py index 4bd5e43..14f1567 100644 --- a/src/ezgg_lan_manager/pages/TournamentTreePage.py +++ b/src/ezgg_lan_manager/pages/TournamentTreePage.py @@ -164,88 +164,10 @@ class TournamentTreePage(Component): ) ) else: - try: - file_name = self.tournament.name.replace(" ", "_") + ".json" - games_per_matchup = 1 - if self.tournament.format != TournamentFormat.FFA: - games_per_matchup = int(self.tournament.format.name[-1]) - logger.info(f"Trying to read tournament data from {file_name}") - with open(from_root("tournament_data", file_name), "r") as f: - json_data = json.load(f) - - last_valid_round = None - round_num = 0 - for round_ in json_data["rounds"]: - if all( - match["opponent_1_id"] is not None or match["opponent_2_id"] is not None - for match in round_ - ): - last_valid_round = round_ - round_num += 1 - - if last_valid_round is None: - last_valid_round = json_data["rounds"][0] - - match_infos = [] - if self.tournament.participant_type == ParticipantType.PLAYER: - match_infos = [MatchInfo( - opponent_1=self.id_to_username_map.get(match["opponent_1_id"], ""), - opponent_2=self.id_to_username_map.get(match["opponent_2_id"], ""), - winner=self.id_to_username_map.get(match["winner"], ""), - opponent_1_seat=self.id_to_seat_map.get(match["opponent_1_id"], ""), - opponent_2_seat=self.id_to_seat_map.get(match["opponent_2_id"], ""), - ) for match in last_valid_round] - elif self.tournament.participant_type == ParticipantType.TEAM: - for match in last_valid_round: - team_1: Optional[Team] = next(filter(lambda t: t.id == match["opponent_1_id"], self.teams), None) - team_2: Optional[Team] = next(filter(lambda t: t.id == match["opponent_2_id"], self.teams), None) - winner: Union[str, Team] = next(filter(lambda t: t.id == match["winner"], self.teams), "") - match_infos.append( - MatchInfo( - opponent_1=team_1.name if team_1 is not None else "", - opponent_2=team_2.name if team_2 is not None else "", - winner=winner if isinstance(winner, str) else winner.name, - opponent_1_seat=self._get_seat_for_team(team_1) if team_1 is not None else "", - opponent_2_seat=self._get_seat_for_team(team_2) if team_2 is not None else "", - ) - ) - else: - raise ValueError("Unknown participant type") - - - + if self.tournament.format == TournamentFormat.FFA: content = Column( Text( - text=f"{self.tournament.name}", - style=TextStyle(fill=self.session.theme.background_color), - justify="center", - font_size=1.2 - ), - Text( - text="Finale" if len(json_data["rounds"]) == round_num else f"Runde {round_num}", - style=TextStyle(fill=self.session.theme.background_color), - justify="center", - font_size=0.9, - margin_bottom=1 - ), - Text( - text=f"Spiele pro Matchup: {games_per_matchup}", - style=TextStyle(fill=self.session.theme.background_color), - justify="center", - font_size=0.8 - ), - Text( - text=f"Melde als Verlierer deinen Matchausgang\nim Discord oder an der Orga-Ecke", - style=TextStyle(fill=self.session.theme.background_color), - justify="center", - font_size=0.8 - ), - *match_infos - ) - except (FileNotFoundError, ValueError, AttributeError): - content = Column( - Text( - text=f"Der Turnierbaum für dieses Turnier steht leider nicht zur Verfügung.\n\nBitte melde sich beim Orga-Team.", + text=f"Dieses Turnier hat keinen Turnierbaum.", style=TextStyle(fill=self.session.theme.background_color), margin_top=1, margin_bottom=1, @@ -255,6 +177,96 @@ class TournamentTreePage(Component): justify="center" ) ) + else: + try: + file_name = self.tournament.name.replace(" ", "_") + ".json" + games_per_matchup = int(self.tournament.format.name[-1]) + logger.info(f"Trying to read tournament data from {file_name}") + with open(from_root("tournament_data", file_name), "r") as f: + json_data = json.load(f) + + last_valid_round = None + round_num = 0 + for round_ in json_data["rounds"]: + if all( + match["opponent_1_id"] is not None or match["opponent_2_id"] is not None + for match in round_ + ): + last_valid_round = round_ + round_num += 1 + + if last_valid_round is None: + last_valid_round = json_data["rounds"][0] + + match_infos = [] + if self.tournament.participant_type == ParticipantType.PLAYER: + match_infos = [MatchInfo( + opponent_1=self.id_to_username_map.get(match["opponent_1_id"], ""), + opponent_2=self.id_to_username_map.get(match["opponent_2_id"], ""), + winner=self.id_to_username_map.get(match["winner"], ""), + opponent_1_seat=self.id_to_seat_map.get(match["opponent_1_id"], ""), + opponent_2_seat=self.id_to_seat_map.get(match["opponent_2_id"], ""), + ) for match in last_valid_round] + elif self.tournament.participant_type == ParticipantType.TEAM: + for match in last_valid_round: + team_1: Optional[Team] = next(filter(lambda t: t.id == match["opponent_1_id"], self.teams), None) + team_2: Optional[Team] = next(filter(lambda t: t.id == match["opponent_2_id"], self.teams), None) + winner: Union[str, Team] = next(filter(lambda t: t.id == match["winner"], self.teams), "") + match_infos.append( + MatchInfo( + opponent_1=team_1.name if team_1 is not None else "", + opponent_2=team_2.name if team_2 is not None else "", + winner=winner if isinstance(winner, str) else winner.name, + opponent_1_seat=self._get_seat_for_team(team_1) if team_1 is not None else "", + opponent_2_seat=self._get_seat_for_team(team_2) if team_2 is not None else "", + ) + ) + else: + raise ValueError("Unknown participant type") + + + + content = Column( + Text( + text=f"{self.tournament.name}", + style=TextStyle(fill=self.session.theme.background_color), + justify="center", + font_size=1.2 + ), + Text( + text="Finale" if len(json_data["rounds"]) == round_num else f"Runde {round_num}", + style=TextStyle(fill=self.session.theme.background_color), + justify="center", + font_size=0.9, + margin_bottom=1 + ), + Text( + text=f"Spiele pro Matchup: {games_per_matchup}", + style=TextStyle(fill=self.session.theme.background_color), + justify="center", + font_size=0.8 + ), + Text( + text=f"Melde als Verlierer deinen Matchausgang\nim Discord oder an der Orga-Ecke", + style=TextStyle(fill=self.session.theme.background_color), + justify="center", + font_size=0.8 + ), + *match_infos + ) + except (FileNotFoundError, ValueError, AttributeError): + content = Column( + Text( + text=f"Der Turnierbaum für dieses Turnier steht leider nicht zur Verfügung.\n\nBitte melde sich beim Orga-Team.", + style=TextStyle(fill=self.session.theme.background_color), + margin_top=1, + margin_bottom=1, + align_x=0.5, + overflow="wrap", + min_width=30, + justify="center" + ) + ) return Column( MainViewContentBox(