Pendu en python
FerméPhil_1857 Messages postés 1872 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 - 6 juil. 2023 à 16:46
- Pendu en python
- Jeu du pendu - Télécharger - Vie quotidienne
- Citizen code python avis - Accueil - Outils
- Trouver la position d'un élément dans une liste python ✓ - Forum Python
- Python generator - Télécharger - Sécurité
8 réponses
30 juin 2023 à 13:37
Bonjour
- tu peux faire une boucle qui va regarder chaque lettre du mot
- tu peux faire une boucle qui travaille sur la copie du mot, tu y mets tes lignes 7 à 12, puis dans la copie tu places ce qui reste du mot après l'index de la première occurrence
- tu peux utiliser les regex
Modifié le 30 juin 2023 à 13:56
Bonjour,
Moi, j'avais fait un truc du même genre avec enumerate:
display = ['_' for k in range(len(mot))] while(not end): print(display) m= input('\nUne lettre : ') found = False if(m in mot): found = True inds = [ind for ind, value in enumerate(mot) if value == m] for ind in inds: #if m in mot ne suffit pas: il faut traiter les occurences multiples comme 2 e dans lycee if(display[ind] == '_'): display[ind] = m break if(not found): print("La lettre " + m + " n'est pas dans le mot.")
Ce n'est pas une bonne idée d'assigner la valeur et la position d'une lettre à la même variable.
D'accord avec phil pour enumerate.
Ce n'est pas grave ici, mais un jeu récursif n'est pas conseillé. On pourrait déborder la pile.
Modifié le 30 juin 2023 à 18:21
Alors oui la méthode de Phil est très belle.
Mais, s'agissant d'un exercice plutôt simple, sur lequel Acnologiaf peine un peu, je pense que c'est encore hors de sa portée.
Si j'étais prof et que l'on me ramène une solution que l'élève n'aurais pas pu faire lui-même, je lui mettrais une mauvaise note.
Concernant le côté récursif, avec en principe 26 récursions maximum (sauf si le joueur propose 2 fois la même lettre), il ne devrait pas y avoir de dépassement de pile.
Par contre, il va falloir veiller à sortir du mode récursif quand le mot est trouvé, et donc faire en sorte que le jeu sache que c'est gagné.
Ce qui n'est pas le cas pour le moment
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionModifié le 1 juil. 2023 à 10:46
Bonjour,
Oui, c'est vrai que c'est peut-être hors de sa portée
Pour ce qui est de sortir de la boucle, je faisais ceci:
if(mot == ''.join(display)): print('\nGagné en {} essais!'.format(nb_essais)) end = True
Idem si le nb d'essais atteignait le nb maxi permis ( if(not found): ..... )
1 juil. 2023 à 19:02
C'est au message de PierrotLeFou que je réagissais.
D'abord.
Ce n'est pas une bonne idée d'assigner la valeur et la position d'une lettre à la même variable.
C'est très juste donc je n'ai rien à redire.
Puis
D'accord avec phil pour enumerate
Sauf que ça n'est pas de son niveau, et là j'explique pourquoi, j'essaye de ne pas donner ce genre de réponse.
Et enfin
Ce n'est pas grave ici, mais un jeu récursif n'est pas conseillé. On pourrait déborder la pile.
Je n'avais même pas fait attention au fait que la fonction était récursive, là bien vu (si je peux dire).
Mais contrairement à ce qu'il dit, c'est grave puisque le programme de Acnologiaf n'en sort jamais.
Modifié le 6 juil. 2023 à 15:50
Bonjour,
Tout d'abord j'aimerais signaler que le pendu est un exercice qu'on voit régulièrement sur le forum donc une petite recherche préalable est toujours une bonne chose.
Préliminaires
Comme python est sensible à la casse (minuscule / majuscule), il est recommandé d'adopter une convention (par exemple ne travailler qu'avec des minuscules ou des majuscules). Dans ce qui suit je suppose qu'on a choisi de travailler avec des minuscules. Une fois cette convention choisie, on peut de manière systématiquement convertir les lettres proposées en minuscules, ce qui évite d'imposer cette contrainte au joueur.
Pour faire cette conversion, on peut utiliser la méthode lower (pour les minuscules) ou upper (pour les majuscules) :
mot = "SeCreT" print(mot.lower()) # Affiche secret print(mot.upper()) # Affiche SECRET
Retour à la question initiale
Je suppose ici que mot et propositions suivent la même convention (que des minuscules ou que des majuscules).
La manière la plus simple est de mémoriser les lettres proposées (variable propositions), puis au moment d'écrire un mot (variable mot), d'itérer sur chaque lettre de mot. Si la lettre courante a été proposée, on l'affiche, sinon on écrit _.
def offusquer_mot(mot: str, propositions: set) -> str: s = "" for a in mot: if a in propositions: s += a else: s += "_" return s
... qu'on écrirait plutôt ainsi si on connaît bien python :
def offusquer_mot(mot: str, propositions: set) -> str: return "".join(a if a in propositions else "_" for a in mot)
Qu'est ce qu'un set ?
Le type set correspond à un ensemble d'éléments distincts.
Dans la fonction précédente, on pourrait parfaitement ce contenter d'une liste (type list), cela n'empêche pas d'utiliser l'opérateur d'appartenance (in). Cependant, un set est plus efficace et plus pratique. En effet, on peut facilement vérifier si l'ensemble des proposition inclue toutes les lettres impliquées dans le mot à découvrir, ce que ne permettra pas une liste.
def tester_victoire(mot: str, propositions: set) -> bool: return set(mot) <= propositions
Si on rassemble tous ces éléments, voici à quoi peut ressembler le jeu :
def offusquer_mot(mot: str, propositions: set) -> str: s = "" for a in mot: if a in propositions: s += a else: s += "_" return s def offusquer_mot(mot: str, propositions: set) -> str: return "".join(a if a in propositions else "_" for a in mot) def tester_victoire(mot: str, propositions: set) -> bool: return set(mot) <= propositions def saisir_lettre(message) -> str: while True: proposition = input(message) if len(proposition) != 1: print("Vous ne devez saisir qu'un caractère") elif not ('a' <= proposition.lower() <= 'z'): print(f"'{proposition}' n'est pas une lettre") else: break return proposition def jeu(mot: str, nombre_tours: int = 10) -> bool: propositions = set() mot = mot.lower() for tour in range(1, nombre_tours + 1): proposition = saisir_lettre( f"[{tour}/{nombre_tours}] Saisir une lettre minuscule ? " ) propositions.add(proposition.lower()) print(offusquer_mot(mot, propositions)) if tester_victoire(mot, propositions): print(f"Victoire, le mot était \"{mot}\"") return True print(f"Défaite, le mot était \"{mot}\"") return False jeu("test")
Bonne chance
6 juil. 2023 à 16:46
Bonjour,
Une version en mode console mais avec un petit graphique:
import os import random import colorama colorama.init() POS = lambda x,y: '\033[{};{}H'.format(x,y) #"escape sequence" pour placer le curseur sur ligne/colonne données failures_nb, tries_nb = 0, 0 end, found = False, True display = [] sketch = {0:[5,50,'_'], 1:[5,52,'_'], 2:[5,51,'|'], 3:[4,51,'|'], 4:[3,51,'|'], 5:[2,51,'_'], 6:[2,52,'_'], 7:[2,53,'_'], 8:[3,52,'/'], 9:[3,54,'|'], 10:[4,54,'o']} words = ['voiture','ordinateur','poker','stylo','lycee','trousse','spatule', 'souris', 'menthe','seisme'] print('\n***** Jeu du pendu *****\n') word = random.choice(words) input('''Choix d'un mot au hasard ... appuyer sur Entrée pour continuer''') display = ['_' for k in range(len(word))] os.system('cls') print('\n***** Jeu du pendu *****') while(not end): print('{}{}'.format(POS(3,1),' '.join(display))) letter = input('\nUne lettre : ') tries_nb += 1 found = False if(letter in word): found = True inds = [ind for ind, value in enumerate(word) if value == letter] for ind in inds: #if letter in word ne suffit pas: il faut traiter les occurences multiples comme 2 e dans lycee if(display[ind] == '_'): display[ind] = letter break if(not found): failures_nb +=1 #lettre pas dans le mot: on commence a dessiner le pendu ... for i in range(failures_nb): print(POS(sketch[i][0],sketch[i][1])+sketch[i][2]) if(failures_nb == len(sketch)): print('''{}Perdu ! C'était {}'''.format(POS(5,1),word)) end = True if(word == ''.join(display)): print('{}{}\n\nGagné en {} essais!'.format(POS(3,1),' '.join(display),tries_nb)) end = True