而循环计数器

时间:2015-12-28 14:37:17

标签: python loops while-loop counter

使用VS2015 Python 3.4
对此while计数器有一些问题。它正在慢慢地让我疯狂,因为我确信它应该'工作,但没有更新柜台。我已经运行了步进调试,可以看到计数器在while条件行之前重置为3。至少可以说我很烦。

import random
import getpass
print ('Welcome to Rock, Paper or Sissors\nEnter an option.')
user_obj = getpass.getpass('Rock, Paper or Sissors: ').lower()
ai_obj = input('Rock, Paper or Sissors: ').lower()
rps = ('rock', 'paper', 'sissors')
#ai_rps = ['rock', 'paper', 'sissors']
#ai_obj = random.choice(ai_rps)
counter = 3
def rps_game(user_obj, ai_obj):
    print('Player selected %s ' % user_obj)
    print('Computer selected %s ' % ai_obj)
    condition = user_obj in rps and ai_obj in rps
    while condition == True and counter >= 0:     
        if user_obj == ai_obj:
            print('Its a draw!')
        elif user_obj == 'rock':
            if ai_obj == 'paper':
                print('You lose!')
                break
            else:
                print('You win!')
        elif user_obj == 'paper':
            if ai_obj == 'sissors':
                print('You lose!')
                break
            else:
                print('You win!')
        elif user_obj == 'sissors':
            if ai_obj == 'rock':
                print('You lose!')
            else:
                print('You win!')
                break    
    else:
        counter += 1 
        print('Invalid input, please select Rock, Paper or Sissors')
        rps_game(user_obj, ai_obj)

rps_game(user_obj, ai_obj)

2 个答案:

答案 0 :(得分:1)

counter重置为其原始值,因为它是一个全局变量。 Python中的全局变量与其他语言的行为不同。试试这个片段:

counter = 3
def f():
    counter = 2 # Shadows global 'counter' by a newly defined one
f()
print (counter) # Prints 3 !

您可以预期打印值为2,而不是3。默认情况下,全局变量是不可变的,并且尝试在没有global关键字的本地范围内修改它将改为使用本地定义。请参阅this discussion以使用全局变量,但最好重新编写程序以使用局部变量。

编辑: 还有一个错误,计数器初始化为3并且仅递增,因此将始终满足条件> = 0(从而创建无限循环)。 你可以尝试:

[...]
def rps_game(user_obj, ai_obj, counter):
    if counter <= 0:
         return
    print('Player selected %s ' % user_obj)
    print('Computer selected %s ' % ai_obj)
    while user_obj in rps and ai_obj in rps :
    [...]
    else:
        print('Invalid input, please select Rock, Paper or Sissors')
        rps_game(user_obj, ai_obj, counter-1)

rps_game(user_obj, ai_obj, 3)

答案 1 :(得分:0)

包含计数器更新的else缩进,以便它暂停。这意味着它只在while循环终止时执行,因为条件为false(不是在你爆发时)。在这种情况下,当用户或ai输入不在有效输入列表中或计数器为负时,条件为假。计数器永远不会是负数,因为它从3开始并且只是递增。如果用户输入无效,则打印错误消息,计数器递增,然后使用递归调用具有相同参数的函数。由于参数没有改变,函数应该做它刚才做的事情,除非它依赖于全局数据(计数器)。但是,如果counter是local(在函数内部初始化),则函数的每次调用都会获得一个新的副本。如果counter是全局的(在函数外部初始化,但在函数内声明为全局),它仍然无法工作,因为你需要递减它。即使这样,因为没有其他输入发生变化,它只会反复打印错误信息。

你的循环限制似乎期望计数器从3开始倒数,因为只要counter为正,它就会继续运行。顺便说一句,使用>=作为条件将使循环执行4次(3,2,1和0)。您可能希望将条件更改为严格大于,并将计数器增量更改为计数器减量。

接下来,您正在使用递归(函数调用自身),但这应该是不必要的,因为循环会将您带回到您需要的位置。

接下来,失败案例突破了循环,但胜诉案例没有。如果你赢了,代码将循环,而不是修改计数器或任何其他输入,所以它不会终止。

最后,从函数外部读取用户输入,因此它永远不会在循环内部发生变化。如果用户输入非法值,则循环将继续测试相同的值。您可能想要读取循环内的用户输入。