123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- 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)
-
-
|