【问题标题】:Memory game timer implementation and error handling记忆游戏计时器实现和错误处理
【发布时间】:2019-03-27 04:29:26
【问题描述】:

我已经实现了一个记忆游戏,用户必须在 5 秒的计时器运行时在脑海中对数字进行排序。

请看下面的代码:

    from random import randint
    from threading import Timer

    def timeout():
        print("Time over\n#####################\n")

    while True:
        list = []
        for i in range(5):
            list.append(randint(1000, 10000))

        t = Timer(5, timeout)
        t.start()

        print(list)
        print('[ 1  ,  2  ,  3  ,  4  ,  5  ]')

        solution = sorted(list)[2]
        print('please select the 3rd largest number in this row (1-5):')
        input_string = input()
        selection = int(input_string)

        if solution == list[selection - 1]:
            print("Your guess is correct\n")
        else:
            print("Your guess is wrong\n")

        t.join()

这里是游戏交互本身(请忽略语法高亮):

USER@HOST:~/$ python3 memory_game.py
[8902, 8655, 1680, 6763, 4489]
[ 1  ,  2  ,  3  ,  4  ,  5  ]
please select the 3rd largest number in this row (1-5):
4
Your guess is correct

Time over
#####################

[5635, 3810, 1114, 5042, 1481]
[ 1  ,  2  ,  3  ,  4  ,  5  ]
please select the 3rd largest number in this row (1-5):
4
Your guess is wrong

Time over
#####################

[6111, 1430, 7999, 3352, 2742]
[ 1  ,  2  ,  3  ,  4  ,  5  ]
please select the 3rd largest number in this row (1-5):
23
Traceback (most recent call last):
  File "memory_game.py", line 24, in <module>
    if solution == list[selection - 1]:
IndexError: list index out of range
Time over
#####################

谁能帮我解决这些问题:
1. 只有当玩家需要超过 5 秒的时间才能回答时,才应该写下“超时”。如果玩家及时解决了它,下一个挑战应该会静默出现。
2. 如果玩家没有写任何猜测并按下“Enter”,程序将终止并显示错误消息: 回溯(最近一次通话最后): 文件“memory_game.py”,第 22 行,在 选择 = int(输入字符串) ValueError:以 10 为基数的 int 的无效文字:''
3. 如果玩家输入任何随机数,程序会以“索引超出范围错误”退出 - 我找不到在哪里放置 try: 除了: 任何帮助将不胜感激 - 谢谢!

【问题讨论】:

    标签: python-3.x error-handling timer


    【解决方案1】:

    至于你的问题:

    1. 您可以使用t.cancel()(停止计时器并且不调用函数)而不是t.join()(等到线程完成;当然,这总是会导致超时)来完成此操作
    2. (和 3.)这些基本相同 - 将查询消息和所有输入处理放入一个 while 循环中,一旦您知道输入有效就将其中断

    ...

    1. 另外,“超时”消息实际上并没有做任何有用的事情(例如,在超时发生后您仍然可以输入有效的答案。我通过使程序退出以蛮力的方式“修复”了该问题如果超时被命中。除了这样做,您还可以使用全局变量来存储超时是否被命中,并在您的输入中相应地处理它(确保使用例如互斥锁使其成为线程安全的)。

    一般来说,转一下程序的结构可能会更容易——让主线程处理输入的超时和验证,让线程只处理输入(这样很容易杀死线程停止处理输入)。

    当然,使用select 模块,可以在没有线程的情况下更好地实现这一点(有一个由线程/计时器写入的管道和标准输入,然后选择两者进行读取,它将阻塞直到用户输入或超时发生)。

    也许有人会发布一个不错的基于asyncio 的解决方案? ;)

    这是修改后的解决方案(尽可能少地修改以使其工作,可以重构其他部分以使其总体上更好):

    import random                                                                                                            
    import threading                                                                                                         
    import os                                                                                                                
    
    def timeout():                                                                                                           
        print("Time over\n#####################\n")                                                                          
        # You can't use sys.exit() here, as this code is running in a thread                                                 
        # See also: https://stackoverflow.com/a/905224/1047040                                                               
        os._exit(0)                                                                                                          
    
    while True:                                                                                                              
        list = []                                                                                                            
        for i in range(5):                                                                                                   
            list.append(random.randint(1000, 10000))                                                                         
    
        t = threading.Timer(5, timeout)                                                                                      
        t.start()                                                                                                            
    
        print(list)                                                                                                          
        print('[ 1  ,  2  ,  3  ,  4  ,  5  ]')                                                                              
    
        solution = sorted(list)[2]                                                                                           
        while True:                                                                                                          
            try:                                                                                                             
                print('please select the 3rd largest number in this row (1-5):')                                             
                input_string = input()                                                                                       
                selection = int(input_string)                                                                                
                chosen = list[selection - 1]                                                                                 
                # If we arrive here, the input was valid, break out of the loop                                              
                break                                                                                                        
            except Exception as e:                                                                                           
                # Tell the user that the input is wrong; feel free to remove "e"                                             
                # from the print output                                                                                      
                print('Invalid input:', e)                                                                                   
    
        if solution == chosen:                                                                                               
            print("Your guess is correct\n")                                                                                 
        else:                                                                                                                
            print("Your guess is wrong\n")                                                                                   
    
        # Make sure to cancel the thread, otherwise guessing correct or wrong                                                
        # will block the CLI interface and still write "time out" at the end                                                 
        t.cancel()                                                                                                           
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      相关资源
      最近更新 更多