La note ne valide pas seulement le résultat de votre programme, mais également son style :
Vérifiez ces points avant de demander à votre intervenant de valider votre code.
Travailler avec :
Les dictionnaires ressemblent aux tableaux mais les cases ne sont pas "numérotées" par des entiers. Par exemple :
jours = { 'janvier': 31, 'février': 28, 'févrierB': 29, 'mars':31, 'avril':30, 'mai':31, 'juin':30, 'juillet':31, 'aout':31, 'septembre':30, 'octobre':31, 'novembre':30, 'decembre':31 }
L'accès à une case se fait de deux manières :
jours["janvier"]
,
get
: jours.get("janvier", ...)
.
L'intérêt de la méthode jours.get(...)
est qu'elle précise une valeur à utiliser si la case n'existe pas. Par exemple :
>>> print(jours["january"]) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'january' >>> print(jours.get("january", 123456)) 123456 >>> print(jours.get("janvier", 123456)) 31
Écrivez une fonction nb_jours
qui prend en argument une liste de noms de mois (des chaines de caractères) et renvoie le nombre de jours total de ces mois. Si un mois n'est pas valide, on ne compte pas de jours :
>>> print(nb_jours([])) 0 >>> print(nb_jours(['mars', 'avril'])) 61 >>> print(nb_jours(['mars', 'april'])) 31 >>> print(nb_jours(['avril', 'février', 'novembre', 'octobre', 'aout', 'mai', 'juillet', 'janvier', 'juin', 'mars', 'septembre', 'decembre'])) 365
Le but du jeu du pendu est de découvrir un mot en devinant ses lettres. L'objectif de ce TP est de pouvoir jouer contre l'ordinateur. Pour cela, nous allons partir d'un fichier qui contient tous les mots du célèbre dictionnaire d'Émile Littré.
Pour les questions qui suivent, vous pourrez utiliser le fichier littre.txt qui contient tous les mots du dictionnaire « Littré ». Ce fichier contient un mot par ligne et en voici un extrait :
ABAQUE ABAS ABASOURDI ABASOURDIR ABAT ABATAGE ABATANT ABATELLEMENT ABATIS ABATTABLE
On peut récupérer la liste de toutes les lignes d'un fichier avec la fonction suivante:
def lire_mots(nom_fichier): """fonction qui récupère la liste des mots dans un fichier paramètre - nom_fichier, de type chaine de caractère : nom du fichier contenant les mots (un par ligne) retour : liste de chaine de caractères """ liste_mots = [] # le tableau qui contiendra les lignes f = open(nom_fichier, encoding="UTF-8") # on ouvre le fichier ligne = f.readline() # une variable temporaire pour récupérer la ligne courante dans le fichier f while ligne != "": liste_mots.append(ligne.strip()) # on rajoute la ligne courante dans le tableau ligne = f.readline() # on récupère la ligne suivante return liste_mots
Utilisez la fonction "lire_mots
" (sans la modifier) pour trouver le nombre de mots dans le fichiers littre.txt.
Ajoutez un commentaire dans votre fichier Python en indiquant le nombre de mots trouvés.
Pendant une partie, nous représenterons l'état connu du joueur par une chaine de caractères. Sa taille sera le nombre de lettres du mot à trouver et les lettres inconnues seront remplacées par le caractère "_
".
Remarque : pour éviter de tester les minuscules / majuscules, vous pouvez convertir un caractère (ou une chaine de caractères) en majuscules avec
c = c.upper()
Écrivez la fonction nouvel_etat
:
def nouvel_etat(mot, etat, c): """fonction qui renvoie le nouvel état après proposition d'une lettre c paramètres : - mot, de type chaine de caractères, - etat, de type chaine de caractères : les lettres inconnues sont représentées par des '_'. Cette chaine a la même longueur que le paramètre mot, - c, de type caractère : la lettre proposée. retour : chaine de caractère où les "_" correspondant au paramètre c ont été remplacés par c """ ...
Pour cela, le plus simple est de parcourir les caractères de la chaine mot
, en reconstruisant l'état au fur et à mesure :
c
passé en argument, on garde le caractère de etat
et on continue
c
passé en argument, on colle un c
dans le nouvel état.
Attention, comme le mot peut contenir plusieurs fois la même lettre, il ne faut pas s'arrêter à la première occurrence de c
trouvée !
L'exécution suivante :
def test3(): mot = "CANARI" # mot secret etat = "C___RI" # état : le joueur a déjà trouvé les lettres "C", "R" et "I" etat2 = nouvel_etat(mot, etat, "a") # mise à jours de l'état avec une nouvelle lettre print("mot :", etat2) # affichage du nouvel etat
devra afficher
>>> test3() mot : CA_ARI
On peut maintenant écrire une première version du jeu du pendu :
littre.txt
,
etat
" avec autant de "_
" que de lettres dans le mot tiré,
nouvel_etat
permet de comparer l'ancien état et le nouveau :
etat
à jour en lui affectant le nouvel état.
Pour tirer un mot au hasard, il suffit de récupérer la liste de tous les mots et de tirer un numéro de case au hasard avec la fonction randint
. N'oubliez pas de faire un
from random import randint
Voici un exemple de partie :
>>> pendu_version1(8) _ _ _ _ _ _ _ _ Vous pouvez faire encore 8 erreurs. Entrez une lettre, suivie d'un saut de ligne : e Dommage... _ _ _ _ _ _ _ _ Vous pouvez faire encore 7 erreurs. Entrez une lettre, suivie d'un saut de ligne : a Bravo ! _ A _ _ A _ _ _ Vous pouvez faire encore 7 erreurs. Entrez une lettre, suivie d'un saut de ligne : l Dommage... _ A _ _ A _ _ _ Vous pouvez faire encore 6 erreurs. Entrez une lettre, suivie d'un saut de ligne : ... ... Perdu... Le mot secret était 'RAMPANT'.
Dans l'exemple, l'état est affiché avec des espaces :
_ A _ _ A _ _ _ Vous pouvez faire encore 7 erreurs.
au lieu de :
_A__A___ Vous pouvez faire encore 7 erreurs.
Si vous souhaitez faire de même, il faudra écrire une procédure supplémentaire affiche_etat
pour afficher l'état correctement...
Ce n'est pas obligatoire.
Écrivez la procédure pendu_version1
. Cette procédure prend en argument le nombre maximal d'erreurs autorisées.
Note : il faudra bien entendu faire une boucle while
et utiliser :
print
pour faire les affichages
input
pour récupérer la lettre proposée par le joueur :
... c = input() ...
La partie précédente ne prenait pas les accents en compte : si la lettre proposée est "e
", il faut en fait vérifier si le mot contient des "é
", "è
", "ê
" ou "ë
". Par ailleurs, le français contient deux lettre doubles : le "æ
" et le "œ
. Lorsque la lettre proposée est "e
", il faut donc aussi vérifier si le mot contient des "æ" ou "œ".
Pour gérer cela, nous allons utiliser un dictionnaire qui associe aux caractères ASCII les caractères accentués correspondants.
variantes = { 'A': 'AÀÄÂÆ', 'C': 'CÇ', 'E': 'EÊÈÉËÆŒ', 'I': 'IÎÏ', 'O': 'OÔÖŒ', 'U': 'UÙÜÛ' }
Notez en particulier que les lettres doubles ont deux lettres correspondantes.
N'oubliez pas qu'il est possible de tester si un caractère apparait dans une chaine avec le mot clé in
:
>>> "c" in "coco" True >>> "t" in "coco" False >>> "O" in "coco" False
Écrivez une fonction nouvel_etat_version2
qui prend les accents et lettres doubles en compte.
Pour cela, il suffit de modifier la fonction nouvel_etat
en modifiant le test qui vérifie si le ième caractère de mot
est égal à c
en un test qui vérifie si le ième caractère du mot apparait dans la chaine contenant toutes les variantes du c
.
Attention : certains caractères n'ont aucune variante et n'apparaissent donc pas dans le dictionnaire variantes
. Il faudra utiliser la méthode variantes.get(...)
pour gérer ces cas.
L'exécution de :
def test5(): mot = "DÉSŒUVRER" etat = "D____VR_R" etat2 = nouvel_etat_version2(mot, etat, "e") print("mot :", etat2)
devra afficher :
>>> test5() mot : DÉ_Œ_VRER
Programmez maintenant la procédure pendu_version2
similaire à pendu_version1
, mais qui prend les accents et lettres doubles en compte.
Votre procédure pendu_version2
est identique à votre procédure pendu_version1
, sauf qu'elle utilise nouvel_etat_version2
...
Nous allons améliorer la version précédente du jeu en ajoutant :
>>> pendu_version3("littre.txt") _ _ _ _ _ _ _ _ Vous pouvez faire encore 8 erreurs. Il y a encore 11595 mots possibles... Entrez une lettre, suivie d'un saut de ligne : e Bravo ! É _ _ _ _ _ _ E Vous pouvez faire encore 8 erreurs. Il y a encore 196 mots possibles... Entrez une lettre, suivie d'un saut de ligne : a Bravo ! É _ _ _ _ A _ E Vous pouvez faire encore 8 erreurs. Il y a encore 46 mots possibles... Entrez une lettre, suivie d'un saut de ligne : l Dommage... É _ _ _ _ A _ E Vous pouvez faire encore 7 erreurs. Il y a encore 46 mots possibles... Entrez une lettre, suivie d'un saut de ligne : p Bravo ! É _ _ _ P A _ E Vous pouvez faire encore 7 erreurs. Il y a encore 5 mots possibles... Entrez une lettre, suivie d'un saut de ligne : e Vous avez déjà proposé cette lettre... É _ _ _ P A _ E Vous pouvez faire encore 7 erreurs. Il y a encore 5 mots possibles... Entrez une lettre, suivie d'un saut de ligne : e Vous avez déjà proposé cette lettre... ... Perdu... Le mot secret était 'ÉTOUPAGE'.
Commencez par écrire la fonction :
def mots_longueur(liste_mots, n): """fonction qui renvoie la liste des chaines d'une longueur donnée dans une liste paramètres : - liste_mots, de type liste de chaines de caractères - n, de type entier retour : liste de chaines de caractères: tous les éléments de mots qui ont la longueur n """
Cette fonction vous permettra de savoir combien de mots sont possible au début d'une partie de pendu : il suffit de garder les mots de même taille que le mot secret.
Écrivez la procédure pendu_version3
et testez-la. N'oubliez pas de :
Note : pour pouvoir compter le nombre de mots restants qui sont compatibles avec les lettres devinées, il est conseillé d'écrire des fonctions auxiliaires :
def mots_sans_lettre(liste_mots, c): """fonction qui renvoie la liste des éléments d'une liste qui ne contiennent pas un caractère donné paramètres : - liste_mots, de type liste de chaines de caractères - c, de type caractère retour : liste de chaine de caractères """ ... def mots_avec_lettre(liste_mots, c): """fonction qui renvoie la liste des éléments d'une liste qui contiennent un caractère donné paramètres : - liste_mots, de type liste de chaines de caractères - c, de type caractère retour : liste de chaine de caractères """ ...
Ces fonctions vous permettront de mettre à jour la liste des mots possibles suivant que la lettre proposée était présente ou pas dans le mot secret.
Pour être plus précis, il ne faudrait garder que les mots qui sont compatible avec les lettres proposées aux positions correctes.
Par exemple, si :
"CANARI"
,
"CA_A__"
,
"N"
,
alors il faut :
"CANA__"
,
"N"
en 2ème position
"N"
en positions 4 et 5.
Vous pouvez faire ceci, mais ce n'est pas obligatoire...
Il serait possible de faire une version graphique du jeu du pendu afin de pouvoir réellement dessiner le pendu. Pour faire simple, nous allons faire une version en "ASCII art". Voici un exemple de partie possible :
-------------- | | | | | | | | /|\ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ _ _ _ _ _ _ _ Vous pouvez faire encore 7 erreurs. Il y a encore 10232 mots possibles... Entrez une lettre, suivie d'un saut de ligne : a Dommage... -------------- | | | | | | | | | | /|\ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ _ _ _ _ _ _ _ Vous pouvez faire encore 6 erreurs. Il y a encore 5037 mots possibles... Entrez une lettre, suivie d'un saut de ligne : e Bravo ! -------------- | | | | | | | | | | /|\ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ _ _ _ _ É _ É Vous pouvez faire encore 6 erreurs. Il y a encore 28 mots possibles... Entrez une lettre, suivie d'un saut de ligne : l Dommage... -------------- | | | | | / \ | \_/ | | | | /|\ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ _ _ _ _ É _ É Vous pouvez faire encore 5 erreurs. Il y a encore 26 mots possibles... Entrez une lettre, suivie d'un saut de ligne : t Dommage... -------------- | | | | | / \ | \_/ | | | | | | | /|\ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ _ _ _ _ É _ É Vous pouvez faire encore 4 erreurs. Il y a encore 17 mots possibles... Entrez une lettre, suivie d'un saut de ligne : p Dommage... -------------- | | | | | / \ | \_/ | |__ | | | | | /|\ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ _ _ _ _ É _ É Vous pouvez faire encore 3 erreurs. Il y a encore 9 mots possibles... ... ...
Pour pouvoir afficher le pendu, nous allons utiliser une fonction auxiliaire :
def affiche_pendu(n): """procédure qui affiche le pendu en fonction du nombre d'erreurs paramètre : - n, de type entier """
Une manière de faire est d'utiliser les deux chaines de caractères : (notez le r
précédent les trois guillemets : il permet de ne pas avoir besoin d'échapper les caractères \
présents dans les chaines)
pendu_final = r""" -------------- | | | | | / \ | \_/ | __|__ | | | | | / \ /|\ / \ / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ """ pendu_numero = r""" -------------- | 1 | 1 | 2 2 | 222 | 55344 | 3 | 3 | 6 7 /|\ 6 7 / | \ / | \ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ """
La première contient les caractères qu'il faut afficher. La seconde (de même taille) indique quels caractères doivent être affichés pour un nombre d'erreurs données :
2
, 3
, 4
, 5
, 6
ou 7
;
6
ou 7
;
Écrivez la procédure affiche_pendu
ainsi que la procédure pendu_version4(dictionnaire)
correspondante. (Le nombre d'erreurs autorisées est forcément 7.)
Lorsqu'on dessine le pendu, le nombre d'erreurs maximal est forcément 7. On peut modifier ceci en commençant à dessiner la potence.
Écrivez un procédure affiche_pendu
qui permet de commencer à afficher la potence.
Écrivez une procédure pendu_version5(dictionnaire, nb_erreurs)
correspondante qui permet de choisir un nombre d'erreurs maximal compris entre 7 (on ne dessine que le pendu) et 11 (on dessine les différents morceaux de la potence).