2

我正在使用 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()

谢谢您的帮助!

4

4 回答 4

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'). 这总是评估为,True因为所有非空字符串都是 "truthy"。因此,您的整个条件总是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()]
于 2013-09-23T22:19:11.543 回答
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'
于 2013-09-23T22:19:17.507 回答
1

正如其他用户指出的那样,您需要将验证更改is_valid_guess为:

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

虽然这不能解决您眼前的问题,但这是一个很好的(值得投票的)建议,并且可以让您避免一些您可能会遇到的错误。

此外,无论用户输入什么,您总是返回他们输入的内容。为了防止这种情况,您必须user_guess()在您的else块中返回:

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
于 2013-09-23T22:40:58.943 回答
1

只需更改inputraw_input

于 2015-12-13T13:49:35.187 回答