【问题标题】:Beginner to Python - why the heck is my while loop not working?Python 初学者 - 为什么我的 while 循环不起作用?
【发布时间】:2015-03-20 02:45:18
【问题描述】:

我正在尝试为作业编写一个程序,您可以在其中输入特定命令,然后您可以对着计算机玩 Rock-Paper-Scissors-Lizard-Spock。 它已经完成并且一直在工作,直到我意识到分配说明希望我完成它,以便您继续玩游戏,直到一个人获得五场胜利。

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

这是我的代码。麻烦的while循环在底部。我几乎很肯定课堂上的一切都有效。我想指出我已经尝试过 while(computerWins

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 rockPaperScissorsLizardSpock: 到底应该做什么。是的,如此简单的事情变得复杂
  • 我应该让用户输入这些字母,并且使用数字来匹配这些值似乎是最直接的方法。如果这是 java 或者我不应该做这些特别的事情,它会更简单。您对这个 while 循环问题有什么建议吗?
  • 我正在尽我所能。我是 python 新手。我以为它应该是一堂课。在这个循环之前它工作得很好。好吧,就像我说的那样,我确实在我的 while 循环中对这两个语句都使用了
  • 对于这么简单的事情,不要为类定义而烦恼。只需创建一些您将调用的函数。 Python 被创建为像这样灵活,没有严格的类结构,因此您可以快速原型化简单的东西(您当然可以创建类,但这不是必需的)。另外,明确标记__main__ 方法,它使代码更易于阅读。做类似if __name__ == "__main__": 之类的事情,这是Java 的public static void main(String[] args) 的Python 等价物

标签: python while-loop python-3.3


【解决方案1】:

基本问题是rockpaperscissorslizardspock 是一个,您希望它是一个函数。它里面的代码只运行一次,当整个类定义被解析时,而不是像你期望的那样每次调用类。

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

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

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

【讨论】:

  • 谢谢!!这解决了一切!我希望我能投票给你。非常感谢。我必须学习更多关于正确使用类的知识。
【解决方案2】:

第一件事是你正在使用一个你可能应该使用函数的类。

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

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

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

之后,您将在本地上下文中遇到全局变量的问题。这个问题已经在另一个 StackOverflow 问题中得到了解释:Using global variables in a function other than the one that created them

【讨论】:

    【解决方案3】:

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

    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
    

    【讨论】:

    • 这太棒了——我肯定在这里学到了一些东西。不幸的是,我认为我必须按照自己的方式行事。这是作业要我做的:
    • (10 分) rockPaperScissorsLizardSpock() 编写一个 Python 函数来玩 Rock、Paper、Scissors、Lizard Spock 游戏。将您的函数命名为 RockPaperScissorsLizardSpock。它应该按如下方式运行:计算机选择石头、纸、剪刀、蜥蜴或斯波克。用户输入她的选择。该程序会打印出选择并说明谁赢了。
    • 运行的示例输出如下所示: 输入您的选择 (r)ock, (p)aper, (sc)cissors, (l)izard, (sp)pock): p 计算机选择蜥蜴。你选择了纸。电脑赢了。您的程序应该继续玩游戏,直到一方获胜五次。请注意,可以使用大型条件语句来确定获胜者,但更自然的方法是使用字典
    • 我明白了,这只是为了灵感;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2022-01-26
    相关资源
    最近更新 更多