python倒计时在倒计时结束时不执行任务

问题描述 投票:0回答:1

我正在尝试编写一个代码,如果您在我的游戏一定时间后没有响应,则代码结束 这是我的代码:

""" This app is a simulator of running a restaurant.
    The orders are randomly generated"""
import time
import random
from threading import Timer

parts = ["Can I get a uhh a ", "I will get the ", "I will get the "]
foods = ["fries", "chips", "soda", "water", "salad", "sandwich", "cookie"]
# imports neccesary libraries and defines lists

print("Welcome to restaurant simulator!\n")
print(
    "Type the order given to you quick\nIf you get it wrong you lose\nThe time gets smaller the more you go\ntry to get a highscore!"
)
time.sleep(2)
input("Press enter to begin!\n")
# explain the game
score = 0
time_left = 5
# defines base variables
def idk():
    print("")
def newTimer():
    global t
    timeout = time_left
    t = Timer(timeout, idk)
    Timer(timeout, print, [f"\nGame over. Your score is {score}"])
newTimer()
# defines a function to restart the timer
while True:
    part1 = random.choice(parts)
    food = random.choice(foods)
    if part1 == parts[-1]:
        food1 = random.choice(foods)

        ask = input(f"{part1}{food}. Wait no the {food1}! Sorry for the confusion.\n")
        if ask.lower().strip() == food1:
            print("\n")
            score = score + 1
            time_left = time_left - 0.1
            t.cancel()
            newTimer()
            t.start()
        else:
            break

        ask = input(f"{part1}{food}\n")
        if ask.lower().strip() == food:
            score = score + 1
            time_left = time_left - 0.1
            t.cancel()
            newTimer()
            t.start()
        else:
            break


# tells score and ends game
print(f"\nGame over. Your score is {score}.")

请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题请帮助我解决这个问题

python import
1个回答
0
投票

有一些例子使用

threading
来运行
input()
并在超时时杀死它,但我宁愿使用具有功能
kbhit()
的模块来检查是否有任何按键被按下(不阻塞代码并等待按键)和
getch()
/
getchar()
来获取此字符。

这样我可以运行循环来检查

kbhit
并运行其他代码来检查是否还有时间回答,它甚至可以显示旋转动画或显示结束时间。当时间到或用户按
ENTER
时退出此功能。它返回文本和剩余时间 - 如果时间大于 0,那么您可以假设用户准时按下了
ENTER
。当然你可以改变它,当用户按下
True
时,你可以返回
ENTER

这里是最少的工作代码。

下面是我在代码中使用的模块

kbhit
的代码。
您必须将这两个文件放在同一个文件夹中。

import time
import random
import kbhit

# --- functions ---

def get_input(timeout):
    animation = r'-\|/'
    index = 0

    text = ""
    
    kb = kbhit.KBHit()

    start_time = time.time()

    while True:
    
        # slow down for animation
        time.sleep(0.05)
        
        current_time = time.time()
        time_left = timeout - (current_time - start_time)

        if time_left < 0:  # to display it correctly when it is smaller then 0
            time_left = 0

        # print animation + time + text
        print(f'\r[{animation[index]}][{time_left:.1f}] : {text}', end='', flush=True)
        index = (index + 1) % len(animation)
        
        if time_left == 0:  # to exit after displaying corrected time 
            break   
            
        if kb.kbhit():
            char = kb.getch()
            if char == '\n':  # ENTER
                break
            elif ord(char) == 127:  # BACKSPACE
                if text:
                    print('\b \b', end='', flush=True) # move back, print space, and move back again
                    text = text[:-1]                
            else:  
                text += char
            
    print()
    return text, time_left

# --- main ---

parts = ["Can I get a uhh a ", "I will get the ", "I will get the "]
foods = ["fries", "chips", "soda", "water", "salad", "sandwich", "cookie"]

print("Welcome to restaurant simulator!\n")
print("Type the order given to you quick")
print("If you get it wrong you lose")
print("The time gets smaller the more you go")
print("try to get a highscore!")
time.sleep(2)

input("\nPress ENTER to begin!\n")

score = 0
time_left = 5
    
while True:
    part1 = random.choice(parts)
    food  = random.choice(foods)
    
    if part1 == parts[-1]:
        food1 = random.choice(foods)

        # --- 
        
        print(f"{part1}{food}. Wait no the {food1}! Sorry for the confusion.\n")
        ask, timeout = get_input(time_left)

        print('answer   :', ask)
        print('time left:', timeout)
        
        if timeout <= 0:
            print('Sorry, too late')
            break
            
        if ask.lower().strip() == food1:
            print("\n")
            score = score + 1
            time_left = time_left - 0.1
        else:
            print('Sorry, wrong answer')       
            break

        # --- 

        print(f"{part1}{food}\n")
        ask, timeout = get_input(time_left)

        print('answer   :', ask)
        print('time left:', timeout)
        
        if timeout <= 0:
            print('Sorry, too late')
            break

        if ask.lower().strip() == food:
            print("\n")
            score = score + 1
            time_left = time_left - 0.1
        else:
            print('Sorry, wrong answer')       
            break

# tells score and ends game
print(f"\nEND: Game over. Your score is {score}.")

模块

kbhit.py
来自要点 michelbl/kbhit.py

#!/usr/bin/env python
'''
A Python class implementing KBHIT, the standard keyboard-interrupt poller.
Works transparently on Windows and Posix (Linux, Mac OS X).  Doesn't work
with IDLE.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as 
published by the Free Software Foundation, either version 3 of the 
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
'''

import os

# Windows
if os.name == 'nt':
    import msvcrt

# Posix (Linux, OS X)
else:
    import sys
    import termios
    import atexit
    from select import select


class KBHit:

    def __init__(self):
        '''Creates a KBHit object that you can call to do various keyboard things.
        '''

        if os.name == 'nt':
            pass

        else:

            # Save the terminal settings
            self.fd = sys.stdin.fileno()
            self.new_term = termios.tcgetattr(self.fd)
            self.old_term = termios.tcgetattr(self.fd)

            # New terminal setting unbuffered
            self.new_term[3] = (self.new_term[3] & ~termios.ICANON & ~termios.ECHO)
            termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.new_term)

            # Support normal-terminal reset at exit
            atexit.register(self.set_normal_term)


    def set_normal_term(self):
        ''' Resets to normal terminal.  On Windows this is a no-op.
        '''

        if os.name == 'nt':
            pass

        else:
            termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term)


    def getch(self):
        ''' Returns a keyboard character after kbhit() has been called.
            Should not be called in the same program as getarrow().
        '''

        s = ''

        if os.name == 'nt':
            return msvcrt.getch().decode('utf-8')

        else:
            return sys.stdin.read(1)


    def getarrow(self):
        ''' Returns an arrow-key code after kbhit() has been called. Codes are
        0 : up
        1 : right
        2 : down
        3 : left
        Should not be called in the same program as getch().
        '''

        if os.name == 'nt':
            msvcrt.getch() # skip 0xE0
            c = msvcrt.getch()
            vals = [72, 77, 80, 75]

        else:
            c = sys.stdin.read(3)[2]
            vals = [65, 67, 66, 68]

        return vals.index(ord(c.decode('utf-8')))


    def kbhit(self):
        ''' Returns True if keyboard character was hit, False otherwise.
        '''
        if os.name == 'nt':
            return msvcrt.kbhit()

        else:
            dr,dw,de = select([sys.stdin], [], [], 0)
            return dr != []


# Test    
if __name__ == "__main__":

    kb = KBHit()

    print('Hit any key, or ESC to exit')

    while True:

        if kb.kbhit():
            c = kb.getch()
            c_ord = ord(c)
            print(c)
            print(c_ord)
            if c_ord == 27: # ESC
                break
            print(c)

    kb.set_normal_term()
© www.soinside.com 2019 - 2024. All rights reserved.