diff --git a/controllers/base.py b/controllers/base.py index cd8badc..58be14b 100644 --- a/controllers/base.py +++ b/controllers/base.py @@ -1,122 +1,269 @@ -from ChessTournament.models.models import Player, Tournament, Round, Match +from ChessTournament.models.models import (Player, Tournament, Round, Match, + MatchHistory) +from ChessTournament.models.models import DATAPATH, PLAYERFILE, TOURNAMENTFILE from ChessTournament.views.menu import Menu from ChessTournament.views.base import View from random import shuffle +import os +import json -class Controller: +class Save: def __init__(self): - # loading models - self.players_list = [] - self.score_list = [] + pass + + def load_file(self, file): + try: + os.mkdir(DATAPATH) + except FileExistsError: + pass + # test if file exists... could be done more gracefully + try: + with open(file, "r") as json_file: + data_tmp = json.load(json_file) + return data_tmp + + except json.decoder.JSONDecodeError: + print("Erreur de format sur le fichier") + except FileNotFoundError: + return False + + def write_file(self, data_tmp, file): + with open(file, "w") as json_file: + json_file.write(json.dumps(data_tmp)) + return "Done." + + + def player_write(self, player) -> bool: + data_tmp = [] + if self.load_file(PLAYERFILE): + data_tmp = (self.load_file(PLAYERFILE)) + data_tmp.append(player) + self.write_file(data_tmp, PLAYERFILE) + print("Joueur créé !") + return True + + def player_load(self) -> list: + """Load and create player from JSON file + returns: + list of Player""" + if self.load_file(PLAYERFILE): + data_tmp = self.load_file(PLAYERFILE) + data_list = [] + for player in data_tmp: + data_list.append(Player(name=player['name'], + lastname=player['lastname'], + birthdate=player['birthdate'], + ine=player['ine'])) + + return data_list + else: + print("\n**** Pas de fichier joueur trouvé :/\n") + + def tournament_write(self, tournament): + data = { + tournament.name: tournament.data() + } + print(data) + + if self.load_file(TOURNAMENTFILE): + data_tmp = self.load_file(TOURNAMENTFILE) + data_tmp[tournament.name] = tournament.data() + self.write_file(data_tmp, TOURNAMENTFILE) + else: + self.write_file(data, TOURNAMENTFILE) + return True + + def tournament_load(self): + if self.load_file(TOURNAMENTFILE): + data_tmp = self.load_file(TOURNAMENTFILE) + return data_tmp + else: + print("\n**** Pas de fichier tournoi trouvé :/ \n") + + +class Application: + def __init__(self, tournament, save, view, menu): + self.tournament = tournament + self.save = save self.match = Match() - self.tournament = Tournament() - - # loading views - self.view = View() - self.menu = Menu() - - # for test - joueur1 = Player("Bob", "Durand", "25/12/1995", "EF34924") - joueur2 = Player("Joe", "Bidjoba", "02/01/2001", "QS42622") - joueur3 = Player("Jeanine", "Mequesurton", "25/12/1995", "AB20022") - joueur4 = Player("Jean-Pierre", "Quiroul", "15/09/1992", "JF78739") - joueur5 = Player("René", "Nuphard", "25/12/1995", "ED22230") - joueur6 = Player("Sophie", "Fonfec", "24/05/1999", "EE49948") - - self.liste = [joueur1, joueur2, joueur3, joueur4, joueur5, joueur6] + self.match_history = MatchHistory() + self.view = view + self.menu = menu def sort_by_score(self): - self.tournament.players_list.sort(key=lambda t: t.score, reverse = True) + self.tournament.players_list.sort(key=lambda t: t.score, reverse=True) def shuffle_players(self): return shuffle(self.tournament.players_list) def create_tournament(self): print("Nouveau tournoi ! \n") - self.tournament.name = input("Nom du tournoi ? : ") - self.tournament.location = input("Lieu du tournoi : ") - self.tournament.date_start = input("date de début (jj/mm/aaaa) : ") - self.tournament.date_end = input("date de fin (jj/mm/aaaa) : ") - self.tournament.description = input("Description ? : ") - #self.tournament.players_list = input("Liste des joueurs : ") - self.tournament.players_list = self.liste - - total_round = input("Nombre de tours ? (4 par défaut) : ") or 4 - if total_round != 4: - self.tournament.total_round = int(total_round) - + tournament_details = self.view.prompt_for_tournament() + self.tournament.name = tournament_details['name'] + self.tournament.location = tournament_details['location'] + self.tournament.date_start = tournament_details['date_start'] + self.tournament.date_end = tournament_details['date_end'] + self.tournament.description = tournament_details['description'] + self.tournament.total_round = tournament_details['total_round'] + if self.save.player_load(): + self.tournament.players_list = self.save.player_load() + self.save.tournament_write(self.tournament) + else: + print("Placez un fichier joueur dans le répertoire data" + "ou créez des nouveaux joueurs depuis le menu") + print() + self.menu_manager() def run_tournament(self): - input("Prêt à lancer le premier round ?\n") - #print("tour", self.tournament.current_round, round1.start_time) - print("Liste des joueurs : ", self.tournament.players_list) shuffle(self.tournament.players_list) - - for i in range(1, self.tournament.total_round): + for each_round in range(1, self.tournament.total_round + 1): + self.tournament.current_round += 1 self.round = Round() - self.round.name = "Round " + str(i) - self.tournament.current_round = self.round.name - #pour chaque tour : - # set le temps de début - # créer les matchs - # afficher les matchs - # attendre la saisie des scores - # ajouter le tour à la liste des tours du tournoi - + self.round.name = "Round " + str(each_round) + self.view.prompt_for_round(self.round) + # set round start time self.round.start_time = self.round.get_time() + # create matches TODO : check from history self.round.match_list = self.create_match() + # display matches + self.view.display_matches(self.round.match_list) self.view.prompt_for_scores() self.round.end_time = self.round.get_time() - self.view.input_scores(self.round.match_list) + self.scores(self.round.match_list) self.sort_by_score() + self.tournament.round_list.append(self.round.save()) + print("après maj", self.tournament.round_list) + self.save.tournament_write(self.tournament) self.view.display_round_info(self.round) self.view.display_scores(self.tournament.players_list) - print("Le tournoi", self.tournament.name, "est terminé !") + print("\nLe tournoi", self.tournament.name, "est terminé !\n") + def get_match_info(self, match_list): + matches = [] + for i in match_list: + matches.append(i.get_data()) + return matches + def check_match(self, match, match_history): + for item in match_history: + if match in item: + return True + else: + return False + def create_match(self) -> list: + """Create match with two consecutive players - - - def create_match(self): - """Create match with two consecutive players. Check if match already happened in round - - returns a round.match_list + returns : + list of Match """ + match_list = [] j = 0 - k = 0 - print(self.tournament.players_list) for i in range(0, len(self.tournament.players_list), 2): j += 1 - match_name = "match" + str(j) match = Match() match.player1 = self.tournament.players_list[i] match.player2 = self.tournament.players_list[i+1] - self.round.match_list.append(match) + match_list.append(match) + return match_list - return self.round.match_list + def scores(self, match_list) -> list: + """user asked to enter scores, update Player + returns: + list of tuples + """ + matches = [] + for match in match_list: + count = match_list.index(match) + 1 + result = self.view.input_scores(match, count) + if result in ("1", "2", "3"): + if result == "1": + match.player1.score += 1 + match.score1 = 1 + elif result == "2": + match.player2.score += 1 + match.score2 = 1 + elif result == "3": + match.player1.score += 0.5 + match.player2.score += 0.5 + match.score1 = match.score2 = 0.5 + matches.append(match.get_data()) + return matches - - def run(self): + def menu_manager(self): menu_choice = self.menu.items(1) - if menu_choice == "4": - print("Bye") - elif menu_choice == "3": - self.menu.items(2) - elif menu_choice == "2": - self.view.prompt_for_new_player() - elif menu_choice == "1": - print("c'est parti") - self.create_tournament() - self.run_tournament() - self.view.display_winner(self.tournament.players_list) - self.view.display_scores(self.tournament.players_list) + while True: + # Quit + if menu_choice == "4": + print("Bye") + + # Rapports + elif menu_choice == "3": + rapport_choice = self.menu.items(2) + + # Go back + if rapport_choice == "4": + self.menu_manager() + + # Display players from file + elif rapport_choice == "1": + if self.save.player_load(): + self.view.display_players(self.save.player_load()) + input("?") + + # Display list of tournaments + elif rapport_choice == "2": + if self.save.tournament_load(): + self.view.display_tournaments(self.save.tournament_load()) + input("?") + + # display tournament's details + elif rapport_choice == "3": + temp = {} + if self.save.tournament_load(): + temp = self.save.tournament_load() + name = self.view.prompt_tournament_to_display(temp) + if name in temp: + self.view.display_tournament_detail( + temp[name]) + else: + self.view.display_error() + + # create new player and save it in file + elif menu_choice == "2": + joueur = self.view.prompt_for_new_player() + self.save.player_write(joueur) + input("Retour ?") + self.menu_manager() + + # create new tournament + elif menu_choice == "1": + print("c'est parti") + self.create_tournament() + self.run_tournament() + self.view.display_winner(self.tournament.players_list) + self.view.display_scores(self.tournament.players_list) + self.menu_manager() -run = Controller() -run.run() +class CheckMatch: + pass + + +class MenuManager: + pass + + +class TournamentManager: + def __init__(self): + pass + + +class UserManager: + pass + diff --git a/main.py b/main.py index 4a86937..e64c8c5 100644 --- a/main.py +++ b/main.py @@ -1,17 +1,21 @@ -from controllers.base import Controller -from views.base import View +from ChessTournament.models.models import Tournament +from ChessTournament.controllers.base import Application, Save +from ChessTournament.views.base import View +from ChessTournament.views.menu import Menu def main(): + tournament = Tournament() + save = Save() view = View() - menu = Controller(view) - menu.run() + menu = Menu() + application = Application(tournament=tournament, + save=save, + view=view, + menu=menu) + # launch application + application.menu_manager() -if __name__ == "__main__" : +if __name__ == "__main__": main() - - - - - diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/models/models.py b/models/models.py index 13d0e93..c6f93dc 100644 --- a/models/models.py +++ b/models/models.py @@ -1,26 +1,57 @@ from datetime import datetime -from time import sleep +from collections import UserList + +DATAPATH = ("data/") +PLAYERFILE = DATAPATH + "liste_joueurs.json" +TOURNAMENTFILE = DATAPATH + "liste_tournois.json" + class Tournament: """Chess tournament with player_list, keeps a list with all rounds""" - def __init__(self, name = None, players_list = None, location = "club", total_round = 4): + def __init__(self, + name="None", + players_list=None, + location="club", + total_round=4 + ): self.name = name self.location = location - self.start = "start" - self.end = "end" + self.start = datetime.now().strftime("%d-%m-%Y") + self.end = self.start self.total_round = total_round self.round_list = [] - self.current_round = 1 + self.current_round = 0 self.players_list = players_list self.description = "Pas de description" + def __str__(self): + return "Tournoi " + self.name + " à " + self.location + + def data(self): + """Save tournament in file""" + players = [] + for i in self.players_list: + # players.append(i.name + " " + i.lastname) + players.append(i.data()) + tournament_dict = { + "name": self.name, + "location": self.location, + "description": self.location, + "start": self.start, + "end": self.end, + "total_rounds": self.total_round, + "current": self.current_round, + "players": players, + "rounds": self.round_list} + return tournament_dict + class Player: """A Chess player""" - def __init__(self, name, lastname, birth_date, ine): + def __init__(self, name, lastname, birthdate, ine): self.lastname = lastname self.name = name - self.birth_date = birth_date + self.birthdate = birthdate self.ine = ine self.score = 0 @@ -31,33 +62,88 @@ class Player: def __repr__(self): return str(self) + def data(self): + player_dict = { + 'prénom': self.name, + 'nom': self.lastname, + 'date de naissance': self.birthdate, + 'ine': self.ine + } + return player_dict + class Match: - def __init__(self, player1 = None, player2 = None): + def __init__(self, player1=None, player2=None): self.player1 = player1 self.player2 = player2 + self.score1 = 0 + self.score2 = 0 def __str__(self): - #return self.player1.name + " " + self.player1.lastname + " / " + self.player2.name + " " + self.player2.lastname - return self.player1.ine + "/" + self.player2.ine - - def __repr__(self): - return str(self) + return self.player1.ine + " / " + self.player2.ine def get_data(self): - return ([self.player1.ine, self.player1.score], [self.player2.ine, self.player2.score]) + return ([self.player1.ine, self.score1], + [self.player2.ine, self.score2]) + + def get_scores(self) -> list: + return (self.player1.ine + + " : " + str(self.score1) + + " - " + self.player2.ine + + " : " + str(self.score2)) class Round: - def __init__(self, name = "Round 1"): + def __init__(self, name="Round 1"): self.name = name self.start_time = None self.end_time = None self.match_list = [] - def __str__(self): - return self.name + ": début le " + self.start_time + " et terminé le " + self.end_time - def get_time(self): + def __str__(self): + return (self.name + + ": début le " + + self.start_time + + " et terminé le " + + self.end_time) + + def get_time(self) -> str: return datetime.now().strftime("%d-%m-%Y à %Hh%M,%Ss") + def save(self) -> dict: + matches = [] + for match in self.match_list: + matches.append(match.get_data()) + dico = { + "Nom": self.name, + "Debut": self.start_time, + "Fin": self.end_time, + "Matches": matches + } + return dico + + +class MatchHistory(UserList): + """Keep a history of matches to avoid same match occur + + returns a list of matches + """ + def __init__(self): + self.matches = [] + + def add(self, match_list): + for match in match_list: + self.matches.append(match) + + def __str__(self): + return self.matches + + def check(self, given_match): + for match in self.matches: + if (given_match.player1 == match.player1 + or given_match.player1 == match.player2): + if (given_match.player2 == match.player2 + or given_match.player2 == match.player2): + return True + return False diff --git a/player_list.json b/player_list.json deleted file mode 100644 index 0eea98e..0000000 --- a/player_list.json +++ /dev/null @@ -1 +0,0 @@ -{"EF34924": ["Bob", "Durand", "25/12/1995", "M"], "QS42622": ["Joe", "Bidjoba", "02/01/2001", "M"], "AB20022": ["Jeanine", "Mequesurton", "25/12/1995", "F"], "JF78739": ["Jean-Pierre", "Quiroul", "15/09/1992", "M"], "ED22230": ["Ren\u00e9", "Nuphard", "25/12/1995", "M"], "EE49948": ["Sophie", "Fonfec", "24/05/1999", "F"]} \ No newline at end of file diff --git a/views/__init__.py b/views/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/views/base.py b/views/base.py index 1c30f83..70fb14f 100644 --- a/views/base.py +++ b/views/base.py @@ -1,6 +1,7 @@ from datetime import datetime import re + class View: """Prompt menu, get choices""" def __init__(self): @@ -25,58 +26,117 @@ class View: def prompt_for_scores(self): print() - input("Saisir les scores ?") + input("Saisir les scores ? (y)") return True + def prompt_for_round(self, round): + print() + input(f"Prêt à lancer le {round.name} ? (y)") + return True + + def display_matches(self, match_list): + print("Liste des matchs : ") + for match in match_list: + print(match.player1.name, match.player1.lastname.upper(), + "contre", match.player2.name, match.player2.lastname.upper(), + "(", match, ")" + ) + def display_round_info(self, round): - print(round) + print("\n -> ", round) def display_scores(self, players_list): - print("Les scores sont :\n") + print("\nLes scores sont :") + print("-----------------") for i in players_list: - print(i.ine, i.name, i.lastname, " : ", i.score) + print(i.ine, i.name, i.lastname, ":", i.score) - def prompt_for_new_player(self): + def prompt_for_new_player(self) -> dict: print("Enregistrez un nouveau joueur :\n") - self.lastname = input("Nom de famille ? : ") - self.name = input("Prénom ? : ") - self.birthdate = input("Date de naissance (jj/mm/aaaa) ? : ") - #self.birthdate = self.check_date() - self.ine = input("Identifiant National d'Echecs (ine) ? : ") - #self.ine = self.test_ine() - return {"Nom": self.lastname, "Prénom": self.name, "Date de naissance": self.birthdate, "INE": self.ine} + lastname = input("Nom de famille ? : ") + name = input("Prénom ? : ") + birthdate = input("Date de naissance (jj/mm/aaaa) ? : ") + ine = input("Identifiant National d'Echecs (ine) ? : ") + return {'name': name, + 'lastname': lastname, + 'birthdate': birthdate, + 'ine': ine} - def input_scores(self, match_list): - for match in match_list: - print(match) - print("Scores pour match", match_list.index(match) + 1, " :") - while True: - try: - result = input(f"1.{match.player1}, 2.{match.player2}, 3.Nul\n") - if result in ("1", "2", "3"): - if result == "1": - match.player1.score += 1 - elif result == "2": - match.player2.score += 1 - elif result == "3": - match.player1.score += 0.5 - match.player2.score += 0.5 - break - else: - print("Entrez un chiffre entre 1 et 3") - except ValueError: - print("Veuillez entrer un chiffre") + def prompt_for_tournament(self) -> dict: + tournament_details = {} + tournament_details['name'] = str.lower(input("Nom du tournoi ? : ")) + tournament_details['location'] = str.lower(input("Lieu du tournoi : ")) + tournament_details['date_start'] = ( + input("date de début (jj/mm/aaaa) : [today] " + or datetime.now().strftime("%d/%m/%Y"))) + tournament_details['date_end'] = ( + input("date de fin (jj/mm/aaaa) : [today] " + or datetime.now().strftime("%d/%m/%Y"))) + tournament_details['description'] = input("Description ? : ") + total_round = input("Nombre de tours ? (4 par défaut) : ") or 4 + tournament_details['total_round'] = int(total_round) + return tournament_details + + def input_scores(self, match, count): + print("Scores pour le match", count, " :") + while True: + try: + result = input(f"1.{match.player1}, " + f"2.{match.player2}, " + f"3.Nul\n") + if result in ("1", "2", "3"): + return result + else: + print("Entrez un chiffre entre 1 et 3") + except ValueError: + print("Veuillez entrer un chiffre") def display_winner(self, player_list): winner = max(player_list, key=lambda t: t.score) - print("Le gagnant est :", winner.name, winner.lastname, "avec un score de :", winner.score) - - - - - + print("Le gagnant est :", + winner.name, + winner.lastname, + "avec un score de :", + winner.score) + def display_players(self, player_list_to_display): + print("Liste des joueurs :") + for player in player_list_to_display: + print(player.data()) + def display_tournaments(self, tournament_list_to_display): + print("Liste des tournois : ") + for tournament in tournament_list_to_display: + print("-", tournament, + "le", + tournament_list_to_display[tournament]['start']) + def prompt_tournament_to_display(self, tournament_list_to_display): + i = 0 + temp_list = [] + for tournament in tournament_list_to_display: + i += 1 + print(i, ".", tournament) + temp_list.append(tournament) + num = int(input("Numéro du tournoi à afficher ? ")) + return temp_list[num - 1] + def display_tournament_detail(self, tournament_to_display): + i = tournament_to_display + print("Nom du tournoi : ", i['name']) + print("Lieu : ", i['location']) + print("Le tournoi a débuté le : ", i['start']) + print("Et s'est terminé le : ", i['end']) + print("Les participants étaient : \n", i['players']) + print("\nLes matches et leurs résultats étaient :") + for j in i['rounds']: + print(j['Nom']) + print("Commencé à ", j['Debut']) + print("Terminé à ", j['Fin']) + print("Liste des matchs :") + for k in j['Matches']: + print(k) + print() + def display_error(self): + print("Erreur de saisie, recommencez;") diff --git a/views/menu.py b/views/menu.py index 478fade..378685e 100644 --- a/views/menu.py +++ b/views/menu.py @@ -11,7 +11,7 @@ class Menu: "[1] Afficher la liste des joueurs", "[2] Afficher l'historique des tournois", "[3] Afficher le détail d'un tournoi", - "[4] Quitter" + "[4] Retour" ] def items(self, value): @@ -19,18 +19,20 @@ class Menu: menu_type = [] if value == 1: menu_type = self.ITEMS + print() + print("MENU GENERAL") if value == 2: menu_type = self.RAPPORTS + print() + print("MENU RAPPORTS") for i in menu_type: print(i) while True: try: choice = input("Choix ? : ") if int(choice) not in range(1, len(menu_type) + 1): - print("Veuillez saisir un chiffre entre 1 et", len(menu_type)) - print(int(choice) in range(1, len(menu_type))) + print("Choisissez un chiffre entre 1 et", len(menu_type)) else: return choice except ValueError: print("Veuillez entrer un chiffre") -