Python 初学者 - 为什么我的 while 循环不起作用?

Beginner to Python - why the heck is my while loop not working?

我正在尝试为一项作业编写一个程序,您可以在其中输入特定命令,然后您可以对着计算机玩石头剪刀石头布蜥蜴史波克游戏。 它已经完成并开始工作,直到我意识到作业说明要我做到这一点,以便您继续玩游戏直到一个人获得五场胜利。

所以我想,没什么大不了的,让我们加入一个 while 循环和一些变量来跟踪胜利。但是当我运行这个程序的时候,它只有运行一次还在。我不知道我做错了什么 - 因为这应该有效。这是我第一次使用 Python(3.3 版)和这个 IDE,所以我真的需要一些帮助。通常我只是调试,但我不知道如何在这个 IDE.

中工作

这是我的代码。麻烦的 while 循环在底部。我几乎肯定 class 中的所有内容都有效。我想指出,我已经尝试过 while(computerWins < 5 and userWins < 5),所以我认为条件不是问题所在。

import random

computerWins = 0
userWins = 0
print ('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\nSpock = sp')

class rockPaperScissorsLizardSpock:
#Two methods for converting from strings to numbers

    #convert name to number using if/elif/else
    #also converts abbreviated versions of the name
    def convertName(name):
        if(name == 'rock' or name == 'r'):
            return 0
        elif(name == 'Spock' or name == 'sp'):
            return 1
        elif(name == 'paper' or name == 'p'):
            return 2
        elif(name == 'lizard' or name == 'l'):
            return 3
        elif(name == 'scissors' or name == 'sc'):
            return 4
        else:
            print ('Error: Invalid name')

    #convert number to a name using if/elif/else
    def convertNum(number):
        if(number == 0):
            return 'rock'
        elif(number == 1):
            return 'Spock'
        elif(number == 2):
            return 'paper'
        elif(number == 3):
            return 'lizard'
        elif(number == 4):
            return 'scissors'
        else:
            print ('Error: Invalid number')

    #User selects an option, and their selection is saved in the 'choice' variable    
    #Using a while loop so that the user cannot input something other than one of the legal options
    prompt = True
    while(prompt):
        i = input('\nEnter your selection: ')
        if(i=='r' or i=='p' or i=='sc' or i=='l' or i=='sp'):
            prompt = False
        else:
            print('Invalid input.')
    prompt = True

    #Convert the user's selection first to a number and then to its full string
    userNum = convertName(i)
    userChoice = convertNum(userNum)

    #Generate random guess for the computer's choice using random.randrange()
    compNum = random.randrange(0, 4)

    #Convert the computer's choice to a string
    compChoice = convertNum(compNum)

    print ('You chose', userChoice)
    print ('The computer has chosen', compChoice)

    #Determine the difference between the players' number selections
    difference = (compNum - userNum) % 5

    #Use 'difference' to determine who the winner of the round is
    if(difference == 1 or difference == 2):
        print ('The computer wins this round.')
        computerWins = computerWins+1
    elif (difference == 4 or difference == 3):
        print ('You win this round!')
        userWins = userWins+1
    elif(difference == 0):
        print ('This round ended up being a tie.')

#Plays the game until someone has won five times
while(computerWins != 5 and userWins != 5):
    rockPaperScissorsLizardSpock()

if(computerWins == 5 and userWins != 5):
    print ('The computer wins.')
elif(computerWins != 5 and userWins == 5):
    print ('You win!')

第一件事是您正在使用 class,而您可能应该使用函数。

您的代码最初是 运行,因为 python 正在加载 class。

但是,行 rockPaperScissorsLizardSpock() 正在创建您的 class 的新匿名实例,它调用您尚未定义的构造函数,因此它什么都不做。

关于 python 的一个有趣的事情是它允许嵌套函数,所以如果您将 class 更改为 def,您就快成功了。

之后,您将 运行 在局部上下文中遇到全局变量问题。该问题已在另一个 Whosebug 问题中得到解释:Using global variables in a function other than the one that created them

根本问题是 rockpaperscissorslizardspock 是一个 class,您希望它是一个函数。其中的代码 运行s exactly once,当整个 class 定义被解析时,而不是每次调用 class期待。

可以 将相关代码放入 __init__ 方法中 - 这是 Java 构造函数的相当直接的类比,因此 运行每次调用class。但在这种情况下,您可能根本不需要它在 class 中 - 调用 class 会创建一个新实例(就像在 Java 中执行 new MyClass() 一样) ,你不使用。在这种情况下(或者如果您将其变成一个函数)您还需要进行更多修改以确保游戏状态正确持续。

最简单的实际解决方案是:

  1. 删除行 class rockpaperscissorslizardspock:(并取消缩进它下面的所有内容)
  2. 获取 class 下但不在函数中的所有代码 - 从玩家做出选择到确定回合获胜者的所有代码 - 并将其粘贴到 [= 的调用位置14=] 在底部循环中。

这是我对骨骼的建议,以更简单的解决方案。如果你愿意,可以使用这里的一些想法。

import random

legal_shapes = ['r', 'p', 'sc', 'sp', 'l']
scoreboard = [0, 0]
print('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\n'
      'Spock = sp')

while(max(scoreboard) < 5):

    print("\nScore is {}-{}".format(*scoreboard))

    # pick shapes
    p1_shape = input('Enter your selection: ')
    if p1_shape not in legal_shapes:
        print('Not legal selection!')
        continue
    p2_shape = random.choice(legal_shapes)
    print('\np1 plays {} and p2 plays {}'.format(
        p1_shape.upper(), p2_shape.upper()))

    # determine int values and result indicator
    p1_shape_int = legal_shapes.index(p1_shape)
    p2_shape_int = legal_shapes.index(p2_shape)
    res = (p1_shape_int - p2_shape_int) % 5
    if res != 0:
        res = abs((res % 2) - 2)

    # Print winner
    if res == 0:
        print(' -> Draw!!')
    else:
        print(' -> p{} wins'.format(res))
        scoreboard[res-1] += 1

print("\nThe game is over!!")
print("p{} won with score {}-{}".format(res, *scoreboard))

它输出类似

的内容
(env)➜ tmp python3 rsp.py
SELECTION KEY:
Rock = r
Paper = p
Scissors = sc
Lizard = l
Spock = sp

Score is 0-0
Enter your selection: T
Not legal selection!

Score is 0-0
Enter your selection: l

p1 plays L and p2 plays SP
 -> p2 wins

Score is 0-1
Enter your selection: l

p1 plays L and p2 plays SC
 -> p2 wins

...

The game is over!!
p2 won with score 2-5