Ce TP est la suite directe du pendu niveau 1.
Créer une fonction qui prend 2 paramètres:
set) de mots sous forme de strstrLa fonction doit charger tous les mots listés dans le fichier dont le nom est spécifié, dans l'ensemble passé en paramètre. Le plus simple comme format du fichier sera d'y mettre un seul mot par ligne.
Vous pouvez utiliser deux méthodes de la classe str:
.lower() qui retourne la version d'une chaîne où toutes les lettres sont en minuscule. Rappellez-vous une str est
immuable donc la valeur retournée est une NOUVELLE str, l'objet str initial sur lequel on appelle la méthode reste
inchangé.
.rstrip() qui permet d'enlever un caractère ou une séquence de caractère à droite d'une chaîne.
def mot_est_deviné(mot_à_deviner, lettres_à_révéler_set):
for lettre in mot_à_deviner:
if lettre not in lettres_à_révéler_set:
return False
return True
def afficher_mot(mot_à_deviner, lettres_à_révéler_set):
str_à_afficher = ""
for lettre in mot_à_deviner:
if lettre in lettres_à_révéler_set:
str_à_afficher += lettre + " "
else:
str_à_afficher += "_ "
print(str_à_afficher)
# Question 1: créer cette fonction
def charger_mots_depuis_fichier(ensemble_mots, nom_fichier):
with open(nom_fichier, "r") as f:
for ligne in f:
ensemble_mots.add(ligne.lower().rstrip("\n"))
Créer un fichier texte dans le même dossier que votre fichier .py, mettez-y 2 ou 3 mots, un par ligne. Puis modifiez votre programme de façon à ce qu'il lise les mots à deviner depuis le fichier en utilisant votre fonction précédente, avant que la logique du jeu démarre.
def mot_est_deviné(mot_à_deviner, lettres_à_révéler_set):
for lettre in mot_à_deviner:
if lettre not in lettres_à_révéler_set:
return False
return True
def afficher_mot(mot_à_deviner, lettres_à_révéler_set):
str_à_afficher = ""
for lettre in mot_à_deviner:
if lettre in lettres_à_révéler_set:
str_à_afficher += lettre + " "
else:
str_à_afficher += "_ "
print(str_à_afficher)
# Question 1: créer cette fonction
def charger_mots_depuis_fichier(ensemble_mots, nom_fichier):
with open(nom_fichier, "r") as f:
for ligne in f:
ensemble_mots.add(ligne.lower().rstrip("\n"))
# Question 2: créer le fichier "pendu_2 liste mots.txt", puis s'en servir
import random
# Le précédent déclarait les mots directement dans un ensemble:
# tous_les_mots = {"bonjour", "salut", "voiture"}
# Le tp présent charge les mots dans un ensemble à partir d'un fichier désormais:
ENSEMBLE_DE_TOUS_LES_MOTS = set()
charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_2 liste mots.txt")
mot_à_deviner = random.choice(list(ENSEMBLE_DE_TOUS_LES_MOTS))
essais_restants = 3
ensemble_lettres_à_révéler = set()
while not mot_est_deviné(mot_à_deviner, ensemble_lettres_à_révéler) and essais_restants > 0:
afficher_mot(mot_à_deviner, ensemble_lettres_à_révéler)
print("Vie restante:", essais_restants)
lettre = input("Lettre: ")
ensemble_lettres_à_révéler.add(lettre)
if lettre not in mot_à_deviner:
essais_restants -= 1
if essais_restants <= 0:
print("Perdu. Le mot est:", mot_à_deviner)
else:
print("Gagné! Le mot est:", mot_à_deviner)
Créer une fonction qui prend 1 paramètre: un ensemble (donc de type set) de mots. La fonction doit:
choice() du module random.
Cherchez et regardez la doc de cette fonction pour savoir comment elle s'utilise. Vous devriez aussi avoir besoin de la fonction
list(), qui est en fait le constructeur de la classe list, et qui permet entre autre de transformer un
set en list.
.remove() de la classe set
def mot_est_deviné(mot_à_deviner, lettres_à_révéler_set):
for lettre in mot_à_deviner:
if lettre not in lettres_à_révéler_set:
return False
return True
def afficher_mot(mot_à_deviner, lettres_à_révéler_set):
str_à_afficher = ""
for lettre in mot_à_deviner:
if lettre in lettres_à_révéler_set:
str_à_afficher += lettre + " "
else:
str_à_afficher += "_ "
print(str_à_afficher)
# Question 1: créer cette fonction
def charger_mots_depuis_fichier(ensemble_mots, nom_fichier):
with open(nom_fichier, "r") as f:
for ligne in f:
ensemble_mots.add(ligne.lower().rstrip("\n"))
# Question 2: créer le fichier "pendu_2 liste mots.txt", puis s'en servir
import random
# Le TP précédent déclarait les mots directement dans un ensemble:
# tous_les_mots = {"bonjour", "salut", "voiture"}
# Le TP présent charge les mots dans un ensemble à partir d'un fichier désormais:
ENSEMBLE_DE_TOUS_LES_MOTS = set()
charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_2 liste mots.txt")
mot_à_deviner = random.choice(list(ENSEMBLE_DE_TOUS_LES_MOTS))
essais_restants = 3
ensemble_lettres_à_révéler = set()
while not mot_est_deviné(mot_à_deviner, ensemble_lettres_à_révéler) and essais_restants > 0:
afficher_mot(mot_à_deviner, ensemble_lettres_à_révéler)
print("Vie restante:", essais_restants)
lettre = input("Lettre: ")
ensemble_lettres_à_révéler.add(lettre)
if lettre not in mot_à_deviner:
essais_restants -= 1
if essais_restants <= 0:
print("Perdu. Le mot est:", mot_à_deviner)
else:
print("Gagné! Le mot est:", mot_à_deviner)
# Question 3: écrire cette fonction
def avoir_et_retirer_mot_aléatoire(ensemble_mots):
if len(ensemble_mots) <= 0:
return
mot = random.choice(list(ensemble_mots))
ensemble_mots.remove(mot)
return mot.lower()
Modifiez le code du programme principal pour que désormais, tous les mots sont proposés au joueur dans un ordre aléatoire, en utilisant la fonction précédente.
Il se peut que vous ayez besoin de la fonction copy du module copy, ou bien de la méthode .copy() de la classe
set, selon ce que vous préférez comme approche. Elles permettent de créer une copie de l'ensemble des mots, c'est à dire un nouvel
objet distinct de l'original, mais qui contient initialement les mêmes éléments. Les deux objets peuvent alors être modifiés indépendamment.
Si le joueur devine tous les mots sans épuiser son nombre d'essais, c'est à dire qu'il n'en reste aucun à deviner, alors il / elle a gagné, et le jeu se termine. Si le joueur épuise son nombre d'essais avant d'avoir découvert TOUS les mots, alors il / elle a perdu.
def mot_est_deviné(mot_à_deviner, lettres_à_révéler_set):
for lettre in mot_à_deviner:
if lettre not in lettres_à_révéler_set:
return False
return True
def afficher_mot(mot_à_deviner, lettres_à_révéler_set):
str_à_afficher = ""
for lettre in mot_à_deviner:
if lettre in lettres_à_révéler_set:
str_à_afficher += lettre + " "
else:
str_à_afficher += "_ "
print(str_à_afficher)
# Question 1: créer cette fonction
def charger_mots_depuis_fichier(ensemble_mots, nom_fichier):
with open(nom_fichier, "r") as f:
for ligne in f:
ensemble_mots.add(ligne.lower().rstrip("\n"))
# Question 3: écrire cette fonction
def avoir_et_retirer_mot_aléatoire(ensemble_mots):
if len(ensemble_mots) <= 0:
return
mot = random.choice(list(ensemble_mots))
ensemble_mots.remove(mot)
return mot.lower()
# Question 4: répéter jeu tant que tous les mots ont pas été sortis, déclarer vainqueur à la fin
import random
import copy # nouvel import
ENSEMBLE_DE_TOUS_LES_MOTS = set()
charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_2 liste mots.txt")
# mot_à_deviner = random.choice(list(ENSEMBLE_DE_TOUS_LES_MOTS)) <= on ne fait plus simplement ça
# Maintenant on va tenir un ensemble des mots restants à deviner, et choisir à partir de là
mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
essais_restants = 3
# on choisit un mot aléatoire pour commencer (s'il y en)
mot_à_deviner = avoir_et_retirer_mot_aléatoire(mots_non_devinés)
while mot_à_deviner and essais_restants > 0: # nouvelle boucle while "extérieure"
ensemble_lettres_à_révéler = set()
while not mot_est_deviné(mot_à_deviner, ensemble_lettres_à_révéler) and essais_restants > 0:
afficher_mot(mot_à_deviner, ensemble_lettres_à_révéler)
print("Vie restante:", essais_restants)
lettre = input("Lettre: ")
ensemble_lettres_à_révéler.add(lettre)
if lettre not in mot_à_deviner:
essais_restants -= 1
if essais_restants <= 0:
print("Perdu. Le mot est:", mot_à_deviner)
else:
print("Gagné! Le mot est:", mot_à_deviner)
# on choisit un mot aléatoire (s'il en reste) pour la prochaine boucle
mot_à_deviner = avoir_et_retirer_mot_aléatoire(mots_non_devinés)
# Joueur à fini le jeu en entier
if essais_restants > 0:
print("Bravo! Vous avez deviné tous les mots!")
Rajouter un score au jeu, et l'afficher au joueur pendant le jeu et à la fin, qu'il / elle ait gagné ou non. Le score est simplement le nombre de mots au total que le joueur a deviné jusque là.
def mot_est_deviné(mot_à_deviner, lettres_à_révéler_set):
for lettre in mot_à_deviner:
if lettre not in lettres_à_révéler_set:
return False
return True
def afficher_mot(mot_à_deviner, lettres_à_révéler_set):
str_à_afficher = ""
for lettre in mot_à_deviner:
if lettre in lettres_à_révéler_set:
str_à_afficher += lettre + " "
else:
str_à_afficher += "_ "
print(str_à_afficher)
# Question 1: créer cette fonction
def charger_mots_depuis_fichier(ensemble_mots, nom_fichier):
with open(nom_fichier, "r") as f:
for ligne in f:
ensemble_mots.add(ligne.lower().rstrip("\n"))
# Question 3: écrire cette fonction
def avoir_et_retirer_mot_aléatoire(ensemble_mots):
if len(ensemble_mots) <= 0:
return
mot = random.choice(list(ensemble_mots))
ensemble_mots.remove(mot)
return mot.lower()
# Question 5: gérer le score
import random
import copy
ENSEMBLE_DE_TOUS_LES_MOTS = set()
charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_2 liste mots.txt")
mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
essais_restants = 3
total_mots_devinés = 0 # on tient un score maintenant
mot_à_deviner = avoir_et_retirer_mot_aléatoire(mots_non_devinés)
while mot_à_deviner and essais_restants > 0:
ensemble_lettres_à_révéler = set()
while not mot_est_deviné(mot_à_deviner, ensemble_lettres_à_révéler) and essais_restants > 0:
# Affichage score pendant le jeu
print("Votre score actuel:", total_mots_devinés)
afficher_mot(mot_à_deviner, ensemble_lettres_à_révéler)
print("Vie restante:", essais_restants)
lettre = input("Lettre: ")
ensemble_lettres_à_révéler.add(lettre)
if lettre not in mot_à_deviner:
essais_restants -= 1
if essais_restants <= 0:
print("Perdu. Le mot est:", mot_à_deviner)
else:
print("Gagné! Le mot est:", mot_à_deviner)
total_mots_devinés += 1 # mise à jour du score
mot_à_deviner = avoir_et_retirer_mot_aléatoire(mots_non_devinés)
if essais_restants > 0:
print("Bravo! Vous avez deviné tous les mots!")
# Affichage score final
print("Votre score final:", total_mots_devinés)
Nettoyer l'écran en l'effaçant régulièrement, par exemple entre chaque lettre proposée par le joueur. Cela risque d'effacer vos messages au joueur
avant qu'il / elle ait le temps de les lire. Dans ce cas, vous pouvez mettre le jeu en pause pendant 2 ou 3 secondes, avec la fonction
sleep() du module time.
Voici ce que vous devriez avoir à la fin de ce TP:
def mot_est_deviné(mot_à_deviner, lettres_à_révéler_set):
for lettre in mot_à_deviner:
if lettre not in lettres_à_révéler_set:
return False
return True
def afficher_mot(mot_à_deviner, lettres_à_révéler_set):
str_à_afficher = ""
for lettre in mot_à_deviner:
if lettre in lettres_à_révéler_set:
str_à_afficher += lettre + " "
else:
str_à_afficher += "_ "
print(str_à_afficher)
# Question 1: créer cette fonction
def charger_mots_depuis_fichier(ensemble_mots, nom_fichier):
with open(nom_fichier, "r") as f:
for ligne in f:
ensemble_mots.add(ligne.lower().rstrip("\n"))
# Question 3: écrire cette fonction
def avoir_et_retirer_mot_aléatoire(ensemble_mots):
if len(ensemble_mots) <= 0:
return
mot = random.choice(list(ensemble_mots))
ensemble_mots.remove(mot)
return mot.lower()
# 6: nettoyage écran et pauses
import random
import copy
import time
import os
ENSEMBLE_DE_TOUS_LES_MOTS = set()
charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_2 liste mots.txt")
mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
essais_restants = 3
total_mots_devinés = 0
mot_à_deviner = avoir_et_retirer_mot_aléatoire(mots_non_devinés)
while mot_à_deviner and essais_restants > 0:
ensemble_lettres_à_révéler = set()
while not mot_est_deviné(mot_à_deviner, ensemble_lettres_à_révéler) and essais_restants > 0:
os.system("cls") # nettoyage ecran
print("Votre score actuel:", total_mots_devinés)
afficher_mot(mot_à_deviner, ensemble_lettres_à_révéler)
print("Vie restante:", essais_restants)
lettre = input("Lettre: ")
ensemble_lettres_à_révéler.add(lettre)
if lettre not in mot_à_deviner:
essais_restants -= 1
if essais_restants <= 0:
print("Perdu. Le mot est:", mot_à_deviner)
else:
print("Gagné! Le mot est:", mot_à_deviner)
total_mots_devinés += 1
# pause pour permettre au joueur de lire le message avant le prochain nettoyage d'écran
time.sleep(2)
mot_à_deviner = avoir_et_retirer_mot_aléatoire(mots_non_devinés)
if essais_restants > 0:
print("Bravo! Vous avez deviné tous les mots!")
print("Votre score final:", total_mots_devinés)