from typing import Tuple from random import shuffle, sample from app.data import Player, DisplayPlayer, Team, Game from app.data import MAX_LEVEL, PLAYER_PER_COURT def _shuffle_two_lists(a: list, b: list) -> Tuple[list, list]: indices = list(range(len(a))) shuffle(indices) a = [a[index] for index in indices] b = [b[index] for index in indices] return a, b def _pick_from_list_after_sorting_other(a: list, b: list[int]) -> list: indices = [i[0] for i in sorted(enumerate(b), key=lambda x: x[1])] return [a[index] for index in indices] def sample_list(indices: list, cost: list[int], count=None) -> list: if count is None: count = len(indices) indices, cost = _shuffle_two_lists(indices, cost) indices = _pick_from_list_after_sorting_other(indices, cost)[:count] return indices def _create_placeholders(courts: dict, name: str) -> list[Game]: dummy_player = Player(id=-1, first=name) dummy_team = Team( player1=DisplayPlayer(dummy_player), player2=DisplayPlayer(dummy_player) ) games = [Game(court, dummy_team, dummy_team) for court in courts] return games def _normalize_skill(level: int, new_max: int) -> int: new_level = round((new_max - 1) * (level / MAX_LEVEL)) + 1 return new_level def _select_players(players: list[Player], count: int) -> list[Player]: identifiers = [player.id for player in players] play_count = [int(player.count) for player in players] ids = sample_list(identifiers, play_count, count) selected_players = [player for player in players if player.id in ids] return selected_players def _create_groups_of_four_players( players: list[Player], new_max: int ) -> list[list[Player]]: identifiers = [player.id for player in players] player_levels = [_normalize_skill(int(player.level), new_max) for player in players] identifiers = sample_list(identifiers, player_levels) court_players = [] for i in range(0, len(players), PLAYER_PER_COURT): court_ids = identifiers[i : i + PLAYER_PER_COURT] selected_players = [player for player in players if player.id in court_ids] court_players.append(selected_players) return court_players def _create_shuffle_games( courts: dict, players: list[Player], levels: int ) -> list[Game]: court_players = _create_groups_of_four_players(players, levels) games = [] for court, players in zip(courts, court_players): team1 = Team( player1=DisplayPlayer(players[0]), player2=DisplayPlayer(players[3]) ) team2 = Team( player1=DisplayPlayer(players[1]), player2=DisplayPlayer(players[2]) ) games.append(Game(court, team1, team2)) return games def _create_team_games(courts: dict, teams: dict) -> tuple[list[Game], list[Player]]: games = [] selected_players = [] for court, (_, players) in zip(courts, teams.items()): players = sample(players, PLAYER_PER_COURT) selected_players += players players.sort(key=lambda x: x.level, reverse=True) team1 = Team( player1=DisplayPlayer(players[0]), player2=DisplayPlayer(players[3]) ) team2 = Team( player1=DisplayPlayer(players[1]), player2=DisplayPlayer(players[2]) ) games.append(Game(court, team1, team2)) return games, selected_players def separate_teams_and_players(players: list[Player]) -> Tuple[dict, list[Player]]: unique_team_id = {player.team for player in players} grouped_players_by_team = {team_id: [] for team_id in unique_team_id} for player in players: team = player.team grouped_players_by_team[team].append(player) active_teams = {} players_without_team = [] for team_id in grouped_players_by_team: if team_id == 0: players_without_team += [ player for player in grouped_players_by_team[team_id] ] else: if len(grouped_players_by_team[team_id]) >= 4: active_teams[team_id] = grouped_players_by_team[team_id] else: players_without_team += [ player for player in grouped_players_by_team[team_id] ] return active_teams, players_without_team def split_courts(courts: dict, n) -> Tuple[dict, dict]: first_half = {k: v for (k, v) in [x for x in courts.items()][:n]} second_half = {k: v for (k, v) in [x for x in courts.items()][n:]} return first_half, second_half