Algo. et prog. 2 en
Logo de Python
Arnaud COUTURIER - Python 3.10

✏️ TP 12 - Jeu du pendu niv.3 ✔️

Ce TP est la suite directe du pendu niveau 2.

Pour rappel, voici le jeu du pendu dans son intégralité. C'est ce que vous aurez à la fin de ce TP, et vers quoi les questions ci-dessous vont vous guider:

Question 1

On va commencer à se pencher sur les dessins pendant le jeu. Pour commencer, dans cette question on va se contenter de juste créer les dessins, on ne les affiche pas encore durant le jeu.

Créer une variable globale de type list, qui contiendra chaque dessin du pendu selon l'évolution du joueur (plus ou moins pendu). Chaque dessin est en fait une chaîne de caractères, qui grâce à l'agencement de caractères spéciaux sur plusieurs lignes, forment un dessin.

Vous pouvez vous servir des triples guillemets """ ou ''', qui comme vous l'avez vu jusqu'ici permettent de délimiter des commentaires sur plusieurs lignes, mais également à délimiter des chaînes de caractères sur plusieurs lignes, ce qui est pratique dans notre cas.

Vous pouvez vous aider des caractères suivants pour vos dessins: ░ ╩ ╠ ═ ║ ╪ ┼ ─ │, mais vous êtes libres de faire les dessins que vous souhaitez. Vous pouvez trouver de nombreux caractères spéciaux grâce au programme "Table des caractères" dans Windows, par exemple.

Voici un exemple, sous forme de code, d'un des dessins que vous devez créer dans la liste de tous les dessins:


			"""
			╠══════╪
			║
			║
			║
			║
			║
			║
		  ══╩════════
		░░░░░░░░░░░░░░░░░"""
		

					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]
				

Question 2

Créer une fonction qui permet d'afficher un des dessins du pendu, en se servant de la liste créée dans la question précédente. La fonction prend un seul paramètre de type int, qui donne le nombre d'essais restants au joueur avant d'avoir perdu. À partir du nombre d'essais restants qu'on lui passe, la fonction est capable d'afficher le dessin correspondant.

Par exemple s'il reste 0 essai restant, ça signifie que le joueur a perdu, et que donc il faut afficher le dessin du pendu complet. Si au contraire il reste des essais restants, il faut afficher un dessin intermédiaire, ou celui qui correspond au début du jeu en cas de nombre d'essais maximal. (d'ailleurs, question qu'il vous faudra résoudre : quel est ce nombre maximal d'essais possibles ?)


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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 3

Utiliser votre fonction et liste créées précédemment, en les intégrant dans le jeu cette fois, afin que le joueur voit son état (plus ou moins pendu). Testez votre jeu pour vérifier que ça fonctionne.


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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 3
					import random
					import copy
					import time
					import os

					ENSEMBLE_DE_TOUS_LES_MOTS = set()
					charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_3 liste mots.txt")
					mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
					# désormais le nombre d'essais restants dépend du nombre de dessins
					essais_restants = len(DESSINS_PENDUS) - 1
					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")
							print("Votre score actuel:", total_mots_devinés)
							# On affiche le pendu au bon endroit
							afficher_pendu(essais_restants)
							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:
							# On affiche le pendu une dernière fois quand le joueur a perdu
							os.system("cls")
							afficher_pendu(essais_restants)
							print("Perdu. Le mot est:", mot_à_deviner)
						else:
							print("Gagné! Le mot est:", mot_à_deviner)
							total_mots_devinés += 1
						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)
				

Question 4

On va rajouter un menu principal à notre jeu, afin que le joueur puisse rejouer une fois qu'il / elle a gagné ou perdu. Dans le menu principal il n'y aura que 2 options : jouer et quitter. L'option jouer lance le jeu tel que vous l'avez développé jusqu'à présent.

Tout d'abord placer tout le code de la logique de votre jeu dans une fonction, afin qu'une partie de pendu puisse facilement être lancée par simple appel de cette fonction. Cela facilitera et raccourcira l'écriture du code du menu principal. Cette fonction ne doit prendre aucun paramètre. Lorsque le joueur gagne (tous les mots devinés) ou perd (plus aucun essai restant), la fonction se termine et retourne le nombre de mots que le joueur a pu trouver au cours de la partie.

Ensuite, dans le contexte global (c'est-à-dire en dehors de toute fonction), créer le menu principal (une boucle while comme vous en avez l'habitude désormais), avec les 2 options citées plus haut. L'option "jouer" doit lancer une partie. L'option "quitter" doit terminer le programme.


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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
					import random
					import copy
					import time
					import os

					ENSEMBLE_DE_TOUS_LES_MOTS = set()
					charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_3 liste mots.txt")


					# nouvelle fonction où une partie entière se déroule
					def jouer():
						mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
						essais_restants = len(DESSINS_PENDUS) - 1
						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")
								print("Votre score actuel:", total_mots_devinés)
								afficher_pendu(essais_restants)
								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:
								os.system("cls")
								afficher_pendu(essais_restants)
								print("Perdu. Le mot est:", mot_à_deviner)
							else:
								print("Gagné! Le mot est:", mot_à_deviner)
								total_mots_devinés += 1
							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)
						time.sleep(2) # on rajoute cette pause car les messages seront effacés dans le menu principal
						os.system("cls") # puis on nettoie l'écran de jeu pour que la suite puisse s'afficher proprement
						return total_mots_devinés


					# Boucle menu principal
					os.system("cls")
					réponse_joueur = ""
					while réponse_joueur != "q":
						os.system("cls")
						print("j - jouer")
						print("q - quitter")
						réponse_joueur = input("Action: ")
						os.system("cls")
						if "j" == réponse_joueur:
							jouer()
				

Question 5

Afficher au joueur son meilleur score dans le menu principal.

Le score est simplement le nombre de mots trouvés lors d'une partie. Le meilleur score n'est pas retenu entre chaque lancement du programme, il commence toujours à zéro. Mais il est retenu entre chaque partie, et il est mis à jour à la fin d'une partie si lors de celle-ci le joueur a trouvé plus de mots que le meilleur score qu'il a pu avoir jusque-là.


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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
					import random
					import copy
					import time
					import os
					
					ENSEMBLE_DE_TOUS_LES_MOTS = set()
					charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_3 liste mots.txt")
					
					
					def jouer():
						mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
						essais_restants = len(DESSINS_PENDUS) - 1
						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")
								print("Votre score actuel:", total_mots_devinés)
								afficher_pendu(essais_restants)
								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:
								os.system("cls")
								afficher_pendu(essais_restants)
								print("Perdu. Le mot est:", mot_à_deviner)
							else:
								print("Gagné! Le mot est:", mot_à_deviner)
								total_mots_devinés += 1
							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)
						time.sleep(2)
						os.system("cls")
						return total_mots_devinés
					
					
					os.system("cls")
					max_mots_trouvés = 0  # le meilleur score
					réponse_joueur = ""
					while réponse_joueur != "q":
						os.system("cls")
						print("Meilleur score:", max_mots_trouvés)
						print("j - jouer")
						print("q - quitter")
						réponse_joueur = input("Action: ")
						os.system("cls")
						if "j" == réponse_joueur:
							# On garde le meilleur score désormais
							score_dernier_jeu = jouer()
							max_mots_trouvés = max(score_dernier_jeu, max_mots_trouvés)
				

Question 6

Ajouter une option dans le menu principal pour permettre au joueur de voir l'ensemble des mots qui sont proposés à chaque partie. Cet ensemble n'est pas affiché en temps normal, seulement quand cette option est choisie.


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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 6
					import random
					import copy
					import time
					import os
					
					ENSEMBLE_DE_TOUS_LES_MOTS = set()
					charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, "pendu_3 liste mots.txt")
					
					
					def jouer():
						mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
						essais_restants = len(DESSINS_PENDUS) - 1
						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")
								print("Votre score actuel:", total_mots_devinés)
								afficher_pendu(essais_restants)
								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:
								os.system("cls")
								afficher_pendu(essais_restants)
								print("Perdu. Le mot est:", mot_à_deviner)
							else:
								print("Gagné! Le mot est:", mot_à_deviner)
								total_mots_devinés += 1
							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)
						time.sleep(2)
						os.system("cls")
						return total_mots_devinés
					
					
					os.system("cls")
					max_mots_trouvés = 0
					réponse_joueur = ""
					while réponse_joueur != "q":
						print("Meilleur score:", max_mots_trouvés)
						print("j - jouer")
						print("v - voir tous les mots existants") # nouvelle option
						print("q - quitter")
						réponse_joueur = input("Action: ")
						os.system("cls")
						if "j" == réponse_joueur:
							score_dernier_jeu = jouer()
							max_mots_trouvés = max(score_dernier_jeu, max_mots_trouvés)
						elif "v" == réponse_joueur:
							# Affichage des mots
							print("Tous les mots:", ENSEMBLE_DE_TOUS_LES_MOTS)
							print()
				

Question 7

Ajouter une option dans le menu principal pour permettre au joueur d'ajouter un mot dans l'ensemble des mots. Attention cet ajout doit être persistant, permanent, c'est-à-dire que lorsque le programme se termine, et qu'on le relance ensuite, le mot ajouté précédemment est toujours présent. Il vous faudra donc modifier le fichier texte qui contient la liste de tous les mots.

Je vous recommande de créer une fonction pour ça, puis de l'exécuter dans le menu principal lorsque l'option pour ajouter un mot est choisie. Cette fonction prend 2 paramètres : le nouveau mot à ajouter (de type str) et un ensemble de tous les mots du jeu (de type set). Cette fonction fait l'ajout aussi bien dans la liste des mots en mémoire (celle que le jeu utilise pendant son exécution) que dans le fichier qui contient tous les mots. Elle ne retourne rien, aucun résultat.

Attention à ne pas permettre l'ajout d'un même mot plusieurs fois, dans l'ensemble des mots en mémoire, comme dans le fichier texte.


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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 7
					# Création de cette variable, car on en a besoin à plusieurs endroits
					NOM_FICHIER_TEXTE_MOTS = "pendu_3 liste mots.txt"
					
					
					# Ajout de cette fonction
					def ajouter_mot(nouveau_mot, tous_les_mots):
						if nouveau_mot in tous_les_mots:
							return
						tous_les_mots.add(nouveau_mot)
						with open(NOM_FICHIER_TEXTE_MOTS, "a") as f:
							f.write(nouveau_mot + "\n")
					
					
					import random
					import copy
					import time
					import os
					
					ENSEMBLE_DE_TOUS_LES_MOTS = set()
					# utilisation de la variable NOM_FICHIER_TEXTE_MOTS au lieu d'écrire directement le nom du fichier
					charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, NOM_FICHIER_TEXTE_MOTS)
					
					
					def jouer():
						mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
						essais_restants = len(DESSINS_PENDUS) - 1
						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")
								print("Votre score actuel:", total_mots_devinés)
								afficher_pendu(essais_restants)
								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:
								os.system("cls")
								afficher_pendu(essais_restants)
								print("Perdu. Le mot est:", mot_à_deviner)
							else:
								print("Gagné! Le mot est:", mot_à_deviner)
								total_mots_devinés += 1
							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)
						time.sleep(2)
						os.system("cls")
						return total_mots_devinés
					
					
					os.system("cls")
					max_mots_trouvés = 0
					réponse_joueur = ""
					while réponse_joueur != "q":
						print("Meilleur score:", max_mots_trouvés)
						print("j - jouer")
						print("v - voir tous les mots existants")
						print("a - ajouter un mot (modif. persistante)")  # nouvelle option
						print("q - quitter")
						réponse_joueur = input("Action: ")
						os.system("cls")
						if "j" == réponse_joueur:
							score_dernier_jeu = jouer()
							max_mots_trouvés = max(score_dernier_jeu, max_mots_trouvés)
						elif "v" == réponse_joueur:
							print("Tous les mots:", ENSEMBLE_DE_TOUS_LES_MOTS)
							print()
						elif "a" == réponse_joueur:
							# Ajout PERSISTANT de mots
							ajouter_mot(input("Nouveau mot: ").lower(), ENSEMBLE_DE_TOUS_LES_MOTS)
							print("Mot ajouté.")
							print()
				

Question 8

Cette question est similaire à la précédente, mais pour supprimer des mots cette fois.

Je vous recommande à nouveau de créer une fonction pour la suppression, et de l'exécuter ensuite lorsque l'option de suppression de mot est choisie dans le menu principal. Elle prend les mêmes paramètres que la fonction d'ajout, mais supprime un mot au lieu de l'ajouter.

Prendre en compte le cas où le mot spécifié n'existe pas, il faut le préciser au joueur sans provoquer d'erreur.


					# Question 1: créer les dessins
					DESSINS_PENDUS = [
						"""
					░░░░░░░░░░░░░░░░░""",
						"""
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║
						║
						║
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /
						║ /
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/
						║
						║
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
						"""
						╠══════╪
						║  /   │
						║ /    ║
						║/     O
						║     ─┼─
						║     / \\
						║
					  ══╩════════
					░░░░░░░░░░░░░░░░░""",
					]


					# Question 2: créer cette fonction
					def afficher_pendu(essais_restants):
						indice = len(DESSINS_PENDUS) - essais_restants - 1
						if indice <= 0:
							print(DESSINS_PENDUS[0])
						elif indice >= len(DESSINS_PENDUS):
							print(DESSINS_PENDUS[-1])
						else:
							print(DESSINS_PENDUS[indice])


					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)


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


					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 8
					NOM_FICHIER_TEXTE_MOTS = "pendu_3 liste mots.txt"


					# Ajout de cette fonction
					def supprimer_mot(mot_à_supprimer, tous_les_mots):
						tous_les_mots.remove(mot_à_supprimer)
						with open(NOM_FICHIER_TEXTE_MOTS, "w") as f:
							for mot in tous_les_mots:
								f.write(mot + "\n")


					def ajouter_mot(nouveau_mot, tous_les_mots):
						if nouveau_mot in tous_les_mots:
							return
						tous_les_mots.add(nouveau_mot)
						with open(NOM_FICHIER_TEXTE_MOTS, "a") as f:
							f.write(nouveau_mot + "\n")


					import random
					import copy
					import time
					import os

					ENSEMBLE_DE_TOUS_LES_MOTS = set()
					# utilisation de la variable NOM_FICHIER_TEXTE_MOTS au lieu d'écrire directement le nom du fichier
					charger_mots_depuis_fichier(ENSEMBLE_DE_TOUS_LES_MOTS, NOM_FICHIER_TEXTE_MOTS)


					def jouer():
						mots_non_devinés = copy.copy(ENSEMBLE_DE_TOUS_LES_MOTS)
						essais_restants = len(DESSINS_PENDUS) - 1
						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")
								print("Votre score actuel:", total_mots_devinés)
								afficher_pendu(essais_restants)
								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:
								os.system("cls")
								afficher_pendu(essais_restants)
								print("Perdu. Le mot est:", mot_à_deviner)
							else:
								print("Gagné! Le mot est:", mot_à_deviner)
								total_mots_devinés += 1
							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)
						time.sleep(2)
						os.system("cls")
						return total_mots_devinés


					os.system("cls")
					max_mots_trouvés = 0
					réponse_joueur = ""
					while réponse_joueur != "q":
						print("Meilleur score:", max_mots_trouvés)
						print("j - jouer")
						print("v - voir tous les mots existants")
						print("a - ajouter un mot (modif. persistante)")
						print("s - supprimer un mot (modif. persistante)")  # nouvelle option
						print("q - quitter")
						réponse_joueur = input("Action: ")
						os.system("cls")
						if "j" == réponse_joueur:
							score_dernier_jeu = jouer()
							max_mots_trouvés = max(score_dernier_jeu, max_mots_trouvés)
						elif "v" == réponse_joueur:
							print("Tous les mots:", ENSEMBLE_DE_TOUS_LES_MOTS)
							print()
						elif "a" == réponse_joueur:
							ajouter_mot(input("Nouveau mot: ").lower(), ENSEMBLE_DE_TOUS_LES_MOTS)
							print("Mot ajouté.")
							print()
						elif "s" == réponse_joueur:
							# Suppression PERSISTANTE des mots
							try:
								supprimer_mot(input("Mot à supprimer: ").lower(), ENSEMBLE_DE_TOUS_LES_MOTS)
								print("Mot supprimé.")
							except KeyError:
								print("Ce mot n'existe pas.")
							print()