2015-08-26 4 views
3

Je crée une implémentation simple de Pendu pour un projet d'école et je suis actuellement coincé sur la tâche de faire apparaître une lettre dans le mot quand on le devine correctement. J'ai déjà un code qui génère des espaces vides en fonction du nombre de lettres dans le mot, ainsi que de presque tous les autres éléments du jeu dont j'ai besoin, mais je n'arrive pas à comprendre comment remplacer les espaces par des lettres correctes.Jeu Pendu en Python: comment remplacer les blancs par des lettres devinées

Je vous serais reconnaissant si vous gardiez les choses simples et expliquées car je suis encore relativement nouveau en programmation. Et si possible, pour ne pas avoir trop à changer de code.

Voici mon code:

import random 

name = str(input("What's your name?")) 
print("Hello,", name + "!") 
failures = 0 
allowed = 1 
guessed = str() 
wordlist = ['hangman', 'dinner', 'computer', 'america', 'olympics', 'football', 'minecraft', 'jacket', 'cabbage', 'electricity', 'dog', 
      'pasta', 'japan', 'water', 'programming', 'anaconda', 'onehunga', 'name', 'windows', 'curtains', 'bieber', 'kirito', 
      'montenegro', 'wheel', 'civilization', 'physics', 'bluebird' 'table', 'ACDC', 'guardian yam' 'mario', 'parachute', 'agario', 'obama', 
      'youtube', 'putin', 'dairy', 'christianity', 'club penguin', 'oskahlavistah', 'coins', 'agitating', 'jumping', 'eating', 
      'your mom', 'executive', 'car', 'jade', 'abraham', 'sand', 'silver', 'uranium', 'oscar is gay', 'bioshock', 'fizzle', 'moonman', 'watermelon', 
      'WAHAHAHAHAHA', 'steve jobs', 'extreme', 'weeaboo jones', 'hot damn', name] 

def correct(guess): 
    if guess in word: 
     if guess not in guessed: 
      print("Correct") 
      return(True) 
    else: 
     if guess not in word and len(guess) == 1 and guess in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ': 
      if guess not in guessed: 
       print("Incorrect!") 
       return(False) 

print("Guess this word!") 
print("You can input any letter from A to Z and the space key.") 
wordnumber = random.randint(0, len(wordlist)) 
word = (wordlist[wordnumber]) 
print("_ "*len(word)) 
while failures < allowed: 
    guess = str(input("Guess a letter!")) 
    if len(guess) != 1 or guess not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ': 
     print("That is not a letter, try again.") 
    if guess in guessed: 
     print("You have already guessed that letter, try again.") 
    iscorrect = correct(guess) 
    guessed = guessed, guess 
    if iscorrect == True: 
     print("Word display still in development") 
    if iscorrect == False: 
     print("You suck") 
     failures = failures+1 
     print("You have", allowed , "guesses left.") 
    if failures == allowed: 
     replay = str(input("Press 1 to play again, press 2 to exit.")) 
     if replay == 1: 
      break 
     else: 
      quit() 

#Now all I have to do is find a way to display positions of correct letters. 
+0

Il serait plus facile si vous pouvez donner juste ce 'string' que vous avez, ce que vous voulez remplacer, ce qui serait d sortie au lieu de l'ensemble du programme – vks

+0

Le raison que j'ai donné mon code entier est que nous puissions trouver une réponse qui ne secoue pas le code. Quoi qu'il en soit, la chaîne que j'ai est wordnumber = random.randint (0, len (wordlist)) word = (liste de mots [nombre de mots]) print ("_" * len (mot)) – ahjfcshfghb

+0

Si je savais comment formater ça ce serait génial xD – ahjfcshfghb

Répondre

0

Pour trouver où la lettre dans la chaîne, l'utilisation word.index (estimation). Ensuite, remplacez la lettre dans le mot "vides". Pour ce faire sauver b_word = "_ "*len(word), et remplacer « _ » au bon endroit:

s = list(b_word) 
s[word.index(guess)] = guess 

Après que la nouvelle b_word imprimer.

+0

Merci, même si cela m'a donné une erreur quand j'ai mis le b_word [word.index (guess)] = deviner. Apparemment, l'objet '' str '' ne supporte pas l'assignation d'objets. – ahjfcshfghb

+0

Désolé, ma faute. J'ai modifié la réponse, essayez de convertir la chaîne en liste. – nevsv

+0

D'accord, cela ne donne pas d'erreur, mais il imprime toujours le mot vide entier quand je devine une réponse correcte. – ahjfcshfghb

0

Pour vous aider à afficher les lettres devinées, vous pouvez les suivre dans une liste dans laquelle les lettres qui n'ont pas encore été devinées sont représentées par des traits de soulignement (ou des espaces ou ce que vous voulez).

Vous pouvez initialiser une telle liste dès que vous avez décidé sur le word secret:

guessed_letters = len(word) * ['_'] 

Pour afficher les lettres devinées, les rejoindre avec des espaces:

print(' '.join(guessed_letters)) 

Par la suite, lorsque le l'utilisateur entre une lettre guess, vous pouvez mettre à jour les lettres correctement devinées en énumérant sur le mot:

for position, letter in enumerate(word): 
    if letter == guess: 
     guessed_letters[position] = letter 

J'ai revu votre programme pour intégrer ce code:

import random 

name = str(input("What's your name?")) 
print("Hello,", name + "!") 
failures = 0 
allowed = 1 
guessed = str() 
wordlist = ['hangman', 'dinner', 'computer', 'america', 'olympics', 'football', 'minecraft', 'jacket', 'cabbage', 'electricity', 'dog', 
      'pasta', 'japan', 'water', 'programming', 'anaconda', 'onehunga', 'name', 'windows', 'curtains', 'bieber', 'kirito', 
      'montenegro', 'wheel', 'civilization', 'physics', 'bluebird' 'table', 'ACDC', 'guardian yam' 'mario', 'parachute', 'agario', 'obama', 
      'youtube', 'putin', 'dairy', 'christianity', 'club penguin', 'oskahlavistah', 'coins', 'agitating', 'jumping', 'eating', 
      'your mom', 'executive', 'car', 'jade', 'abraham', 'sand', 'silver', 'uranium', 'oscar is gay', 'bioshock', 'fizzle', 'moonman', 'watermelon', 
      'WAHAHAHAHAHA', 'steve jobs', 'extreme', 'weeaboo jones', 'hot damn', name] 

def correct(guess): 
    if guess in word: 
     if guess not in guessed: 
      print("Correct") 
      return(True) 
    else: 
     if guess not in word and len(guess) == 1 and guess in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ': 
      if guess not in guessed: 
       print("Incorrect!") 
       return(False) 

print("Guess this word!") 
print("You can input any letter from A to Z and the space key.") 
wordnumber = random.randint(0, len(wordlist)) 
word = (wordlist[wordnumber]) 
guessed_letters = len(word) * ['_'] 
print(' '.join(guessed_letters)) 
while failures < allowed: 
    guess = str(input("Guess a letter!")) 
    if len(guess) != 1 or guess not in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ': 
     print("That is not a letter, try again.") 
    if guess in guessed: 
     print("You have already guessed that letter, try again.") 
    iscorrect = correct(guess) 
    guessed = guessed, guess 
    if iscorrect == True: 
     for position, letter in enumerate(word): 
      if letter == guess: 
      guessed_letters[position] = letter 
     print(' '.join(guessed_letters)) 
    if iscorrect == False: 
     print("You suck") 
     failures = failures+1 
     print("You have", allowed , "guesses left.") 
    if failures == allowed: 
     replay = str(input("Press 1 to play again, press 2 to exit.")) 
     if replay == 1: 
      break 
     else: 
      quit() 

Il y a d'autres problèmes avec le programme qui ne relèvent pas du champ d'application de cette question.

+0

Je suppose que vous parlez des échecs == permis et de la chaîne devinée, et j'ai l'intention de les corriger plus tard. Mais ça a bien fonctionné, merci! – ahjfcshfghb

+0

Question: Comment fonctionne exactement la fonction d'énumération? Comme quoi est «pour position» et ainsi de suite? Désolé, je suis un noob complet – ahjfcshfghb

+0

Vous savez comment 'range' fonctionne, non? Il vous permet de parcourir les valeurs. Eh bien, «énumérer» fait la même chose, sauf qu'il compte aussi les valeurs à partir de zéro.Au lieu de 'pour position, lettre dans enumerate (mot)' vous pouvez écrire 'for (position, lettre) dans enumerate (mot)' pour indiquer clairement qu'on vous donne deux choses à chaque itération: une position basée sur zéro dans le mot et la lettre à cette position. –

0
import sys 
import random 
wordlist = ['hangman', 'dinner', 'computer', 'america', 'olympics', 'football', 'minecraft', 'jacket', 'cabbage', 'electricity', 'dog', 
      'pasta', 'japan', 'water', 'programming', 'anaconda', 'onehunga', 'name', 'windows', 'curtains', 'bieber', 'kirito', 
      'montenegro', 'wheel', 'civilization', 'physics', 'bluebird' 'table', 'ACDC', 'guardian yam', 'mario', 'parachute', 'agario', 'obama', 
      'youtube', 'putin', 'dairy', 'christianity', 'club penguin', 'oskahlavistah', 'coins', 'agitating', 'jumping', 'eating', 
      'your mom', 'executive', 'car', 'jade', 'abraham', 'sand', 'silver', 'uranium', 'oscar is gay', 'bioshock', 'fizzle', 'moonman', 'watermelon', 
      'WAHAHAHAHAHA', 'steve jobs', 'extreme', 'weeaboo jones', 'hot damn'] 

class Guess: 

    def __init__(self): 

     self.SECRET = random.choice(wordlist) 
     self.GUESSES_ALLOWED = int(raw_input("The secret's word has %s letter, you how many times can you be mistaken?" % len(self.SECRET))) 
     self.WRONG = [] 
     self.GUESSED = [] 

    def make_a_guess(self): 

     while self.GUESSES_ALLOWED: 
      current_guess = raw_input('Guess a letter!') # TODO: to check for double chars 
      self.print_mask() 

      if current_guess in self.GUESSED: 
       print "You;ve already guessed that! Try again!\n" 
       self.make_a_guess() 
       self.print_mask() 
      elif current_guess in self.WRONG: 
       print "You;ve already guessed that! Try again!\n" 
       self.make_a_guess() 
       self.print_mask() 
      elif current_guess not in self.SECRET: 
       self.GUESSES_ALLOWED -= 1 
       print "WRONG! Guesses left: %s\n" % self.GUESSES_ALLOWED 
       self.WRONG.append(current_guess) 
       self.print_mask() 
      elif current_guess in self.SECRET: 
       print "CORRECT! Guesses left: %s\n" % self.GUESSES_ALLOWED 
       self.GUESSED.append(current_guess) 
       self.print_mask() 
       if set(self.GUESSED) == set(self.SECRET): 
        print "You guessed the word!" 
        repeat = raw_input("Play again? type y or n and press Enter") 
        if 'y' in repeat: 
         a = Guess() 
         a.make_a_guess() 
        elif 'n' in repeat: 
         sys.exit(0) 
     else: 
      print "You got '%s' guesses left, you lost!" % self.GUESSES_ALLOWED 
      repeat = raw_input("Play again? type y or n and press Enter") 
      if 'y' in repeat: 
       a = Guess() 
       a.make_a_guess() 
      elif 'n' in repeat: 
       sys.exit(0) 


    def print_mask(self): 

     guessed_indexes = [] 
     for letter in self.GUESSED: 
      indexes_for_one_letter = [i for i, x in enumerate(self.SECRET) if x == letter] 
      guessed_indexes += indexes_for_one_letter 

     MASK_TO_PRINT = [] 
     for i, letter in enumerate(self.SECRET): 
      if i in guessed_indexes: 
       MASK_TO_PRINT.append(letter) 
      else: 
       MASK_TO_PRINT.append("_") 

     print " ".join(MASK_TO_PRINT) 


if __name__ == '__main__': 

    game = Guess() 
    game.make_a_guess() 

Tout d'abord, nous importons sys ne nous pourrions quitter si le joueur ne veut pas jouer plus

est mis en œuvre toute la logique dans la méthode de make_a_guess Devinez de classe. chaque fois qu'un nouveau jeu sera lancé, une nouvelle instance de la classe Guess sera créée.

Ceci est une nouvelle implémentation, car votre variante avait des erreurs vraiment importantes, par exemple, vous devriez utiliser raw_input() pour autoconvertir l'entrée en string. Pour vous écrire des progrès de deviner, print_mask() dans mon code est utilisé dans la méthode que vous devriez rechercher toutes les occurrences de lettres déjà devinées et les rassembler. Par exemple, vous avez deviné M et F et leurs index seront [0,3] si le mot 'FORM' est un mot secret.C'est pourquoi lorsque vous itérez une boucle sur le mot secret, si vous rencontrez cet index courant, vous pouvez aussi itérer sur [0,3], -> lorsque vous ajoutez la lettre de l'index correspondant liste vous préparer pour l'impression ultérieure comme un affichage de la progression en cours. Si aucun index actuel ne peut être trouvé dans [0,3] pendant l'itération sur les lettres de mots du secret - alors vous ajoutez "_" au lieu de la lettre qui vous a été devinée.

Ensuite, vous réduisez la liste pour être sous forme de chaîne afin de poursuivre l'imprimer: « » .join (MASK_TO_PRINT)

Logic est comme ça: mot secret est « cabage » vous l'aurez deviné « c » avant et « a » si self.GUESSED contient [0,1,3] vous itérer sur:

prepared_list_for_print = [] 
for i, letter in enumerate('cabage'): 
    if i in [0,1,3]: 
     prepared_list_for_print.append(letter) 
    else: 
     prepared_list_for_print.append("_") 
+0

Merci de mettre tant d'efforts dans la création de cette réponse, mais j'ai quelques commentaires ... Vous n ' t _need_ à importer sys; il y a une fonction 'exit()' intégrée. L'OP utilise (probablement) Python 3, donc il n'a pas d'instruction 'print' pour utiliser la fonction' print() '. Et ils n'ont pas 'raw_input()': dans Python 3 cette fonction a été renommée en 'input()' et l'ancienne fonction dangereuse Python 2 'input()' a été éliminée. Je ne sais pas pourquoi vous avez utilisé un 'class' - ce n'est pas nécessaire pour cette tâche (et Python n'est pas Java) et il pourrait être un peu trop avancé pour l'OP. –

+0

Je crois qu'il n'est jamais tôt pour commencer à utiliser des classes tout de suite, même si Python n'est pas Java et que les scripts peuvent être très bien sans aucune classe. La classe est juste un bon moyen d'organiser les champs requis initiaux et est idéal pour l'héritage et d'autres bonnes choses. Merci pour la note que c'est Python3, je me suis demandé pourquoi cette entrée demandait des guillemets pour passer une chaîne à une variable – user3625397

0

Vos instructions au joueur sont un peu trompeur: vous dites au joueur qu'ils peuvent « entrée une lettre de A à Z et la touche d'espace ", mais vous ne Ils peuvent également utiliser les lettres minuscules de a à z, ce qui est important car votre programme fait la distinction entre les minuscules &.

Diverses choses pourraient être faites à votre code pour l'améliorer. Par exemple, vous n'avez pas besoin de convertir les données renvoyées par input() en une chaîne - c'est déjà une chaîne. Vous pouvez simplifier la logique en testant si une supposition est valide: vous effectuez deux de vos tests deux fois sur les mêmes données d'entrée. De plus, votre logique de replay nécessite un peu de travail. Et il n'y a pas de fonction intégrée nommée quit() (et vous n'en avez pas défini une); peut-être que vous vouliez dire exit(), mais vous pouvez probablement réorganiser votre logique de sorte que vous n'avez pas besoin d'utiliser exit().

De toute façon, voici un moyen d'implémenter une fonction d'affichage de mots du pendu. Cette fonction reçoit la chaîne word et guessed, qui peut être une chaîne ou une liste, mais il serait plus efficace d'utiliser un set.

def display(word, guessed): 
    word = ' '.join([ch if ch in guessed else '_' for ch in word]) 
    print(word) 


display('computer', set('stop')) 
display('cabbage', list('bag')) 
display('banana', 'abcn')    

sortie

_ o _ p _ t _ _ 
_ a b b a g _ 
b a n a n a