【问题标题】:Hangman game in Python: how to replace blanks with guessed lettersPython中的刽子手游戏:如何用猜测的字母替换空格
【发布时间】:2015-11-20 05:18:55
【问题描述】:

我正在为一个学校项目创建一个简单的 Hangman 实现,我目前的任务是让一个字母在正确猜测的情况下显示在单词中。我已经有代码可以根据单词中的字母数量以及我需要的游戏的几乎所有其他组件生成空格,但我不知道如何用正确的字母替换空格。

如果你能保持简单和解释,我将不胜感激,因为我在编程方面还是新手。如果可能的话,这样我就不必过多地更改我的代码了。

这是我的代码:

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.

【问题讨论】:

  • 如果你能给出你所拥有的string,你想替换什么,输出什么而不是整个程序会更容易
  • 我给出整个代码的原因是我们可以找出一个不会影响代码的答案。无论如何,我拥有的字符串是 wordnumber = random.randint(0, len(wordlist)) word = (wordlist[wordnumber]) print("_ "*len(word))
  • 如果我知道如何格式化那将是很棒的 xD
  • 欢迎新用户!如果您对我的回答感到满意,请接受并点赞。

标签: python string algorithm


【解决方案1】:

您对玩家的指示有点误导:您告诉玩家他们可以“输入从 A 到 Z 的任何字母和空格键”,但您没有提到他们也可以使用小写字母a 到 z,这很重要,因为您的程序区分大小写字母。

可以对您的代码做各种事情来改进它。例如,您不需要将input() 返回的数据转换为字符串——它已经是字符串了。您可以简化测试猜测是否有效的逻辑:您对相同的输入数据执行两次测试。此外,您的重播逻辑需要一些工作。并且没有名为quit() 的内置函数(你还没有定义一个);也许你的意思是exit(),但你可以重新组织你的逻辑,这样你就不需要使用exit()

不管怎样,这里有一个实现Hangman单词显示功能的方法。此函数接收word 字符串和guessed,可以是字符串或列表,但使用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')            

输出

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

【讨论】:

    【解决方案2】:
    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()
    

    首先, 如果玩家不想再玩,我们导入 sys 是否可以退出

    整个逻辑在 Guess 类的 make_a_guess 方法中实现。 每次新游戏开始时,都会创建 Guess 类的新实例。

    这是一个新的实现,因为您的变体有一些非常重要的错误,例如,您最好使用 raw_input() 以便将输入自动转换为字符串。

    为了写你猜的进度,我的代码中使用了 print_mask() 在该方法中,您应该查找所有已经猜到的字母并收集它们。例如,如果 'FORM' 词是秘密词,您猜到 M 和 F 并且它们的索引将是 [0,3]。这就是为什么当你在一个循环中迭代秘密词时,如果你遇到你迭代的当前索引也可以在 [0,3] 中找到,-> 即当你将相应索引的字母添加到某个空时您准备稍后打印的列表作为当前进度的显示。如果在对秘密的单词字母进行迭代期间在 [0,3] 中找不到当前索引 - 那么您添加“_”而不是猜测到您准备的空列表的字母。

    然后您将列表缩小为字符串以便进一步打印它: " ".join(MASK_TO_PRINT)

    逻辑是这样的: 秘密词是'卷心菜' 你之前猜到了 'c' 和 'a' 所以 self.GUESSED 包含 [0,1,3] 然后你迭代:

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

    【讨论】:

    • 感谢您为创建此答案付出了这么多努力,但我有几个 cmets... 您不需要 需要 导入 sys;有一个内置的exit() 函数。 OP (可能)使用 Python 3,因此他们没有 print 语句,他们必须使用 print() 函数。而且他们没有 raw_input():在 Python 3 中,该函数已重命名为 input(),并且旧的危险 Python 2 input() 函数已被淘汰。我不知道你为什么使用class - 这个任务没有必要(而且 Python 不是 Java),它对于 OP 来说可能有点太高级了。
    • 我相信立即开始使用类永远不会太早,即使 Python 不是 Java 并且脚本在没有单个类的情况下也可以正常工作。类只是组织给定初始必填字段的好方法,非常适合继承和其他好东西。感谢您注意它是 Python3,我想知道为什么这个输入需要引号才能将字符串传递给变量
    【解决方案3】:

    为了帮助您显示猜出的字母,您可以在列表中跟踪它们,其中尚未猜出的字母由下划线(或空格或任何您喜欢的)表示。

    一旦你决定了秘密word,你就可以初始化这样一个列表:

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

    要显示猜出的字母,请用空格连接它们:

    print(' '.join(guessed_letters))
    

    随后,当用户输入字母guess时,您可以通过枚举单词来更新正确猜测的字母:

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

    我已经修改了您的程序以包含此代码:

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

    该程序还有其他问题不在此问题的范围内。

    【讨论】:

    • 我假设您在谈论失败 == 允许和猜测的字符串,我打算稍后修复这些问题。但效果很好,谢谢!
    • 问题:枚举函数究竟是如何工作的?比如什么是''for position''等等?对不起,我是一个完全的菜鸟
    • 您知道range 的工作原理,对吧?它允许您迭代值。好吧,enumerate 做同样的事情,除了它还计算从零开始的值。而不是for position, letter in enumerate(word),您可以写for (position, letter) in enumerate(word),以清楚地表明您在每次迭代中都会得到两件事:单词中从零开始的位置和该位置的字母。
    • 还有一件事:请看这个页面:stackoverflow.com/help/someone-answers
    【解决方案4】:

    要查找字符串中字母的位置,请使用 word.index(guess)。 然后替换“空白”字中的字母。 为此保存b_word = "_ "*len(word), 并在正确的位置替换'_':

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

    然后打印新的 b_word。

    【讨论】:

    • 谢谢,尽管当我输入 b_word[word.index(guess)] = guess 时它给了我一个错误。显然,''str'' 对象不支持项目分配。
    • 对不起,我的错。我已经编辑了答案,尝试将字符串转换为列表。
    • 好的,它没有给出错误,但是当我猜到正确答案时,它仍然会打印整个空白单词。
    • 打印 s 而不是 b_word
    猜你喜欢
    • 2021-07-31
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    相关资源
    最近更新 更多