1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
from typing import Tuple
from operator import attrgetter
from dataclasses import dataclass, field
from match_up.utilities import sample_list
from match_up.model import (
Team,
Game,
Player,
DisplayPlayer,
PlayerList,
CourtList,
MAX_LEVEL,
PLAYER_PER_COURT,
)
def _create_placeholders(courts: dict, name: str) -> list[Game]:
dummy_player = Player(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) -> dict:
identifiers = [player.id for player in players]
play_count = [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(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_games(courts: dict, players: list[Player], levels: int):
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
@dataclass
class RoundGenerator:
courts: CourtList = field(default_factory=lambda: CourtList())
players: PlayerList = field(default_factory=lambda: PlayerList())
round: int = 0
proposal: tuple = tuple()
def __post_init__(self) -> None:
self.games = _create_placeholders(self.courts.get_courts(), "---")
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 _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
active_players = self.players.get_players()
selected_players = _select_players(active_players, required_player_count)
games = _create_games(used_courts, selected_players, total_levels)
return games, selected_players
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"))
return games, selected_players
def clear(self) -> list[Game]:
self.proposal = tuple()
return self.games
def propose(self, levels: int) -> list[Game]:
self.proposal = self._generate_proposal(levels)
return self.proposal[0]
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
identifiers = [player.id for player in proposed_players]
self.players.increment_game_count(identifiers)
self.proposal = tuple()
self.round += 1
return self.games
|