diff options
Diffstat (limited to 'model.py')
| -rw-r--r-- | model.py | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/model.py b/model.py new file mode 100644 index 0000000..a623d0a --- /dev/null +++ b/model.py @@ -0,0 +1,184 @@ +from math import floor +from csv import reader +from pathlib import Path +from random import sample +from operator import attrgetter +from dataclasses import dataclass + + +@dataclass +class Court: + number: int + status: bool + + +@dataclass +class CourtList: + total: int + + def __post_init__(self): + self.courts = [Court(i + 1, True) for i in range(self.total)] + self.active = self.total + + def get_court(self, court_number: int): + return [court for court in self.courts if court.number == court_number] + + def toggle_court(self, court_number: int): + self.courts = [ + ( + Court( + number=court_number, + status=not court.status, + ) + if court_number == court.number + else court + ) + for court in self.courts + ] + self.active = sum([court.status for court in self.courts]) + + +@dataclass +class Player: + name: str + skill: int = 0 + status: bool = True + + +class PlayerList: + + def __init__(self, location: Path = "players.csv"): + players = [] + with open(location, newline="") as file: + data_reader = reader(file) + next(data_reader, None) + for row in data_reader: + player = Player(name=row[0], skill=row[1], status=(row[2] == "True")) + players.append(player) + players.sort(key=attrgetter("name")) + self.players = players + + def get_player(self, player_request: str): + players = [player for player in self.players if player.name == player_request] + players.sort(key=attrgetter("name")) + return players + + def get_active_players(self): + players = [player for player in self.players if player.status] + players.sort(key=attrgetter("name")) + return players + + def toggle_player(self, player_request: Player): + self.players = [ + ( + Player( + name=player.name, + skill=player.skill, + status=not player.status, + ) + if player.name == player_request + else player + ) + for player in self.players + ] + + def __str__(self): + display_string = "" + for player in self.players: + display_string += player.__str__() + "\n" + return display_string + + +@dataclass +class Team: + player1: Player + player2: Player + + +@dataclass +class Game: + court: Court + team1: Team + team2: Team + + +DUMMY_PLAYER = Player(name="-") +DUMMY_TEAM = Team(player1=DUMMY_PLAYER, player2=DUMMY_PLAYER) + + +def create_dummy_games(courts: list[Court]): + return [Game(court, DUMMY_TEAM, DUMMY_TEAM) for court in courts] + + +RESERVED_PLAYER = Player(name="Reserved") +RESERVED_TEAM = Team(player1=RESERVED_PLAYER, player2=RESERVED_PLAYER) + + +def create_reserved_games(courts: list[Court]): + return [Game(court, RESERVED_TEAM, RESERVED_TEAM) for court in courts] + + +PLAYER_PER_COURT = 4 + + +def create_single_game(court: Court, players: list[Player]): + team1 = Team(player1=players[0], player2=players[3]) + team2 = Team(player1=players[1], player2=players[2]) + return Game(court, team1, team2) + + +def create_possible_games(court_list: list[Court], players: list[Player]): + clumped_players = [ + players[i : i + PLAYER_PER_COURT] + for i in range(0, len(players), PLAYER_PER_COURT) + ] + games = [ + create_single_game(court, clump) + for court, clump in zip(court_list, clumped_players) + ] + return games + + +@dataclass +class GameList: + + def clear(self, court_list: CourtList): + courts = court_list.courts + active_courts = [court for court in courts if court.status] + inactive_courts = [court for court in courts if not court.status] + dummy_games = create_dummy_games(active_courts) + reserved_games = create_reserved_games(inactive_courts) + games = dummy_games + reserved_games + games.sort(key=attrgetter("court.number")) + self.games = games + + def create_random_games(self, court_list: CourtList, player_list: PlayerList): + active_players = player_list.get_active_players() + active_courts = [court for court in court_list.courts if court.status] + inactive_courts = [court for court in court_list.courts if not court.status] + possible_games = floor(len(active_players) / PLAYER_PER_COURT) + current_players = sample(active_players, possible_games * PLAYER_PER_COURT) + active_games = create_possible_games( + active_courts[:possible_games], current_players + ) + dummy_games = create_dummy_games(active_courts[possible_games:]) + reserved_games = create_reserved_games(inactive_courts) + games = active_games + dummy_games + reserved_games + games.sort(key=attrgetter("court.number")) + self.games = games + + def create_skilled_games(self, court_list: CourtList, player_list: PlayerList): + active_players = player_list.get_active_players() + active_courts = [court for court in court_list.courts if court.status] + inactive_courts = [court for court in court_list.courts if not court.status] + possible_games = floor(len(active_players) / PLAYER_PER_COURT) + current_players = sample(active_players, possible_games * PLAYER_PER_COURT) + current_players.sort(key=attrgetter("skill")) + active_games = create_possible_games( + active_courts[:possible_games], current_players + ) + dummy_games = create_dummy_games(active_courts[possible_games:]) + reserved_games = create_reserved_games(inactive_courts) + games = active_games + dummy_games + reserved_games + games.sort(key=attrgetter("court.number")) + self.games = games |
