from math import floor from typing import Tuple from random import shuffle from pandas import read_csv from random import randint, getrandbits, sample from names import get_first_name, get_last_name from match_up.data import Player, DisplayPlayer, Team, Game from match_up.data import ( MIN_LEVEL, MAX_LEVEL, PLAYER_PER_COURT, GUESTS_PER_LEVEL, GUEST_LEVELS, ) 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.append(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 _init_guests(session) -> None: for level_id, level in enumerate(GUEST_LEVELS): for player_id in range(GUESTS_PER_LEVEL): unique_id = (level_id * GUESTS_PER_LEVEL) + player_id + 1 player = Player( id=-unique_id, first="Guest", last=str(unique_id), level=level, status=False, count=0, ) session.add(player) session.commit() def _init_database_from_csv(session, csv_location: str) -> None: data = read_csv(csv_location) session.query(Player).delete() for _, entry in data.iterrows(): player = Player( id=entry["id"], first=entry["first"], last=entry["last"], level=entry["skill"], status=False, count=0, ) session.add(player) session.commit() _init_guests(session) def _init_random_database(session, player_count: int = 80) -> None: total_teams = 5 players_per_team = 5 for i in range(player_count): if i < total_teams * players_per_team: team = floor(i / players_per_team) + 1 else: team = 0 player = Player( id=i, first=get_first_name(), last=get_last_name(), level=randint(MIN_LEVEL, MAX_LEVEL), team=team, status=bool(getrandbits(1)), count=0, ) session.add(player) session.commit() _init_guests(session)