aboutsummaryrefslogtreecommitdiff
path: root/controller.py
diff options
context:
space:
mode:
authorKaran Jayachandra <karan.jayachandra@nxp.com>2024-10-16 11:08:15 +0200
committerKaran Jayachandra <karan.jayachandra@nxp.com>2024-10-16 11:08:15 +0200
commitd304a470e5a9fae6fc0c8975f050cb7aa290f74a (patch)
tree2918384d92c63e6bbe3d3fa642317fa1ab96ac07 /controller.py
parent600b6afff3066d5fc9c4eca659f969322e670a77 (diff)
First working version with history
Diffstat (limited to 'controller.py')
-rw-r--r--controller.py157
1 files changed, 82 insertions, 75 deletions
diff --git a/controller.py b/controller.py
index 45ae2bf..751586e 100644
--- a/controller.py
+++ b/controller.py
@@ -1,102 +1,109 @@
-from math import floor
-from random import sample
+from typing import Tuple
from operator import attrgetter
-from dataclasses import dataclass, field
-from model import Team, Game, PlayerList, CourtList
+from dataclasses import dataclass
+from utilities import sample_list
+from model import Team, Game, PlayerList, CourtList, MAX_LEVEL, PLAYER_PER_COURT
-PLAYER_PER_COURT = 4
-
-def _create_placeholders(courts: dict, name: str):
+def _create_placeholders(courts: dict, name: str) -> list[Game]:
dummy_team = Team(player1=name, player2=name)
- return [Game(court, dummy_team, dummy_team) for court in courts]
-
-
-def create_game(court: int, players: dict):
- ids = list(players.keys())
- team1 = Team(player1=players[ids[0]].name, player2=players[ids[3]].name)
- team2 = Team(player1=players[ids[1]].name, player2=players[ids[2]].name)
- return Game(court, team1, team2)
+ games = [Game(court, dummy_team, dummy_team) for court in courts]
+ return games
-def select_players(players: dict, count: int):
- identifiers = sample(sorted(players), count)
- return {id: players[id] for id in identifiers}
+def _normalize_skill(players: dict, new_max: int) -> int:
+ player_levels = []
+ for _, player in players.items():
+ skill_level = player.skill
+ new_level = round((new_max - 1) * (skill_level / MAX_LEVEL)) + 1
+ player_levels.append(new_level)
+ return player_levels
-def get_random_combinations(players: dict) -> list[dict]:
- ids = list(players.keys())
- clumps = [
- ids[i : i + PLAYER_PER_COURT] for i in range(0, len(players), PLAYER_PER_COURT)
- ]
+def _create_groups_of_four_players(players: dict, new_max: int) -> list[dict]:
+ player_levels = _normalize_skill(players, new_max)
+ identifiers = sample_list([*players], player_levels)
+ clumps = []
+ for i in range(0, len(players), PLAYER_PER_COURT):
+ clumps.append(identifiers[i : i + PLAYER_PER_COURT])
combinations = [{id: players[id] for id in clump} for clump in clumps]
return combinations
-def create_random_games(courts: CourtList, players: PlayerList):
- active_courts, reserved_courts = courts.separate_courts()
-
- # Block the courts for other activities
- reserved_games = _create_placeholders(reserved_courts, "RESERVED")
-
- # Check if there are too many courts
- possible_players = players.separate_players()[0]
- possible_games = floor(len(possible_players) / PLAYER_PER_COURT)
-
- # Create the games
- selected_players = select_players(
- possible_players, possible_games * PLAYER_PER_COURT
- )
- combinations = get_random_combinations(selected_players)
-
- used_courts = dict(list(active_courts.items())[:possible_games])
- active_games = [
- create_game(court, clump) for court, clump in zip(used_courts, combinations)
- ]
-
- # Create dummy games if there are empty courts
- dummy_games = []
- if possible_games < len(active_courts):
- unused_courts = dict(list(active_courts.items())[possible_games:])
- dummy_games = _create_placeholders(unused_courts, "---")
-
- # Return the list of games
- games = active_games + dummy_games + reserved_games
- games.sort(key=attrgetter("court"))
- games = {idx: value for idx, value in enumerate(games)}
+def _create_games(courts: dict, players: list[dict], levels: int):
+ grouped_players = _create_groups_of_four_players(players, levels)
+ games = []
+ for court, players in zip(courts, grouped_players):
+ ids = [*players]
+ team1 = Team(player1=players[ids[0]].name, player2=players[ids[3]].name)
+ team2 = Team(player1=players[ids[1]].name, player2=players[ids[2]].name)
+ games.append(Game(court, team1, team2))
return games
@dataclass
-class Session:
+class RoundGenerator:
courts: CourtList
players: PlayerList
round: int = 0
- games: dict = field(default_factory=dict)
- proposal: dict = field(default_factory=dict)
- history: list[dict] = field(default_factory=list)
+ proposal: tuple = tuple()
+
+ def __post_init__(self) -> None:
+ self.history = {key: 0 for key, _ in self.players.get_players().items()}
+ self.games = self._generate_proposal(MAX_LEVEL)[0]
+
+ def _separate_courts(self, courts: dict) -> Tuple[dict, dict]:
+ possible_games = min(len(courts), self.players.get_possible_game_count())
+ courts_as_list = list(courts.items())
+ used_courts = dict(courts_as_list[:possible_games])
+ unused_courts = dict(courts_as_list[possible_games:])
+ return used_courts, unused_courts
+
+ def _select_players(self, count: int) -> dict:
+ active_players = self.players.get_active_players()
+ identifiers = [*active_players]
+ play_count = [self.history[player_id] for player_id in active_players]
+ ids = sample_list(identifiers, play_count, count)
+ return {player_id: active_players[player_id] for player_id in ids}
+
+ def _create_inactive_games(self) -> list[Game]:
+ active_courts, reserved_courts = self.courts.separate_courts()
+ reserved_games = _create_placeholders(reserved_courts, "RESERVED")
+ _, unused_courts = self._separate_courts(active_courts)
+ blank_games = _create_placeholders(unused_courts, "---")
+ games = reserved_games + blank_games
+ return games
+
+ def _create_active_games(self, total_levels: int):
+ active_courts, _ = self.courts.separate_courts()
+ used_courts, _ = self._separate_courts(active_courts)
+ required_player_count = len(used_courts) * PLAYER_PER_COURT
+ selected_players = self._select_players(required_player_count)
+ games = _create_games(used_courts, selected_players, total_levels)
+ return games, selected_players
- def __post_init__(self):
- self.history = []
- active_courts, inactive_courts = self.courts.separate_courts()
- dummy_games = _create_placeholders(active_courts, "---")
- reserved_games = _create_placeholders(inactive_courts, "RESERVED")
- games = dummy_games + reserved_games
+ def _generate_proposal(self, total_levels: int) -> Tuple[list[Game], dict]:
+ inactive_games = self._create_inactive_games()
+ active_games, selected_players = self._create_active_games(total_levels)
+ games = active_games + inactive_games
games.sort(key=attrgetter("court"))
- games = {idx: value for idx, value in enumerate(games)}
- self.games = games
+ return games, selected_players
- def clear_round(self):
- self.proposal = {}
+ def clear(self) -> list[Game]:
+ self.proposal = tuple()
return self.games
- def propose_round(self, levels: int = 10):
- self.proposal = create_random_games(self.courts, self.players)
- return self.proposal
+ def propose(self, levels: int) -> list[Game]:
+ self.proposal = self._generate_proposal(levels)
+ return self.proposal[0]
- def confirm_round(self):
- self.games = self.proposal
- self.history.append(self.proposal)
- self.proposal = {}
+ def confirm(self) -> list[Game]:
+ proposed_games, proposed_players = self.proposal
+ if self.games == proposed_games or len(proposed_games) == 0:
+ return self.games
+ self.games = proposed_games
+ for player_id in proposed_players:
+ self.history[player_id] = self.history[player_id] + 1
+ self.proposal = tuple()
self.round += 1
return self.games