簡體   English   中英

無法打破While循環

[英]Can't Break Out of While Loop

我編寫了以下python代碼。 它列出了我在互聯網上找到的英語單詞列表,並將它們作為列表,以便我可以將其用於子手。 好吧,我的問題是,每次我運行該程序並成功猜出單詞時,它都不會脫離while循環。 它一直在繼續。 我不知道為什么要為我的生活。 有人對為什么不向最終獲獎者打印最終信息有任何線索嗎?

import random

words = []

lettersGuessed = []

isGuessed = 0



wordFile = open(r'C:\Users\Sarah\PycharmProjects\hangman\words.txt')

for word in wordFile:
    words.append(word.rstrip(wordFile.readline()))


mysteryWord = random.choice(words)

while len(mysteryWord) <= 1:
    mysteryWord = random.choice(words)

for letter in mysteryWord:
    print("?", end = "")
print("\n")

def isWon():
    #win conditions
    count = 0
    for letter in mysteryWord:
        if letter in lettersGuessed:
            count += 1

        if count == len(mysteryWord):
            isGuessed = 1



count = 0

while isGuessed == 0:


    guess = input("Guess a letter \n")

    if guess.upper() or guess.lower() in mysteryWord:
        lettersGuessed.append(guess)
        for letter in mysteryWord:
            if letter in lettersGuessed:
                print(letter, end ='')
            else:
                print("?", end = '')
    print("\n")
    count = 0
    isWon()
    if isGuessed == 1:
        break

print("Congratulations, you correctly guessed ", mysteryWord)

直接的問題是,無論輸入如何, isWon()都沒有設置isGuessed 如果您猜到字符串“ foo”,那么

lettersGuessed.append(guess)

將使lettersGuessed一個包含一個項目的列表,該項目是一個字符串。 我想你想做的是

lettersGuessed.extend(list(guess))

這會將每個guess字母添加到lettersGuessed列表中。

還有兩點值得一提:

  • 如果您在問題中猜中該詞的字謎,則isWon()會認為游戲獲勝,例如,如果詞“ foo”是“ oof”,則該詞將被視為正確的解決方案
  • words.append(word.rstrip(wordFile.readline()))讀取輸入文件的每一偶數行,並在刪除與下一個單詞共有的任何字符后,將其添加到words列表中。 您想要改為執行words.append(word.strip())

isGuessed在您的頂級代碼和isGuessedisWon功能是兩個不同的變量。 函數是一個單獨的命名空間(否則,函數將使用具有通用名稱的變量,例如i會對其他代碼造成嚴重破壞)。

這可以通過global聲明來解決,但這是非常糟糕的樣式。 同樣適用於mysteryWordlettersGuessed類的變量。

相反,您應該從isWon函數返回值:

def isWon(mysteryWord, lettersGuessed):
   # do your counting...
   return isGuessed

# main code
victory = False
while not victory:
   # ...
   victory = isWon(mysteryWord, lettersGuessed)
   # you don't even need the if ... break statement

順便說一句,您對所有被猜到的字母的支票都可以做成一線:

def isWon(mysteryWord, lettersGuessed):
    return set(lettersGuessed) == set(mysteryWord)

這與范圍有關。 isGuessed isWon()使用的isWon()在本地范圍內定義。 如果要影響在全局范圍中聲明的isGuessed ,則必須在修改isGuessed之前將其作為參數傳遞給isWon()或使用global關鍵字。 見下文:

def isWon():
#win conditions
count = 0
for letter in mysteryWord:
    if letter in lettersGuessed:
        count += 1

    if count == len(mysteryWord):
        global isGuessed
        isGuessed = 1    

輸出此更改:

python3 test.py
?????

Guess a letter
1
?????

Guess a letter
2
?????

Guess a letter
3
????3

Guess a letter
4t
????3

Guess a letter
t
t??t3

Guess a letter
e
te?t3

Guess a letter
s
test3

Congratulations, you correctly guessed  test3

您正在嘗試使用全局變量is_guessed進行通信,但isWon函數未提供global is_guessed行,因此它正在將isWon局部變量設置為is_guessed而不是全局變量。

我的建議是, global is_guessedisWon()添加global is_guessed ,而是從isWon()返回TrueFalse (基於用戶是否贏了),然后使用該值結束循環。

這是您的代碼的替代版本:

import random

words = []
with open(r'C:\Users\Sarah\PycharmProjects\hangman\words.txt') as wordFile:
    for word in wordFile:           # assuming one word per line
        words.append(word.strip())  # iterating a file reads one line per iteration

mysteryWord = random.choice(words)
mysteryLetters = set(mysteryWord.lower())
lettersGuessed = set()

def isWon():
    return mysteryLetters == (lettersGuessed & mysteryLetters)

while not isWon():
    for letter in mysteryWord:
        if letter in lettersGuessed:
            print(letter, end ='')
        else:
            print("?", end = '')
    print()

    guess = input("Guess a letter \n")[:1].lower()

    if guess in mysteryWord:
        lettersGuessed.add(guess)

print("Congratulations, you correctly guessed ", mysteryWord)

好吧,我知道我的回答有點晚了,但這是我的解決方案:

#!/usr/bin/env python3

import random

word_file_name = "/usr/share/dict/canadian-english"

with open(word_file_name) as word_file:
    # I'm assuming your input file has one word per line and that
    # you want to keep only words that has more than one letter
    words = [word.rstrip() for word in word_file if len(word) > 1]

mystery_word = random.choice(words)

# Using sets helps to remove duplicate letters and eases membership tests 
letters_mystery = set(mystery_word.upper())
letters_guessed = set()

not_guessed = True

while not_guessed:
    # We create a list with all the letters found or not
    letters_to_show = [letter if letter.upper() in letters_guessed else "?"
                       for letter in mystery_word]
    # We join them before printing them
    print("".join(letters_to_show), "\n")

    guess_received = input("Guess a letter :")
    if guess_received.strip():
        # We only keep the first letter received
        guess_kept = guess_received[0].upper()

        if guess_kept in letters_mystery:
            letters_guessed.add(guess_kept)

    # We determine if we need to continue
    not_guessed = letters_guessed != letters_mystery

print("Congratulations, you correctly guessed", mystery_word)

關鍵點:

  • 列表理解用於將單詞放入列表
  • 集合用於保留一組字母,不能重復。
  • 條件表達式用於選擇將顯示字母還是顯示?
  • 真相測試可用於簡化某些信息的驗證
  • 您正在使用像isGuessed == 1這樣的表達式,就像在C中,True等於1而False等於0一樣。在Python中,變量可以是布爾值。 您可以在if語句中直接使用它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM