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 !
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".
'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()
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+
Savoir, c'est bien; apprendre c'est mieux; partager c'est parfait.
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 !
@ +++
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+
Savoir, c'est bien; apprendre c'est mieux; partager c'est parfait.
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.
@ +++
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.
Python c'est bon, mangez-en.