def new_round(): """ Create a new round for a tournament. """ id_tournament = input("Give ID of the tournament : ") last_round = Tournament.get(id_tournament).rounds[-1].id_round last_round_done = True if Tournament.get(id_tournament).tournament_open: for match in Round.get(last_round).matches: if (match.player_a_score or match.player_b_score) == match.match_in_progress: last_round_done = False break if last_round_done: next_round = int(last_round.split(":")[-1]) + 1 next_round = f"{id_tournament}:{next_round}" RoundManager().create_round(next_round) else: print( f"The round {last_round} is not finished yet, you can't create the next round." ) else: print( f"The tournament {id_tournament} is already finished. You cannot create another round." ) Tournament.load_from_db()
def create_tournament(id_tournament: str): """ Create a new tournament. Arg: * *id_tournament* (str): ID of the **new** tournament """ if not Tournament.get(id_tournament): name_tournament = input("Name the tournament : ") place_tournament = str( input("Where does the tournament happen : ")) number_day_tournament = int( input("How many days will last the tournament : ")) dates_tournaments = [] for i in range(number_day_tournament): day = input(f"Date n°{i} : ") dates_tournaments.append(day) dates_tournaments = " - ".join(map(str, dates_tournaments)) number_players = int(input("How many players : ")) advised_round = 4 number_rounds = input( f"How many rounds (by default: {advised_round}) : ") number_rounds = number_rounds if number_rounds != "" else advised_round time_control = int( input("How long will last matches (in minutes) : ")) description = input("Enter the description of the tournament : ") Tournament(id_tournament, name_tournament, place_tournament, dates_tournaments, number_players, number_rounds, time_control, description) return True else: print("The ID given is already taken.") return False
def create_round(self, id_round: str): """ Create a new round for a tournament. Arg: * *id_round* (str): ID of the round """ id_tournament = id_round.split(":")[0] tournament = Tournament.get(id_tournament) if tournament.tournament_open and len(tournament.rounds) < tournament.number_rounds: if not Round.get(id_round): times = self.get_times(id_tournament) name_round = f"Round {id_round.split(':')[1]}" begin_time = times[0] end_time = times[1] Round(id_round, name_round, begin_time, end_time) if tournament.players: pairs = self.create_pairs(id_tournament) matches = [] for index, (player_a, player_b) in enumerate(pairs): id_match = f"{id_round}:{index + 1}" match = Match(id_match, player_a, player_b) matches.append(match) Round.get(id_round).set_matches(matches) tournament.add_round(Round.get(id_round)) if len(tournament.rounds) >= tournament.number_rounds: tournament.tournament_open = False else: raise Exception(f"Round {id_round} already exists.") else: print("The tournament has already reach his maximum rounds number.")
def show_players_ranked(id_tournament: str): """ Show players sorted by rank in a tournament. Arg: * *id_tournament* (str): ID of the tournament """ players = Tournament.get(id_tournament).players sort_list = [] for player in players: sort_list.append({ "id_player": player.id_player, "points": player.points[id_tournament] if id_tournament in player.points.keys() else 0, "elo": int(player.elo) }) sort_list = sorted(sort_list, key=itemgetter("elo"), reverse=True) sort_list = sorted(sort_list, key=itemgetter("points"), reverse=True) sorted_players = [] for stats in sort_list: id_player = stats["id_player"] sorted_players.append(Player.get(id_player)) for player in sorted_players: print(player, end="") score = player.points[ id_tournament] if id_tournament in player.points.keys() else 0 print(f"\t\t\t\t Score : {score}")
def show_players_alpha(id_tournament: str): """ Show players sorted by alpha in a tournament. Arg: * *id_tournament* (str): ID of the tournament """ players = Tournament.get(id_tournament).players sort_list = [] for player in players: sort_list.append({ "id_player": player.id_player, "last_name": player.last_name, "first_name": player.first_name }) sort_list = sorted(sort_list, key=itemgetter("first_name"), reverse=False) sort_list = sorted(sort_list, key=itemgetter("last_name"), reverse=False) sorted_players = [] for stats in sort_list: id_player = stats["id_player"] sorted_players.append(Player.get(id_player)) for player in sorted_players: print(player, end="") score = player.points[ id_tournament] if id_tournament in player.points.keys() else 0 print(f"\t\t\t\t Score : {score}")
def add_players(id_tournament: str): """ Add players (new or not) to the tournament. Arg: * *id_tournament* (str): ID of the tournament """ tournament = Tournament.get(id_tournament) if tournament and not tournament.rounds: tournament = Tournament.get(id_tournament) list_players = [] for i in range(tournament.number_players): id_player = input( f"Tournament : {tournament.name_tournament}," f" player {i + 1}/{tournament.number_players}\n" f"Give the ID of the player that'll play. " f"If it's a new player, please give an unique" f"ID to register him : ") if not list_players: if Player.get(id_player): list_players.append(Player.get(id_player)) else: PlayerManager.create_player(id_player) list_players.append(Player.get(id_player)) else: for player in list_players: if player.id_player == id_player: print( "This player is already playing this tournament! Please retry : " ) id_player = input( f"Tournament : {tournament.name_tournament}," f" player {i + 1}/{tournament.number_players}\n" f"Give the ID of the player that'll play. " f"If it's a new player, please give an unique" f"ID to register him : ") if Player.get(id_player): list_players.append(Player.get(id_player)) else: PlayerManager().create_player(id_player) list_players.append(Player.get(id_player)) tournament.set_players(list_players) for player in list_players: player.tournaments_played.append(id_tournament) else: raise Exception(f"Tournament ID : {id_tournament} does not exist.")
def show_tournament(id_tournament: str): """ Show a specific tournament. Arg: * *id_tournament* (str): ID of the tournament """ tournament = Tournament.get(id_tournament) print(tournament)
def end_tournament(id_tournament: str): """ Set the tournament closed. Arg: * *id_tournament* (str): ID of the tournament """ tournament = Tournament.get(id_tournament) if tournament: tournament.tournament_open = False
def set_round(): """ Set the winners of a round. """ id_tournament = input("Give ID of the tournament : ") Report.show_all_rounds(id_tournament) id_round = Tournament.get(id_tournament).rounds[-1].id_round round_done = False for match in Round.get(id_round).matches: if (match.player_a_score and match.player_b_score) != match.match_in_progress: round_done = True break if not round_done: RoundManager().set_results(id_round) RoundManager().round_done(id_round) if len(Tournament.get(id_tournament).rounds) == Tournament.get( id_tournament).number_rounds: Tournament.get(id_tournament).set_tournament_finished() elif round_done and Tournament.get(id_tournament).tournament_open: print( f"The round {id_round} is already set, you have to create another round." ) else: print( f"The tournament {id_tournament} is already set and clear. You have to create another tournament." ) Tournament.load_from_db()
def get_times(id_tournament: str): """ Return list of two elements : time_round_begin, time_round_end The format is : Hour:Minute:Second - Day/Month/Year """ time_a = datetime.datetime.now() time_a_strf = time_a.strftime("%H:%M:%S - %d/%b/%Y") time_added = Tournament.get(id_tournament).time_control minutes_added = datetime.timedelta(minutes=time_added) time_b = time_a + minutes_added time_b_strf = time_b.strftime("%H:%M:%S - %d/%b/%Y") return time_a_strf, time_b_strf
def add_round(id_tournament: str): """ Add a round on the tournament. Arg: * *id_tournament* (str): ID of the tournament """ tournament = Tournament.get(id_tournament) if tournament: if tournament.tournament_open: if len(tournament.rounds) < tournament.number_rounds: id_round = f"{len(tournament.rounds)}" RoundManager().create_round(id_round) else: raise Exception( "Maximum rounds for this tournament is already reached" ) else: raise Exception("The Tournament is already finished") else: raise Exception(f"There is no tournament : {id_tournament}")
def sort_players_by_score(id_tournament: str): """ Sort the players by score, including also the elo. score > elo Arg: * *id_tournament* (str): ID of the tournament """ players = Tournament.get(id_tournament).players list_stats = [] for player in players: list_stats.append({"id_player": player.id_player, "elo": int(player.elo), "score": player.points[id_tournament] if id_tournament in player.points.keys() else 0 }) list_stats = sorted(list_stats, key=itemgetter("elo"), reverse=True) list_stats = sorted(list_stats, key=itemgetter("score"), reverse=True) list_players = [] for item in list_stats: list_players.append(Player.get(item["id_player"])) return list_players
def create_pairs(self, id_tournament: str, offset_first=0, offset_last=0): """ Create pairs of players that'll play against each other for the next round. Args: * *id_tournament* (str): ID of the tournament * *offset* (int): An offset used when players already played together """ tournament = Tournament.get(id_tournament) players = self.sort_players_by_score(id_tournament) number_matches = len(players) // 2 pairs = [] if self.check_first_round(tournament): for i in range(number_matches): player_a = players[i] player_b = players[i + number_matches] pairs.append([player_a, player_b]) return pairs else: # Not first round : tables = [[] for _ in range(number_matches)] number_first_tables = (number_matches//2) + 1 if number_matches % 2 else number_matches//2 # Create subdivisions first_tables = [i for i in range(number_first_tables)] last_tables = [i for i in range(number_first_tables, number_matches)] # Isolate firsts players of each subdivisions last_tables_player = players.pop((last_tables[0]*2) + 1) first_tables_player = players.pop(first_tables[0]) # Place firsts players in firsts tables of subdivisions tables[first_tables[0]].append(first_tables_player) tables[last_tables[0]].append(last_tables_player) # List of each subdivisions' players players_first = [player for player in players[:(number_first_tables*2)-1]] players_last = [player for player in players[(number_first_tables*2)-1:]] target = first_tables[0] for _ in range(len(players_first)): player = players_first.pop(offset_first) if len(players_first) > offset_first \ else players_first.pop(0) tables[target].append(player) if len(tables[target]) >= 2: player_a = tables[target][0] player_b = tables[target][1] if f"{id_tournament}:{player_a.id_player}" in player_b.matches_passed: offset_first += 1 return self.create_pairs(id_tournament, offset_first, offset_last) else: target += 1 target = last_tables[0] len_players_last = len(players_last) for _ in range(len_players_last): player = players_last.pop(offset_last) if offset_last < len(players_last) \ else players_last.pop(0) tables[target].append(player) if len(tables[target]) >= 2: player_a = tables[target][0] player_b = tables[target][1] if f"{id_tournament}:{player_a.id_player}" in player_b.matches_passed: offset_last += 1 self.create_pairs(id_tournament, offset_first, offset_last) else: target += 1 if target >= number_matches: return tables return pairs