summaryrefslogtreecommitdiff
path: root/src/match_up
diff options
context:
space:
mode:
authorKaran Jayachandra <mail@karanjayachandra.com>2024-12-02 20:47:11 +0100
committerKaran Jayachandra <mail@karanjayachandra.com>2024-12-02 20:47:11 +0100
commit662e0854a6c61503954aa659e1c932db69443a06 (patch)
tree8d9cf47a6bbac47fe9eeffbc0d92a1eef4323572 /src/match_up
parented182035cdd39659563b25ffef5387578db25799 (diff)
Fixed bug with team based games
Diffstat (limited to 'src/match_up')
-rw-r--r--src/match_up/controller.py54
-rw-r--r--src/match_up/data.py1
-rw-r--r--src/match_up/model.py71
-rw-r--r--src/match_up/routes.py4
-rw-r--r--src/match_up/utilities.py100
5 files changed, 130 insertions, 100 deletions
diff --git a/src/match_up/controller.py b/src/match_up/controller.py
index 4c7119f..b00bf6b 100644
--- a/src/match_up/controller.py
+++ b/src/match_up/controller.py
@@ -2,7 +2,14 @@ from typing import Tuple
from operator import attrgetter
from match_up.data import Game, PLAYER_PER_COURT
from match_up.model import Player, PlayerList, CourtList
-from match_up.utilities import _create_placeholders, _select_players, _create_shuffle_games, _create_team_games
+from match_up.utilities import (
+ _create_placeholders,
+ _select_players,
+ _create_shuffle_games,
+ _create_team_games,
+ separate_teams_and_players,
+ split_courts,
+)
class RoundGenerator:
@@ -37,33 +44,20 @@ class RoundGenerator:
required_player_count = len(used_courts) * PLAYER_PER_COURT
active_players = self.players.get_players()
if group_by_team:
- unique_team_id = {player.team for player in active_players}
- grouped_players_by_team = {team_id: [] for team_id in unique_team_id}
- for player in active_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]]
-
- regular_courts = len(used_courts) - len(active_teams)
- reg_courts = {A:N for (A,N) in [x for x in used_courts.items()][:regular_courts]}
- team_courts = {A:N for (A,N) in [x for x in used_courts.items()][regular_courts:]}
-
- required_player_count = required_player_count - (PLAYER_PER_COURT * len(active_teams))
- selected_players_without_team = _select_players(players_without_team, required_player_count)
- regular_games = _create_shuffle_games(reg_courts, selected_players_without_team, total_levels)
-
- team_games, selected_players_with_team = _create_team_games(team_courts, active_teams)
-
- selected_players = selected_players_without_team + selected_players_with_team
+ active_teams, team_less_players = separate_teams_and_players(active_players)
+ regular_court_count = len(used_courts) - len(active_teams)
+ regular_courts, team_courts = split_courts(used_courts, regular_court_count)
+ new_player_count = required_player_count - (
+ PLAYER_PER_COURT * len(active_teams)
+ )
+ regular_players = _select_players(team_less_players, new_player_count)
+ regular_games = _create_shuffle_games(
+ regular_courts, regular_players, total_levels
+ )
+ team_games, selected_team_players = _create_team_games(
+ team_courts, active_teams
+ )
+ selected_players = regular_players + selected_team_players
games = regular_games + team_games
else:
selected_players = _select_players(active_players, required_player_count)
@@ -80,7 +74,9 @@ class RoundGenerator:
def propose(self, levels: int, group_by_team: bool) -> list[Game]:
inactive_games = self._create_inactive_games()
- active_games, selected_players = self._create_active_games(levels, group_by_team)
+ active_games, selected_players = self._create_active_games(
+ levels, group_by_team
+ )
games = active_games + inactive_games
games.sort(key=attrgetter("court"))
self.proposed_games = games
diff --git a/src/match_up/data.py b/src/match_up/data.py
index d8996fe..c00dde2 100644
--- a/src/match_up/data.py
+++ b/src/match_up/data.py
@@ -22,7 +22,6 @@ class Player(BASE):
status = Column("status", Integer)
count = Column("count", Integer)
-
def __init__(
self,
id: int,
diff --git a/src/match_up/model.py b/src/match_up/model.py
index 52d72b2..467310b 100644
--- a/src/match_up/model.py
+++ b/src/match_up/model.py
@@ -1,12 +1,23 @@
from math import floor
from typing import Tuple
from os.path import isfile
+from pandas import read_csv
from dataclasses import dataclass
from importlib.resources import path
+from random import getrandbits, randint
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine, not_
-from match_up.data import PLAYER_PER_COURT, BASE, Player, DisplayPlayer
-from match_up.utilities import _init_database_from_csv, _init_random_database
+from names import get_first_name, get_last_name
+from match_up.data import (
+ MIN_LEVEL,
+ MAX_LEVEL,
+ PLAYER_PER_COURT,
+ BASE,
+ GUEST_LEVELS,
+ GUESTS_PER_LEVEL,
+ Player,
+ DisplayPlayer,
+)
@dataclass
@@ -33,6 +44,62 @@ class CourtList:
return active_courts, inactive_courts
+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"],
+ team=entry["team"],
+ 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)
+
+
class PlayerList:
def __init__(self, csv_location=None) -> None:
diff --git a/src/match_up/routes.py b/src/match_up/routes.py
index f9cd2fa..e5a3b99 100644
--- a/src/match_up/routes.py
+++ b/src/match_up/routes.py
@@ -19,7 +19,9 @@ def get_controls():
def get_random_games():
levels = int(request.form["levels"].split()[0])
team_practice = request.form["team"] == "Teams"
- return render_template("games.j2", games=_rg.propose(levels, team_practice), title="Proposal")
+ return render_template(
+ "games.j2", games=_rg.propose(levels, team_practice), title="Proposal"
+ )
@_app.route("/confirm", methods=["POST"])
diff --git a/src/match_up/utilities.py b/src/match_up/utilities.py
index fa82b58..7140a5f 100644
--- a/src/match_up/utilities.py
+++ b/src/match_up/utilities.py
@@ -1,17 +1,7 @@
-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 random import shuffle, sample
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,
-)
+from match_up.data import MAX_LEVEL, PLAYER_PER_COURT
def _shuffle_two_lists(a: list, b: list) -> Tuple[list, list]:
@@ -71,7 +61,9 @@ def _create_groups_of_four_players(
return court_players
-def _create_shuffle_games(courts: dict, players: list[Player], levels: int) -> list[Game]:
+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):
@@ -84,13 +76,14 @@ def _create_shuffle_games(courts: dict, players: list[Player], levels: int) -> l
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)
+ selected_players += players
+ players.sort(key=lambda x: x.level, reverse=True)
team1 = Team(
player1=DisplayPlayer(players[0]), player2=DisplayPlayer(players[3])
)
@@ -101,57 +94,30 @@ def _create_team_games(courts: dict, teams: dict) -> tuple[list[Game], list[Play
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"],
- team=entry["team"],
- status=False,
- count=0,
- )
- session.add(player)
- session.commit()
- _init_guests(session)
+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 _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)
+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