记忆游戏计时器的实现和错误处理

时间:2019-03-27 04:29:26

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

我已经实现了一个记忆游戏,用户必须在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”,程序将终止并显示错误消息: 追溯(最近一次通话):   在第22行的文件“ memory_game.py”中     选择= int(输入字符串)     ValueError:以10为底的int的无效文字:''
3.如果玩家输入任何随机数,程序将退出并显示“索引超出范围错误”-我找不到放置尝试的位置:例外: 任何帮助将不胜感激-谢谢!

1 个答案:

答案 0 :(得分:0)

关于您的问题:

  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()                                                                                                           
相关问题