2013-09-23 96 views
2

我正在使用Python,我正在嘗試編寫一個模擬岩石,紙張,剪刀遊戲的簡單程序。除了當我輸入一個無效的回覆(除岩石,紙張或剪刀以外的東西)時,一切都可以正常工作。Python岩石,紙,剪刀遊戲

Traceback (most recent call last): 
File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 88, in <module> 
main() 
File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 14, in main 
number = user_guess() 
File "C:/Users/home/Desktop/BAGARDNER/Python/rock_pape_scissors.py", line 48, in user_guess 
return number 
UnboundLocalError: local variable 'number' referenced before assignment 

我明白,這是告訴我,號碼不被引用,但是從我瞭解的代碼,它不應該需要一個號碼時限定符是假的。

#import random module 
import random 
#main function 
def main(): 
    #intro message 
    print("Let's play 'Rock, Paper, Scissors'!") 
    #call the user's guess function 
    number = user_guess() 
    #call the computer's number function 
    num = computer_number() 
    #call the results function 
    results(num, number) 

#computer_number function 
def computer_number(): 
    #get a random number in the range of 1 through 3 
    num = random.randrange(1,4) 
    #if/elif statement 
    if num == 1: 
     print("Computer chooses rock") 
    elif num == 2: 
     print("Computer chooses paper") 
    elif num == 3: 
     print("Computer chooses scissors") 
    #return the number 
    return num 

#user_guess function 
def user_guess(): 
    #get the user's guess 
    guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ") 
    #while guess == 'paper' or guess == 'rock' or guess == 'scissors': 
    if is_valid_guess(guess): 
     #if/elif statement 
     #assign 1 to rock 
     if guess == 'rock': 
      number = 1 
     #assign 2 to paper 
     elif guess == 'paper': 
      number = 2 
     #assign 3 to scissors 
     elif guess == 'scissors': 
      number = 3 
     return number 
    else: 
     print('That response is invalid.') 
     user_guess() 

def is_valid_guess(guess): 
    if guess == 'rock' or 'paper' or 'scissors': 
     status = True 
    else: 
     status = False 
    return status 

def restart(): 
    answer = input("Would you like to play again? Enter 'y' for yes or \ 
    'n' for no: ") 
    #if/elif statement 
    if answer == 'y': 
     main() 
    elif answer == 'n': 
     print("Goodbye!") 
    else: 
     print("Please enter only 'y' or 'n'!") 
     #call restart 
     restart() 

#results function 
def results(num, number): 
    #find the difference in the two numbers 
    difference = num - number 
    #if/elif statement 
    if difference == 0: 
     print("TIE!") 
     #call restart 
     restart() 
    elif difference % 3 == 1: 
     print("I'm sorry! You lost :(") 
     #call restart 
     restart() 
    elif difference % 3 == 2: 
     print("Congratulations! You won :)") 
     #call restart 
     restart() 

main() 

謝謝你的幫忙!

回答

3

這是你的問題:

if guess == 'rock' or 'paper' or 'scissors': 

這條線is_valid_guess沒有做什麼,你認爲它。相反,它總是返回True。你正在尋找的是這樣的:

if guess == 'rock' or guess == 'paper' or guess == 'scissors': 

或更簡潔:

if guess in ('rock', 'paper', 'scissors'): 

的問題是,你有什麼總是返回True因爲Python如何在一個字符串評估布爾上下文。該生產線if guess == 'rock' or 'paper' or 'scissors':計算結果爲:

if (guess == 'rock') or ('paper') or ('scissors'): 

這意味着就是,Python檢查,看看是否guess == 'rock'。如果這是真的,則條件評估爲True。如果它是錯誤的,解釋器會嘗試評估bool('paper')。由於all non-empty strings are "truthy"因此總是評估爲True。因此,您的整個條件總是True,並且每個字符串都是「有效的」。

因此,您的代碼會將所有字符串視爲「有效」,然後在未將實際支持的猜測分配給某個數字時爆炸。


最後一點,你is_valid_guess方法可以精簡一點,因爲你只是回到你的布爾表達式的結果。而不是將status變量用作中間變量,只需計算表達式並立即返回即可。我還使用字符串對象的lower()方法來允許不區分大小寫的猜測,以防萬一您要允許。

def is_valid_guess(guess): 
    return guess.lower() in ('rock', 'paper', 'scissors') 

你有另外一個問題,你在評論中提到:你在遞歸的方式實現user_guess,所以它如果用戶輸入一個無效的猜測調用自身。但是,在這種情況下,它不會返回遞歸調用的結果。您需要通過更改的user_guess最後一行返回遞歸結果:

return user_guess() 

否則你應該做的是功能使用一個循環,而不是遞歸,這是我會做什麼,因爲功能不固有遞歸。你可以做這樣的事情:

def user_guess(): 
    # get first guess 
    guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ") 

    # If that guess is invalid, loop until we get a valid guess. 
    while not is_valid_guess(guess): 
     print('That response is invalid.') 
     guess = input("Choose 'rock', 'paper', or 'scissors' by typing that word. ") 

    # Now assign the (valid!) guess a number 
    # This dictionary is just shorthand for your if/elif chain. 
    guess_table = { 
     'rock' : 1, 
     'paper' : 2, 
     'scissors' : 3 
    } 

    # Return the number associated with the guess. 
    return guess_table[guess.lower()] 
+0

謝謝你的快速反應。這已經解決了我最初的問題。但是,現在我得到一個新的錯誤。回傳(最近呼叫最後): 文件「C:/Users/home/Desktop/BAGARDNER/Python/rock_paper_scissors.py」,第84行,在 main() 文件「 C:/Users/home/Desktop/BAGARDNER/Python/rock_paper_scissors.py「,第18行,在主 結果(編號,編號) 文件」C:/Users/home/Desktop/BAGARDNER/Python/rock_paper_scissors.py「 ,第70行,結果爲 difference = num - number TypeError:不支持的操作數類型爲 - :'int'和'NoneType' –

+0

這發生在我以其他方式「修復」它之前。 –

+1

@BryceGardner這是因爲'user_guess'中的一個錯誤。當發現無效響應時,再次調用'user_guess()',但不返回結果。因此,無論何時你最終輸入一個合法的猜測,這個結果都會被丟棄,'user_guess'返回'None'直到'main'函數。只需將'user_guess'的最後一行更改爲'return user_guess()'。 –

1

變化

if guess == 'rock' or 'paper' or 'scissors': 

if guess == 'rock' or guess == 'paper' or guess == 'scissors': 

事實上,爲了使功能精簡越好,只是這樣做:

def is_valid_guess(guess): 
    return guess == 'rock' or guess == 'paper' or guess == 'scissors' 
+0

雖然修復了最初的問題,但它會產生一個新問題:Traceback(最近調用最後一次): 文件「C:/Users/home/Desktop/BAGARDNER/Python/rock_paper_scissors.py」,第84行, main() 文件「C:/Users/home/Desktop/BAGARDNER/Python/rock_paper_scissors.py」,第18行,主要爲 results(num,number) 文件「C:/ Users/home/Desktop/BAGARDNER/Python/rock_paper_scissors.py「,第70行,結果爲 difference = num - number TypeError:不支持的操作數類型爲 - :'int'和'NoneType' –

+0

@BryceGardner:檢查Henry Keiter的上面的註釋。 –

1

其他用戶指出,你需要改變你的驗證在is_valid_guess到:

if guess == 'rock' or guess == 'paper' or guess == 'scissors': 

雖然這不會解決你眼前的問題,這是件好事(給予好評,值得)的意見,並會讓你避免你會遇到一些錯誤。 。

另外,無論什麼用戶輸入,你總是返回他們鍵入爲了防止這種情況,你必須在你的else塊返回user_guess()

if is_valid_guess(guess): 
    #if/elif statement 
    #assign 1 to rock 
    if guess == 'rock': 
     number = 1 
    #assign 2 to paper 
    elif guess == 'paper': 
     number = 2 
    #assign 3 to scissors 
    elif guess == 'scissors': 
     number = 3 
    return number 
else: 
    print('That response is invalid.') 
    return user_guess() # <-- right here 
1

只要改變inputraw_input