PYTHON: How to make a program to stop if some seconds have passed?

Viewed 436

So I'm making a little speed game. A random letter is going to be generated by a function, right after that, I want the program to wait some seconds. If nothing is pressed, you will lose and your record will be displayed If you press the right key, another random letter is going to be displayed. I used the time function and simulated a cronometer that lasts in a range (0,2). This is what I have so far. It works, the thing is, it displays the first letter, if you press it wrong you lose (good) but even if you press it right, the cronometer obviously keeps running, so it gets to 2 and you lose. I want it to stop and reset after I hit the key, but I have no idea of how to do it. Im new in programming so I'm sorry if you don't get something.

import string
import random
import msvcrt
import time

def generarletra():
    string.ascii_lowercase
    letra = random.choice(string.ascii_lowercase)
    return letra

def getchar():
    s = ''
    return msvcrt.getch().decode('utf-8')

print("\nWelcome to Key Pop It!")
opcion = int(input("\n  Press 1 to play OR\n  Press 2 for instructions"))

if(opcion == 1):
    acum=0
    while True:
        letra2 = generarletra()
        print(letra2)
        key = getchar()
        for s in range (0,2):
            print("Segundos ", s)
            time.sleep(2)
        acum = acum + 1
        if((key is not letra2) or (s == 2)):
            print("su record fue de, ", acum)
            break

elif(opcion == 2):
    print("\n\nWelcome to key pop it!\nThe game is simple, the machine is going to generate a 
random\nletter and you have to press it on your keyboard, if you take too\nlong or press the wrong 
letter, you will lose.")
else:
    print("Invalid option!")

PD: You need to run it with a console simulation in your IDE or directly from the console. msvcrt library won't work inside an IDE for some reason.

2 Answers

msvcrt.getch() is blocking, so you don't actually measure the time it took the user to press the key. The for loop starts after the user already pressed it. also, time.sleep() is blocking, so the user will have to wait the sleep time even if he already pressed the key.

To solve the first problem you can use msvcrt.kbhit() to check if the user pressed on some key, and call msvcrt.getch() only if he did. This way msvcrt.getch() will return immediately after you call it.

To solve the second problem you can just use time.time() to get the start time of the round, and compare it to current time inside a loop. You can print how much time passed inside the loop also.

Here is the final code (with some extra naming and formatting changes):

import string
import random
import msvcrt
import time

MAX_TIME = 2

def get_random_char():
    return random.choice(string.ascii_lowercase)

def get_user_char():
    return msvcrt.getch().decode('utf-8')

print("\nWelcome to Key Pop It!")
option = input("\n  Press 1 to play OR\n  Press 2 for instructions\n")

if option == "1":
    score=0
    while True:
        char = get_random_char()            
        print("\n" + char)
        start_time = time.time()
        while not msvcrt.kbhit():
            seconds_passed = time.time() - start_time
            print("seconds passed: {0:.1f}".format(seconds_passed), end="\r")
            if seconds_passed >= MAX_TIME:
                key = None
                break
        else:
            key = get_user_char()
        if key != char:
            break
        score = score + 1
    print("\nsu record fue de, ", score)

elif option == "2":
    print("""
    Welcome to key pop it!
    The game is simple, the machine is going to generate a random
    letter and you have to press it on your keyboard, if you take too
    long or press the wrong letter, you will lose.""")
else:
    print("Invalid option!")

Timestamp-solution:

from time import time, sleep

start = time()  # start time measuring by creating timestamp


def time_passed(start, duration):
    """tests if an amount of time has passed
    Args:
        start(float): timestamp of time()
        duration(int): seconds that need to pass
    Returns:
        bool: are 'duration' seconds over since 'start'
    """
    return start + duration <= time()


# Use as condition for while
while not time_passed(start, 5):
    sleep(1)

# ... or if statements or <younameit>
if time_passed(start, 5):
    print("Do something if 5 seconds are over")
Related