Partie.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. from Outils.Moteur_de_jeu.Fenetre import *
  2. from Outils.Moteur_de_jeu.Joueur import *
  3. from random import randint
  4. from time import *
  5. import requests
  6. import json
  7. class Partie : # Quentin 17/10/2016
  8. """
  9. Attributs :
  10. .joueurs : Joueur * Joueur
  11. .plateau : Plateau
  12. .tour : int
  13. .afficher : bool
  14. .cases_selectionnables : int * int liste
  15. .barrieres_selectionnables : Barriere liste
  16. .liste_coups_licites : Coup liste
  17. .etape : string
  18. .deroulement : Coup liste
  19. Méthodes :
  20. .joueur_actuel(self)
  21. .est_selectionnable(self, barriere)
  22. .executer_tour(self, coup)
  23. .tourner_jeu(self)
  24. .demarrer(self)
  25. .sauvegarder_deroulement(self, nom, gagnant)
  26. """
  27. DOSSIER_STANDARD = "PARTIES_A_TRAITER" # Chemin privililégié pour enregistrer les fichiers
  28. def __init__(self, joueurA, joueurB, afficher, dossier_save = "", demander_nom = False) : # Quentin 13/10/2016
  29. """
  30. joueurA et joueurB : les deux participants
  31. afficher : booléen qui vaut true si une fenêtre doit s'afficher
  32. dossier_save : '' -> pas de sauvegarde
  33. '*' -> sauvegarde sur jhub
  34. chemin -> sauvegarde dans le dossier indiqué
  35. """
  36. # Pour se souvenir :
  37. self.joueurA = joueurA
  38. self.joueurB = joueurB
  39. # Attribut .joueurs
  40. if randint(0,1) == 1 : # Tirage au sort du joueur qui commence
  41. self.joueurs = (joueurA, joueurB)
  42. joueurA.num = 0
  43. joueurB.num = 1
  44. else :
  45. self.joueurs = (joueurB, joueurA)
  46. joueurB.num = 0
  47. joueurA.num = 1
  48. # Attribut .plateau ; correspond respectivement à x lignes, y colonnes et n barrières par joueur
  49. self.plateau = Plateau(9, 9, 10)
  50. # Attributs caractérisant l'affichage
  51. config = self.types_joueurs()
  52. self.afficher = afficher or config != "OO" # L'affichage est nécessaire si un humain présent
  53. self.demander_nom = demander_nom and config != "OO" # S'il n'y a pas d'humain, il ne faut pas demander les noms
  54. # Attribut caractérisant les items sélectionnables sur le plateau :
  55. if self.joueur_actuel().type == "H" :
  56. self.cases_selectionnables = self.plateau.cases_accessibles_joueur(0)
  57. self.barrieres_selectionnables = self.plateau.liste_barrieres_possibles()
  58. else :
  59. self.cases_selectionnables = []
  60. self.barrieres_selectionnables = []
  61. #Attribut permettant de controler à posteriori le choix de l'I.A.
  62. self.liste_coups_licites = self.plateau.liste_coups_possibles()
  63. # Attribut .etape
  64. self.etape = "J"
  65. """
  66. Quatre étapes possibles :
  67. - J : Pour l'humain : se déplacer sans gagner -> J
  68. se déplacer et atteindre la rangée opposée -> F
  69. choisir de poser une barrière -> B1
  70. Pour l'ordinateur : attendre que l'utilisateur clique sur le bouton -> J
  71. - B1 : choisir le barycentre de la barrière -> B2 si on peut choisir l'orientation, J sinon
  72. annuler -> J
  73. - B2 : choisir l'orientation de la barrière -> J
  74. annuler -> B1
  75. - F : fin de la self
  76. """
  77. # Attributs d'enregistrement
  78. self.deroulement = [] # C'est une liste de Coups qu'il faut incrémenter à chaque action de joueur.
  79. self.dossier_save = dossier_save
  80. def joueur_actuel(self) : # Quentin 09/2016
  81. """ Retourne le joueur dont c'est le tour. """
  82. return self.joueurs[self.plateau.tour]
  83. def types_joueurs(self) :
  84. """ Renvoie 'OH', 'OO', 'HO' ou 'HH' selon les types des joueurs """
  85. return self.joueurs[0].type + self.joueurs[1].type
  86. def est_selectionnable(self, barriere) : # Quentin 04/10/2016
  87. """ Permet de savoir si une barrière est dans la liste des barrières sélectionnables """
  88. for b in self.barrieres_selectionnables :
  89. if b == barriere :
  90. return True
  91. return False
  92. def coup_IA(self) : # Quentin 15/11/2016
  93. """ Retourne le coup calculé par l'I.A. """
  94. l = self.plateau.liste_coups_possibles()
  95. id_coup = ( Global.partie.joueur_actuel().calculer_coup(Global.partie.plateau.copie_complete(), l) ) % len(l)
  96. return l[id_coup]
  97. def executer_tour(self, coup) : # Quentin 15/11/2016
  98. """
  99. Fonction utilisée lorsqu'il y a affichage.
  100. Applique un coup et fait la transition vers le tour suivant.
  101. """
  102. self.plateau.executer_coup(coup)
  103. self.deroulement.append(coup)
  104. if self.plateau.gagnant() != -1 : # Condition de victoire
  105. self.etape = "F"
  106. self.enregistrer_partie()
  107. else :
  108. self.etape = "J"
  109. if self.joueur_actuel().type == "H" :
  110. # Calcul des nouvelles cases et barrières :
  111. self.cases_selectionnables = self.plateau.cases_accessibles_joueur(self.plateau.tour)
  112. self.barrieres_selectionnables = self.plateau.liste_barrieres_possibles()
  113. else :
  114. if self.types_joueurs() == "OO" or self.affichage.var_bouton.get() == 1 :
  115. self.cases_selectionnables = []
  116. self.barrieres_selectionnables = []
  117. else :
  118. # Exécution immédiate du tour de l'I.A.
  119. self.affichage.rafraichissement(self)
  120. self.executer_tour(self.coup_IA())
  121. def tourner_jeu(self) : # Quentin 17/10/2016
  122. """
  123. Fonction utilisée lorsqu'il n'y a pas affichage.
  124. Applique les coups en boucle
  125. Retourne le gagnant
  126. """
  127. while self.plateau.gagnant() == -1 : # Condition de victoire
  128. coup = self.coup_IA()
  129. self.plateau.executer_coup(coup)
  130. self.deroulement.append(coup)
  131. self.enregistrer_partie()
  132. return self.joueurs[1 - self.plateau.tour]
  133. def lancement(self) : # Quentin 15/11/2016
  134. """ Lance la partie et retourne le gagnant dans le cadre d'un match d'I.A. """
  135. if self.afficher :
  136. self.affichage = Affichage(self.plateau, self.types_joueurs() in ("OH","HO"))
  137. if self.joueur_actuel().type == "O" and self.types_joueurs() in ("OH","HO") :
  138. self.executer_tour(self.coup_IA())
  139. self.affichage.rafraichissement(Global.partie)
  140. self.affichage.fenetre.mainloop()
  141. else :
  142. return self.tourner_jeu()
  143. def demarrer(self) :
  144. """ Demande de saisir les noms puis lance la partie """
  145. if self.demander_nom :
  146. saisie_noms(self)
  147. else :
  148. return self.lancement()
  149. def relancer(self) : # Quentin 21/11/2016
  150. """
  151. Recrée une partie avec les mêmes joueurs et le même dossier de sauvegarde
  152. """
  153. return Partie(self.joueurs[0], self.joueurs[1], self.afficher, self.dossier_save, False)
  154. #############################
  155. # Sauvegarde de la partie : #
  156. #############################
  157. def obtenir_donnees(self) :
  158. """ Retourne un couple (nom, contenu). Nom n'est que le nom du fichier, le chemin est ajouté après """
  159. (year, month, day, hour, minute, second, weekday, yearday, daylight) = localtime(time())
  160. instant = "%02d-%02d-%04d %02dh%02dmin%02ds" % (day, month, year, hour, minute, second)
  161. nom = self.joueurs[0].nom + " VS " + self.joueurs[1].nom + " " + instant + ".txt"
  162. # En-tête :
  163. contenu = ["Joueur 1 : " + self.joueurs[0].nom + " /" + self.joueurs[0].type + "\nJoueur 2 : " + self.joueurs[1].nom + " /" + self.joueurs[1].type + "\n\n"]
  164. # Coups :
  165. for t in enumerate( self.deroulement ) :
  166. k, cp = t
  167. contenu.append( "Coup " + str(k + 1) + " : " + cp.get_code() + "\n" )
  168. # Gagnant :
  169. contenu.append("\nGagnant : joueur " + str(2 - self.plateau.tour))
  170. return (nom, contenu)
  171. def sauvegarde(self, nom, contenu) :
  172. """ Enregistre les données de la partie """
  173. nomEntier = self.dossier_save + "/" + nom
  174. try :
  175. flux = open(nomEntier, "w")
  176. except :
  177. print("Echec de l'enregistrement.")
  178. print(nomEntier)
  179. return
  180. for l in contenu :
  181. flux.write(l)
  182. flux.close()
  183. def enregistrer_partie(self) :
  184. if self.dossier_save != "" :
  185. (nom, contenu) = self.obtenir_donnees()
  186. self.sauvegarde(nom, contenu)