首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >While循环计数器

While循环计数器
EN

Stack Overflow用户
提问于 2015-12-28 22:37:17
回答 2查看 4.1K关注 0票数 2

使用VS2015 Python 3.4

while计数器有一些问题。它慢慢地让我发疯,因为我确信它“应该”工作,但没有更新计数器。我已经运行了单步调试,在while条件行之前可以看到计数器重置为3。至少可以说这让我很恼火。

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

发布于 2015-12-28 23:24:34

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

代码语言:javascript
复制
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将始终得到满足(从而创建无限循环)。您可以尝试:

代码语言:javascript
复制
[...]
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
EN

Stack Overflow用户

发布于 2015-12-29 00:43:57

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

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

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

接下来,失败的案例会跳出循环,但成功的案例不会。如果您赢了,代码将循环,不修改计数器或任何其他输入,因此它不会终止。

最后,用户输入是从函数外部读取的,因此它永远不会在循环内更改。如果用户输入了非法的值,循环将继续测试相同的值。您可能希望读取循环中的用户输入。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34495485

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档