from Outils.Moteur_de_jeu.Fenetre import * from Outils.Moteur_de_jeu.Joueur import * from random import randint from time import * import requests import json class Partie : # Quentin 17/10/2016 """ Attributs : .joueurs : Joueur * Joueur .plateau : Plateau .tour : int .afficher : bool .cases_selectionnables : int * int liste .barrieres_selectionnables : Barriere liste .liste_coups_licites : Coup liste .etape : string .deroulement : Coup liste Méthodes : .joueur_actuel(self) .est_selectionnable(self, barriere) .executer_tour(self, coup) .tourner_jeu(self) .demarrer(self) .sauvegarder_deroulement(self, nom, gagnant) """ DOSSIER_STANDARD = "PARTIES_A_TRAITER" # Chemin privililégié pour enregistrer les fichiers def __init__(self, joueurA, joueurB, afficher, dossier_save = "", demander_nom = False) : # Quentin 13/10/2016 """ joueurA et joueurB : les deux participants afficher : booléen qui vaut true si une fenêtre doit s'afficher dossier_save : '' -> pas de sauvegarde '*' -> sauvegarde sur jhub chemin -> sauvegarde dans le dossier indiqué """ # Pour se souvenir : self.joueurA = joueurA self.joueurB = joueurB # Attribut .joueurs if randint(0,1) == 1 : # Tirage au sort du joueur qui commence self.joueurs = (joueurA, joueurB) joueurA.num = 0 joueurB.num = 1 else : self.joueurs = (joueurB, joueurA) joueurB.num = 0 joueurA.num = 1 # Attribut .plateau ; correspond respectivement à x lignes, y colonnes et n barrières par joueur self.plateau = Plateau(9, 9, 10) # Attributs caractérisant l'affichage config = self.types_joueurs() self.afficher = afficher or config != "OO" # L'affichage est nécessaire si un humain présent self.demander_nom = demander_nom and config != "OO" # S'il n'y a pas d'humain, il ne faut pas demander les noms # Attribut caractérisant les items sélectionnables sur le plateau : if self.joueur_actuel().type == "H" : self.cases_selectionnables = self.plateau.cases_accessibles_joueur(0) self.barrieres_selectionnables = self.plateau.liste_barrieres_possibles() else : self.cases_selectionnables = [] self.barrieres_selectionnables = [] #Attribut permettant de controler à posteriori le choix de l'I.A. self.liste_coups_licites = self.plateau.liste_coups_possibles() # Attribut .etape self.etape = "J" """ Quatre étapes possibles : - J : Pour l'humain : se déplacer sans gagner -> J se déplacer et atteindre la rangée opposée -> F choisir de poser une barrière -> B1 Pour l'ordinateur : attendre que l'utilisateur clique sur le bouton -> J - B1 : choisir le barycentre de la barrière -> B2 si on peut choisir l'orientation, J sinon annuler -> J - B2 : choisir l'orientation de la barrière -> J annuler -> B1 - F : fin de la self """ # Attributs d'enregistrement self.deroulement = [] # C'est une liste de Coups qu'il faut incrémenter à chaque action de joueur. self.dossier_save = dossier_save def joueur_actuel(self) : # Quentin 09/2016 """ Retourne le joueur dont c'est le tour. """ return self.joueurs[self.plateau.tour] def types_joueurs(self) : """ Renvoie 'OH', 'OO', 'HO' ou 'HH' selon les types des joueurs """ return self.joueurs[0].type + self.joueurs[1].type def est_selectionnable(self, barriere) : # Quentin 04/10/2016 """ Permet de savoir si une barrière est dans la liste des barrières sélectionnables """ for b in self.barrieres_selectionnables : if b == barriere : return True return False def coup_IA(self) : # Quentin 15/11/2016 """ Retourne le coup calculé par l'I.A. """ l = self.plateau.liste_coups_possibles() id_coup = ( Global.partie.joueur_actuel().calculer_coup(Global.partie.plateau.copie_complete(), l) ) % len(l) return l[id_coup] def executer_tour(self, coup) : # Quentin 15/11/2016 """ Fonction utilisée lorsqu'il y a affichage. Applique un coup et fait la transition vers le tour suivant. """ self.plateau.executer_coup(coup) self.deroulement.append(coup) if self.plateau.gagnant() != -1 : # Condition de victoire self.etape = "F" self.enregistrer_partie() else : self.etape = "J" if self.joueur_actuel().type == "H" : # Calcul des nouvelles cases et barrières : self.cases_selectionnables = self.plateau.cases_accessibles_joueur(self.plateau.tour) self.barrieres_selectionnables = self.plateau.liste_barrieres_possibles() else : if self.types_joueurs() == "OO" or self.affichage.var_bouton.get() == 1 : self.cases_selectionnables = [] self.barrieres_selectionnables = [] else : # Exécution immédiate du tour de l'I.A. self.affichage.rafraichissement(self) self.executer_tour(self.coup_IA()) def tourner_jeu(self) : # Quentin 17/10/2016 """ Fonction utilisée lorsqu'il n'y a pas affichage. Applique les coups en boucle Retourne le gagnant """ while self.plateau.gagnant() == -1 : # Condition de victoire coup = self.coup_IA() self.plateau.executer_coup(coup) self.deroulement.append(coup) self.enregistrer_partie() return self.joueurs[1 - self.plateau.tour] def lancement(self) : # Quentin 15/11/2016 """ Lance la partie et retourne le gagnant dans le cadre d'un match d'I.A. """ if self.afficher : self.affichage = Affichage(self.plateau, self.types_joueurs() in ("OH","HO")) if self.joueur_actuel().type == "O" and self.types_joueurs() in ("OH","HO") : self.executer_tour(self.coup_IA()) self.affichage.rafraichissement(Global.partie) self.affichage.fenetre.mainloop() else : return self.tourner_jeu() def demarrer(self) : """ Demande de saisir les noms puis lance la partie """ if self.demander_nom : saisie_noms(self) else : return self.lancement() def relancer(self) : # Quentin 21/11/2016 """ Recrée une partie avec les mêmes joueurs et le même dossier de sauvegarde """ return Partie(self.joueurs[0], self.joueurs[1], self.afficher, self.dossier_save, False) ############################# # Sauvegarde de la partie : # ############################# def obtenir_donnees(self) : """ Retourne un couple (nom, contenu). Nom n'est que le nom du fichier, le chemin est ajouté après """ (year, month, day, hour, minute, second, weekday, yearday, daylight) = localtime(time()) instant = "%02d-%02d-%04d %02dh%02dmin%02ds" % (day, month, year, hour, minute, second) nom = self.joueurs[0].nom + " VS " + self.joueurs[1].nom + " " + instant + ".txt" # En-tête : contenu = ["Joueur 1 : " + self.joueurs[0].nom + " /" + self.joueurs[0].type + "\nJoueur 2 : " + self.joueurs[1].nom + " /" + self.joueurs[1].type + "\n\n"] # Coups : for t in enumerate( self.deroulement ) : k, cp = t contenu.append( "Coup " + str(k + 1) + " : " + cp.get_code() + "\n" ) # Gagnant : contenu.append("\nGagnant : joueur " + str(2 - self.plateau.tour)) return (nom, contenu) def sauvegarde(self, nom, contenu) : """ Enregistre les données de la partie """ nomEntier = self.dossier_save + "/" + nom try : flux = open(nomEntier, "w") except : print("Echec de l'enregistrement.") print(nomEntier) return for l in contenu : flux.write(l) flux.close() def enregistrer_partie(self) : if self.dossier_save != "" : (nom, contenu) = self.obtenir_donnees() self.sauvegarde(nom, contenu)