Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème code jeu du pendu !

    24 décembre 2010 à 16:50:33

    Bonjour,
    Pour me remettre un peu a programmer en python, j'ai voulu refaire le jeu du pendu en utilisant un maximum la POO, j'ai fini le jeu mais il y a un petit bug que je n'arrive pas a résoudre.
    j'ai créer 2 classes, une classe Score et une classe Mot

    #!/usr/bin/python
    #-*- coding: UTF-8 -*-
    
    # Module de classes pour le jeu du pendu
    import pickle
    from random import randrange
    
    class Score(object):
        "Gère les scores des Joueurs en fonction de leur nom"
        def __init__(self):
            "Initialisation du dictionnaire de scores"
            try:
                fichier = open("scores.bin", "rb")
                self.scores = pickle.load(fichier)
                fichier.close()
            except IOError:
                self.scores = {}
            
    
        def sauver(self):
            "Sauvegarde du dictionnaire dans un fichier bin"
            fichier = open("scores.bin", "wb")
            pickle.dump(self.scores, fichier)
            fichier.close()
    
        def recherche(self, nom):
            "Recherche le score du joueur et au besoins le crée"
            if nom in self.scores:
                self.joueur = [nom, self.scores[nom]]
            else:
                self.scores[nom] = (0, 0)
                self.joueur = [nom, self.scores[nom]]
            return self.joueur
    
        def affiche(self):
            "Affiche les scores par ordre décroissants"
            ordre = []
            noms = list(self.scores.keys())
            valeurs = tuple(self.scores.values())
            for n in range(len(noms)):
                ordre.append([valeurs[n], noms[n]])
                ordre.sort()
                ordre.reverse()
            for ele in ordre:
                print("{} a un score de {} point(s) pour {} mot(s) trouvé(s)".format
                      (ele[1], ele[0][0], ele[0][1]))
    
        def incremente(self, nom, score):
            "Actualise le score du joueur dès qu'il finit une partie"
            if nom in self.scores:
                self.scores[nom] = score
    
    class Mot(str):
        """gere les mots qui doivent être trouvés par l'utilisateur"""
        def __init__(self):
            "Chargement des mots dans une liste"
            str.__init__(self)
            self.mots, self.malus = [], 1
            try:
                fichier = open("mots.txt", "r")
            except IOError:
                print("Le fichier 'mots.txt' est introuvable !")
            while 1:
                ligne = fichier.readline()
                if ligne == "":
                    break
                else:
                    self.mots.append(ligne[:-1])
            fichier.close()
    
        def pioche(self):
            "Tire au hasard un mot dans la liste et la renvoie"
            i = randrange(len(self.mots))
            mot = self.mots[i]
            self.mots.remove(mot)
            return mot
    
        def convert(self, mot):
            "Convertie le mot visible en mot avec *"
            l = len(mot)
            mot2 = mot[0] + ((l-2)*"*") + mot[l-1]
            return mot2
       
        def afficheLettre(self, car, mot, motcrypt):
            "Affiche sur le mot crypté la lettre trouvée"
            if car not in mot:
                self.malus+=1
            else:
                for n in range(1, len(mot)):
                    if car == mot[n]:
                        motcrypt = motcrypt[:n] + car + motcrypt[n+1:]
            return motcrypt
    


    et une classe Pendu qui importe le contenu du fichier classes.py

    #!/usr/bin/python
    #-*- coding: UTF-8 -*-
    
    from classes import *
    
    class Pendu(object):
        """Application du jeu du pendu version console"""
        def __init__(self):
            self.joueur = Score() # instanciation de la classe Score
            self.enigme = Mot() # Instanciation de la classe Mot
            print("")
            print("")
            print("Bienvenu sur le jeu du pendu ! (version console)")
            print("")
            print("version 1.0 éditée par Dario")
            print("")
            while 1:
                print("Veuillez entrer votre choix et appuyer sur <ENTER>")
                print("<C> pour commencer une nouvelle partie")
                print("<A> pour afficher les meilleurs scores")
                print("<Q> pour quitter le programme")
                debut = input("")
                debut = debut.upper().strip() # Choix de l'utilisateur
                if debut == "Q":
                    print("Fin de partie merci d'avoir participé !")
                    print("Appuyez sur <ENTER > pour fermer la fenetre")
                    input()
                    break
                elif debut == "A": # Scores par ordre décroissants
                    self.joueur.affiche()
                    print("")
                elif debut == "C":
                    self.commencer()
                else:
                    print("Choix incorect !")
        
        def commencer(self):
            "Initialise le joueur et charge les mots a trouver"
            print("Veuillez entrer votre nom et appuyer sur <ENTER>: ")
            self.nom = input()
            if self.nom:
                self.nom = self.nom.capitalize().strip()
                self.donnees = self.joueur.recherche(self.nom)
                print("Bienvenu {} !".format(self.donnees[0]))
                print("Vous vous avez comptabilisé {} point(s) pour {} mot(s) trouvés !"
                      .format(self.donnees[1][0], self.donnees[1][1]))
                print("")
                print("Appuyez sur <ENTER> pour commencer la partie")
                input("")
                self.sequence()
            else:
                print("Erreur de saisie ! le nom doit contenir au moin 1 caractère !")
                print("")
                self.commencer()
            
                
        def sequence(self):
            "Realise une partie complete du jeu du pendu"
            self.enigme.malus = 1
            self.motClair = self.enigme.pioche()
            self.motCrypt = self.enigme.convert(self.motClair)
            statScore, statMot = self.donnees[1][0], self.donnees[1][1]
            while 1: 
                print("Mot a trouver: {}, veuillez taper une lettre: ".format(
                    self.motCrypt))
                print("Il vous reste {} chances pour trouver !".format(
                    8-self.enigme.malus))
                carac = input()
                if len(carac) != 1: # Il doit y avoir une seule lettre !
                    print("Saisie incorecte, vous devez entrer une seule lettre")
                else:
                    carac = carac.lower() # en minuscule
                self.motCrypt = self.enigme.afficheLettre(carac, self.motClair, self.motCrypt)
                if self.motCrypt == self.motClair:
                    statMot+=1
                    statScore = statScore + (100//self.enigme.malus) # MAJ score et mots
                    self.donnees[1] = (statScore, statMot)
                    self.joueur.incremente(self.donnees[0], self.donnees[1]) # MAJ du Score
                    self.joueur.sauver() # Effectue la sauvegarde
                    print("Bravo ! Vous avez gagné !")
                    print("")
                    print("Votre score a été mis a jour !")
                    print("tapez <Q> pour revenir au menu principal")
                    print("ou <ENTER> pour recommencer une partie: ")
                    quitter = input()
                    
                    if quitter.upper()!= "Q":
                        self.sequence()
                    else:
                        break
                        Pendu()
    
                elif self.enigme.malus == 8:
                    statMot+=1 # incremente 1 au nombre de mots
                    self.donnees[1] = (statScore, statMot)
                    self.joueur.incremente(self.donnees[0], self.donnees[1]) # MAJ du Score
                    self.joueur.sauver() # Effectue la sauvegarde
                    print("Vous avez perdu !")
                    print("")
                    print("le mot était: {} !".format(self.motClair))
                    print("tapez <Q> pour revenir au menu principal")
                    quitter = input("ou <ENTER> pour recommencer une partie: ")
                    if quitter.upper() != "Q":
                        self.sequence()
                    else:
                        break
                        Pendu()
                
    
    if __name__ == "__main__":
        Pendu()
    


    quand je commence une partie, si je veut en rejouer une autre et qu'ensuite je veut quitter, il me réaffiche le mot avec le nombre de chances restant pour le trouver, j'ai essayé pas mal de choses, mais je n'arrive pas a résoudre ce probleme de manière a quand je rentre "Q" pour quitter, le jeu reviens au menu principal !
    Je précise que ça ne le fait que si on rejoue une partie et qu'on quitte ensuite !
    Merci d'avance de votre aide !
    • Partager sur Facebook
    • Partager sur Twitter
      24 décembre 2010 à 17:29:20

      Salut,

      Quand tu commentes les lignes 90 et 106 ("break") cela résout ton problème ou pas ?
      • Partager sur Facebook
      • Partager sur Twitter
        25 décembre 2010 à 8:40:12

        Non justement, si je quitte dirrectement après une seule partie ça fonctionne correctement, mais si je rejoue une partie et ensuite je quitte, ça bug !
        apparement il y a un problème avec la boucle au niveau de la ligne 63 qui n'est pas interrompu car il n'y a pas de réinitialisation du mot et du "malus".
        • Partager sur Facebook
        • Partager sur Twitter
          25 décembre 2010 à 11:56:40

          je pense que le problème est ici ...

          'Q' apelle sequence() alors que ça devrait beaker je crois ?

          break est suivit d'une instruction ?

          print("tapez <Q> pour revenir au menu principal")
                      quitter = input("ou <ENTER> pour recommencer une partie: ")
                      if quitter.upper() != "Q":
                          self.sequence()
                      else:
                          break
                          Pendu()
          


          • Partager sur Facebook
          • Partager sur Twitter

          Python c'est bon, mangez-en. 

            25 décembre 2010 à 16:49:52

            Salut Darioo2,
            1. Joyeux Noël et meilleurs vœux pour 2011.
            2. Tu utilises de nombreuses qui n'ont pas été initialisée. C'est dangereux car tu ne sais pas ce qu'elles peuvent contenir ! Par exemple les variables debut, carac n'ont pas été initialisées. Ce n'est pas l'idéal.

            Ton code :
            Je viens de jeter un œil rapidement sur ton code. J'ai l'une ou l'autre remarque à faire :
            - Dans la classe pendu, lignes 11 à 16 : tu ne connais pas \n au lieu de ces multiples lignes print("") ?
            Cela se répète à plusieurs endroits dans ton code.

            Pour ton problème :

            Citation : Classe Pendu, ligne 32


            elif debut == "C":
            self.commencer()


            Tu initialises debut à la valeur C mais après, tu ne le réinitialise pas quand tu quittes.

            Citation : Classe sequence, ligne 87


            if quitter.upper()!= "Q":
            self.sequence()
            else:
            break
            Pendu()


            Là, si quitter n'est pas Q, on continue. C'est OK
            Mais si quitter est Q ???
            Break. C'est OK mais 1 ligne trop tôt !
            Mais il faut d'abord réinitialiser la variable debut sans quoi, ton programme sait qu'il doit jouer.
            Et ensuite, seulement, tu break.

            L'appel à Pendu() après break ne sert à rien puisque le programme break, il quitte la boucle.

            A+
            • Partager sur Facebook
            • Partager sur Twitter
            Savoir, c'est bien; apprendre c'est mieux; partager c'est parfait.
              25 décembre 2010 à 17:36:09

              Merci pour vos réponses !

              J'ai modifié un peu le code de manière a réinitialiser la variable debut et changer les instructions else par elif pour mieux cibler la requette mais le problème est toujours le meme !
              #!/usr/bin/python
              #-*- coding: UTF-8 -*-
              
              from classes import *
              
              class Pendu(object):
                  """Application du jeu du pendu version console"""
                  def __init__(self):
                      self.joueur = Score() # instanciation de la classe Score
                      self.enigme = Mot() # Instanciation de la classe Mot
                      print("")
                      print("")
                      print("Bienvenu sur le jeu du pendu ! (version console)")
                      print("")
                      print("version 1.0 éditée par Dario")
                      print("")
                      while 1:
                          print("Veuillez entrer votre choix et appuyer sur <ENTER>")
                          print("<C> pour commencer une nouvelle partie")
                          print("<A> pour afficher les meilleurs scores")
                          print("<Q> pour quitter le programme")
                          debut = input("")
                          debut = debut.upper().strip() # Choix de l'utilisateur
                          if debut == "Q":
                              print("Fin de partie merci d'avoir participé !")
                              print("Appuyez sur <ENTER > pour fermer la fenetre")
                              input()
                              break
                          elif debut == "A": # Scores par ordre décroissants
                              self.joueur.affiche()
                              print("")
                          elif debut == "C":
                              self.commencer()
                          else:
                              print("Choix incorect !")
                  
                  def commencer(self):
                      "Initialise le joueur et charge les mots a trouver"
                      print("Veuillez entrer votre nom et appuyer sur <ENTER>: ")
                      self.nom = input()
                      if self.nom:
                          self.nom = self.nom.capitalize().strip()
                          self.donnees = self.joueur.recherche(self.nom)
                          print("Bienvenu {} !".format(self.donnees[0]))
                          print("Vous vous avez comptabilisé {} point(s) pour {} mot(s) trouvés !"
                                .format(self.donnees[1][0], self.donnees[1][1]))
                          print("")
                          print("Appuyez sur <ENTER> pour commencer la partie")
                          input("")
                          self.sequence()
                      else:
                          print("Erreur de saisie ! le nom doit contenir au moin 1 caractère !")
                          print("")
                          self.commencer()
                      
                          
                  def sequence(self):
                      "Realise une partie complete du jeu du pendu"
                      self.enigme.malus = 1
                      self.motClair = self.enigme.pioche()
                      self.motCrypt = self.enigme.convert(self.motClair)
                      statScore, statMot = self.donnees[1][0], self.donnees[1][1]
                      while 1: 
                          print("Mot a trouver: {}, veuillez taper une lettre: ".format(
                              self.motCrypt))
                          print("Il vous reste {} chances pour trouver !".format(
                              8-self.enigme.malus))
                          carac = input()
                          if len(carac) != 1: # Il doit y avoir une seule lettre !
                              print("Saisie incorecte, vous devez entrer une seule lettre")
                          else:
                              carac = carac.lower() # en minuscule
                          self.motCrypt = self.enigme.afficheLettre(carac, self.motClair, self.motCrypt)
                          if self.motCrypt == self.motClair:
                              statMot+=1
                              statScore = statScore + (100//self.enigme.malus) # MAJ score et mots
                              self.donnees[1] = (statScore, statMot)
                              self.joueur.incremente(self.donnees[0], self.donnees[1]) # MAJ du Score
                              self.joueur.sauver() # Effectue la sauvegarde
                              print("Bravo ! Vous avez gagné !")
                              print("")
                              print("Votre score a été mis a jour !")
                              print("tapez <Q> pour revenir au menu principal")
                              print("ou <ENTER> pour recommencer une partie: ")
                              quitter = input()
                              
                              if quitter.upper()!= "Q":
                                  self.sequence()
                              elif quitter.upper() =="Q":
                                  debut = None
                                  break
              
                          elif self.enigme.malus == 8:
                              statMot+=1 # incremente 1 au nombre de mots
                              self.donnees[1] = (statScore, statMot)
                              self.joueur.incremente(self.donnees[0], self.donnees[1]) # MAJ du Score
                              self.joueur.sauver() # Effectue la sauvegarde
                              print("Vous avez perdu !")
                              print("")
                              print("le mot était: {} !".format(self.motClair))
                              print("tapez <Q> pour revenir au menu principal")
                              quitter = input("ou <ENTER> pour recommencer une partie: ")
                              if quitter.upper() != "Q":
                                  self.sequence()
                              elif quitter.upper() =="Q":
                                  debut= None
                                  break
                          
              
              if __name__ == "__main__":
                  Pendu()
              

              merci pour les remarques sur mon code, je tacherais de le réviser un peu pour l'améliorer au niveau des print et voir pour certaines variables !.
              il semble que le probleme viens vraiment du fait que le while1: ne se break pas, parce qu'il me relance la boucle a partir sans repiocher un autre mot !

              EDIT: Apparement j'ai résolu le problème en remplacant les break par Pendu(), le jeu reviens au menu principal comme ça, mais je ne sais toujours pas pourquoi mon break ne break pas ;p
              Merci de votre aide, je vais essayé de retravailler un peu le code pour corriger mes erreurs, et eventuellement le poster ici si quelqu'un veut me donner son avis !
              @ +++
              • Partager sur Facebook
              • Partager sur Twitter
                26 décembre 2010 à 4:21:08

                Un petit détail : quelle version de Python utilises-tu et sous quel IDE ?
                Parce que moi, sous Ulipad, j'ai des dizaines "d'incohérences" par rapport à la version Python 2.6. Actuellement, on est à la version - stable - 3.1.2 mais il est encore -pour combien de temps encore ? - conseillé de travailler avec 2.6 au minimum et 2.7 même s'il est déjà possible de travailler sous 3.1 mais avec le risque que dans certaines versions de logiciels, 3.x ne soit pas encore implémentée.
                Actuellement, on se dirige doucement vers la version 3.x. J'écris "on se dirige" même si elle est déjà d'application, il y a encore peu d'applications "pros" qui sont sous Python 3.x.

                Il est plus que fortement conseillé d'initialiser TOUTES les variables avant de les utiliser dans le code pour plusieurs raisons :
                1. on sait facilement les retrouver et savoir d'où elle proviennent (variables locales, globales, ...)
                2. On est certain de leur contenu puisqu'à l'initialisation on définit leur contenu.

                Ta variable "debut" est "déclarée" (ou plutôt utilisée sans déclaration ni initialisation) locale dans la "def __init__" et n'est donc plus accessible depuis "def sequence" !
                Il te faut déclarer "debut" comme globale.

                A+
                • Partager sur Facebook
                • Partager sur Twitter
                Savoir, c'est bien; apprendre c'est mieux; partager c'est parfait.
                  26 décembre 2010 à 11:39:31

                  Bonjour,
                  Merci pour tes remarques, je suis en phase apprentissage, donc ça m'aide beaucoups de comprendre ce qui ne va pas dans ma façon de coder !
                  J'ai essayé de modifier un peu le code pour le rendre plus fiable en initialisant les variables, je n'ai plus aucun problèmes d'execution du programme, j'ai aussi essayé de limiter le nombre de print quand cela était possible.
                  #!/usr/bin/python
                  #-*- coding: UTF-8 -*-
                  
                  from classes import *
                  
                  class Pendu(object):
                      """Application du jeu du pendu version console"""
                      def __init__(self):
                          self.joueur = Score() # instanciation de la classe Score
                          self.enigme = Mot() # Instanciation de la classe Mot
                          self.debut, self.enigme.malus = "", None
                          print("\n\nBienvenu sur le jeu du pendu ! (version console)\
                                  \n\nversion 1.0 éditée par Dario\n")
                          while 1:
                              print("Veuillez entrer votre choix et appuyer sur <ENTER>\
                                      \n<C> pour commencer une nouvelle partie\
                                      \n<A> pour afficher les meilleurs scores\
                                      \n<Q> pour quitter le programme")
                              self.debut = input("")
                              self.debut = self.debut.upper().strip() # Choix de l'utilisateur
                              if self.debut == "Q":
                                  print("Fin de partie merci d'avoir participé !")
                                  print("Appuyez sur <ENTER > pour fermer la fenetre")
                                  input()
                                  break
                              elif self.debut == "A": # Scores par ordre décroissants
                                  self.joueur.affiche()
                                  print("")
                              elif self.debut == "C":
                                  self.commencer()
                              else:
                                  print("Choix incorect !")
                      
                      def commencer(self):
                          "Initialise le joueur et charge les mots a trouver"
                          print("Veuillez entrer votre nom et appuyer sur <ENTER>: ")
                          self.nom = input()
                          if self.nom:
                              self.nom = self.nom.capitalize().strip()
                              self.donnees = self.joueur.recherche(self.nom)
                              print("Bienvenu {} !".format(self.donnees[0]))
                              print("Vous vous avez comptabilisé {} point(s) pour {} mot(s) trouvés !"
                                    .format(self.donnees[1][0], self.donnees[1][1]))
                              print("\nAppuyez sur <ENTER> pour commencer la partie\n")
                              input("")
                              self.sequence()
                          else:
                              print("Erreur de saisie ! le nom doit contenir au moin 1 caractère !\n")
                              self.commencer()
                          
                              
                      def sequence(self):
                          "Realise une partie complete du jeu du pendu"
                          self.enigme.malus = 1
                          self.motClair = self.enigme.pioche()
                          self.motCrypt = self.enigme.convert(self.motClair)
                          statScore, statMot = self.donnees[1][0], self.donnees[1][1]
                          while self.enigme.malus != None: 
                              print("Mot a trouver: {}, veuillez taper une lettre: ".format(
                                  self.motCrypt))
                              print("Il vous reste {} chances pour trouver !".format(
                                  8-self.enigme.malus))
                              carac = input()
                              if len(carac) != 1: # Il doit y avoir une seule lettre !
                                  print("Saisie incorecte, vous devez entrer une seule lettre")
                              else:
                                  carac = carac.lower() # en minuscule
                              self.motCrypt = self.enigme.afficheLettre(carac, self.motClair, self.motCrypt)
                              if self.motCrypt == self.motClair:
                                  statMot+=1
                                  statScore = statScore + (100//self.enigme.malus) # MAJ score et mots
                                  self.donnees[1] = (statScore, statMot)
                                  self.joueur.incremente(self.donnees[0], self.donnees[1]) # MAJ du Score
                                  self.joueur.sauver() # Effectue la sauvegarde
                                  self.enigme.malus = None # Réinitialisation de la variable
                                  print("Bravo ! Vous avez gagné !\n\nVotre score a été mis a jour !\
                                          \nTapez <Q> pour revenir au menu principal\
                                          \nou <ENTER> pour recommencer une partie: ")
                                  quitter = input()
                                  if quitter.upper()!= "Q":
                                      self.sequence()
                                  elif quitter.upper() =="Q":
                                      self.debut = None
                  
                              elif self.enigme.malus == 8:
                                  statMot+=1 # incremente 1 au nombre de mots
                                  self.donnees[1] = (statScore, statMot)
                                  self.joueur.incremente(self.donnees[0], self.donnees[1]) # MAJ du Score
                                  self.joueur.sauver() # Effectue la sauvegarde
                                  self.enigme.malus = None # Réinitialisation de la variable
                                  print("Vous avez perdu !\nle mot était: {} !".format(self.motClair))
                                  print("tapez <Q> pour revenir au menu principal")
                                  quitter = input("ou <ENTER> pour recommencer une partie: ")
                                  if quitter.upper() != "Q":
                                      self.sequence()
                                  elif quitter.upper() =="Q":
                                      self.debut = ""
                              
                  
                  if __name__ == "__main__":
                      Pendu()
                  

                  J'utilise la version 3.1.2 puisque j'ai commencer sur cette version avec un livre qui traite de python3. Pygame et PyQt sont compatibles avec python3 maintenant donc je pense que j'ai encore de quoi faire.
                  Je code principalement sous IDLE, j'ai aussi utilisé un peu pydev mais finalement je m'y retrouve sur plus sur IDLE vu que j'ai un ecran large, je peut facilement ouvrir 2 ou 3 fenetres de code + l'interpreteur et vu que je suis en phase d'apprentissage, l'autocompletion ne m'interesse pas pour le moment.
                  @ +++
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Problème code jeu du pendu !

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown