Python摇滚,纸,剪刀游戏

时间:2013-09-23 22:13:00

标签: python-3.x

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

我知道这告诉我这个数字没有引用,但根据我对代码的理解,当限定符为false时,它不需要数字。

#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 个答案:

答案 0 :(得分: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,因为all non-empty strings are "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()]

答案 1 :(得分: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'

答案 2 :(得分: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

答案 3 :(得分:1)

只需将input更改为raw_input

即可