simple #1

Merged
Yann merged 10 commits from simple into dev 2025-02-13 10:32:14 +00:00
14 changed files with 624 additions and 160 deletions

View File

@ -1,2 +1,11 @@
## Refactored
# work in progress
All models are in `models/models.py`
Sequence can be seen in `controllers/base.py` in the `Controller.run()` method
for testing purpose, the players_list is created when controller is instantiated
To test, execute the controllers/base.py
- first menu is called from view
- the method to create player just returns the object (doesn't write anything)
- 1 -> creates a new tournament then run it

269
controllers/base.py Normal file
View File

@ -0,0 +1,269 @@
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 Save:
def __init__(self):
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.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)
def shuffle_players(self):
return shuffle(self.tournament.players_list)
def create_tournament(self):
print("Nouveau tournoi ! \n")
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):
shuffle(self.tournament.players_list)
for each_round in range(1, self.tournament.total_round + 1):
self.tournament.current_round += 1
self.round = Round()
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.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("\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
returns :
list of Match
"""
match_list = []
j = 0
for i in range(0, len(self.tournament.players_list), 2):
j += 1
match = Match()
match.player1 = self.tournament.players_list[i]
match.player2 = self.tournament.players_list[i+1]
match_list.append(match)
return 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 menu_manager(self):
menu_choice = self.menu.items(1)
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()
class CheckMatch:
pass
class MenuManager:
pass
class TournamentManager:
def __init__(self):
pass
class UserManager:
pass

51
main.py
View File

@ -1,40 +1,21 @@
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 = Menu()
application = Application(tournament=tournament,
save=save,
view=view,
menu=menu)
# launch application
application.menu_manager()
#Menu
## creer un nouveau tournoi
## enregistrer un nouveau joueur
## rapport
### afficher la liste des joueurs inscrits
### liste des tournois
### afficher un tounroi en particulier :
#### liste des joueurs du tournoi (alphab.)
#### liste des tours, matchs
# Nouveau Tournoi :
## entrer les infos :
## nom, lieu, date début, date fin, nombre de tours(opt)
# Participants / joueurs :
## besoin d'enregistrer des nouveaux joueurs ?
## selection des participant dans la liste des joueurs du club
## Creation du 1er tour : affichage du tour, de la liste des matchs (paire nom.prenom) :
## En attente saisie séquentielle des résultats pour chaque match :
### Saisie résultat match 1 : 1. Bob LEPONGE / 2. Bernard DINAMOUK / 3.Match Nul
### ?
## Tour suivant (puis itération) : affichage du tour, de la liste des matchs (paire nom.prenom) :
## etc
## Après le dernier tour : affichage du vainqueur
## sauvegarde du tournoi : tournois/{date.nom.lieu}/{date.nom.lieu}.json, matchs.json
##
if __name__ == "__main__" :
if __name__ == "__main__":
main()

149
models/models.py Normal file
View File

@ -0,0 +1,149 @@
from datetime import datetime
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
):
self.name = name
self.location = location
self.start = datetime.now().strftime("%d-%m-%Y")
self.end = self.start
self.total_round = total_round
self.round_list = []
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, birthdate, ine):
self.lastname = lastname
self.name = name
self.birthdate = birthdate
self.ine = ine
self.score = 0
def __str__(self):
"""Used in print"""
return self.ine
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):
self.player1 = player1
self.player2 = player2
self.score1 = 0
self.score2 = 0
def __str__(self):
return self.player1.ine + " / " + self.player2.ine
def get_data(self):
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"):
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) -> 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

View File

@ -1,14 +0,0 @@
class Menu:
def items(self):
print("[1] Créer un nouveau tournoi", end='\n')
print("[2] Enregistrer un nouveau joueur", end='\n')
print("[3] Rapports", end='\n')
print("[4] Quitter", end='\n')
def rapports():
print("[1] Afficher la liste des joueurs", end='\n')
print("[2] Afficher l'historique des tournois", end='\n')
print("[3] Afficher le détail d'un tournoi", end='\n')
print("[4] Quitter", end='\n')

View File

@ -1,19 +0,0 @@
import json
class Player:
"""Define player, should store only data for now ? Don't see further"""
def get_new_player(self):
get_player = {}
print("Enregistrez un nouveau joueur :\n")
get_player['lastname'] = input('Nom de famille :\n')
get_player['name'] = input('Prénom :\n')
get_player['birth_date'] = input('Date de naissance :\n')
#convert dict in json object and write it in players.json file (with "a" append to file)
with open("players.json", "a") as output:
output.write(json.dumps(get_player, indent=3))
new = Player()
new.get_new_player()

View File

@ -1,10 +0,0 @@
{
"lastname": "Prout",
"name": "Joe",
"birth_date": "23/02/2003"
}
{
"lastname": "Dupont",
"name": "Pierre",
"birth_date": "20/01/2002"
}

View File

@ -1,74 +0,0 @@
from random import choice
class Turn():
def __init__(self, name, matchs):
self.name = name
self.matchs = matchs
self.match_history = []
def rambling(self, player_list):
"""jumble (random order) players in list and return list"""
self.tmp_list = []
self.picked_player = []
for i in range(2^len(player_list)):
self.picked_player = choice(player_list)
self.tmp_list.append(self.picked_player)
return self.tmp_list
def sorting(self, player_list):
"""order players on score : use second index (for every item in the list) as key (given by function score)"""
def score(couple):
return couple[1]
return sorted(player_list, key=score)
def associate(self, player_list):
"""create a match list"""
self.match_list = []
self.couple = ()
for i in range(len(player_list)):
if i % 2 == 0 :
self.couple = (player_list[i][0], player_list[i+1][0])
if self.couple in self.match_history:
self.couple = (player_list[i][0], player_list[i + 2][0])
self.match_list.append(self.couple)
else:
self.match_list.append(self.couple)
self.match_history.append(self.name)
self.match_history.append(self.match_list)
return self.match_list
def matchmarking(self, player_list):
pass
list = [['Player1', 8],
['Player2', 2],
['Player3', 0],
['Player4', 5],
['Player5', 8],
['Player6', 3],
['Player7', 1],
['Player8', 6],
['Player9', 3],
['Player10', 4],
['Player11', 3],
['Player12', 2],
['Player13', 8],
['Player14', 4],
['Player15', 2],
['Player16', 7]]
tour = Turn("tour1", 1)
print(tour.sorting(list))
print(tour.rambling(list))
print(tour.associate(tour.sorting(list)))
print(f"Voici l'historique des matchs : {tour.match_history}")
tour2 = Turn()

142
views/base.py Normal file
View File

@ -0,0 +1,142 @@
from datetime import datetime
import re
class View:
"""Prompt menu, get choices"""
def __init__(self):
pass
def check_date(self):
while True:
date = input("Date de naissance (jj/mm/aaaa) ? : ")
if datetime.strptime(date, '%d/%m/%Y'):
break
else:
print("La date doit être au format jj/mm/aaaa")
def test_ine(self):
ine_pattern = r'[a-zA-Z]{2}\d{5}'
while True:
ine = input("Identifiant National d'Echecs (ine) ? : ")
if re.match(ine_pattern, ine):
break
else:
print("Mauvais format d'ine")
def prompt_for_scores(self):
print()
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("\n -> ", round)
def display_scores(self, players_list):
print("\nLes scores sont :")
print("-----------------")
for i in players_list:
print(i.ine, i.name, i.lastname, ":", i.score)
def prompt_for_new_player(self) -> dict:
print("Enregistrez un nouveau joueur :\n")
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 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)
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;")

38
views/menu.py Normal file
View File

@ -0,0 +1,38 @@
class Menu:
def __init__(self):
self.ITEMS = [
"[1] Créer un nouveau tournoi",
"[2] Enregistrer un nouveau joueur",
"[3] Rapports",
"[4] Quitter"
]
self.RAPPORTS = [
"[1] Afficher la liste des joueurs",
"[2] Afficher l'historique des tournois",
"[3] Afficher le détail d'un tournoi",
"[4] Retour"
]
def items(self, value):
"""displays menu depending on given value"""
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("Choisissez un chiffre entre 1 et", len(menu_type))
else:
return choice
except ValueError:
print("Veuillez entrer un chiffre")

View File

@ -1,7 +0,0 @@
# generate player list
from random import randint
list = []
for i in range(16):
list.append(["Player"+str(i+1), randint(0, 8)])