python-3.x - 记忆游戏计时器实现和错误处理
问题描述
我已经实现了一个记忆游戏,用户必须在 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”,程序将终止并显示错误消息: Traceback (last recent call last): File "memory_game.py", line 22, in selection = int(input_string) ValueError: invalid以 10 为基数的 int 的文字:''
3. 如果玩家输入任何随机数,程序将退出并出现“索引超出范围错误” - 我找不到在哪里放置 try: except: 任何帮助将不胜感激 -谢谢!
解决方案
至于你的问题:
- 您可以使用
t.cancel()
(停止计时器并且不调用该函数)而不是t.join()
(等到线程完成;这总是会导致超时,当然) - (和 3。)这些基本上是相同的——将查询消息和所有输入处理放入一个
while
循环中,一旦你知道输入是有效的,就跳出它
...
- 另外,“超时”消息实际上并没有做任何有用的事情(例如,在超时发生后您仍然可以输入有效答案。我通过在超时时使程序退出以蛮力的方式“修复”该问题除了这样做,您还可以使用全局变量来存储超时是否被命中,并在您的输入中相应地处理它(确保使用例如互斥锁使其成为线程安全的)。
一般来说,把程序的结构转一下可能会更容易——让主线程处理输入的超时和验证,让线程只处理输入(这样很容易杀死线程停止被处理的输入)。
当然,使用该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()
推荐阅读
- embedded - 在不同的 STM32F3/F4 MCU 上使用相同的代码
- html - 如何使社交图标与移动设备的中心对齐?
- r - 将 JSON-stat 数据获取到 DF (R) 的问题
- php - 创建包含 woocommerce 类别的页面
- linux - 如何使用自定义 PAM 模块解锁计算机
- php - 如何构建 Wordpress 存档模板以在单个模板中显示作者的多个 post_types?
- visual-studio-code - 如何在 Yocto SDK 中使用 Cmake Tools 扩展配置构建环境
- javascript - 遍历Vue中的json文件
- python - 以概率启动 cronjob
- javascript - 如何在其类索引中获取输入的值并将其分配给在其自己的集合中具有相同索引的另一个输入?