简体   繁体   中英

How to set a time limit for a game?

I've programmed a game that takes a song and artist name from an external file. The program prints the artist name but masks the title of the song, and the user must guess the title correctly to earn points. That works fine, but I want to add a time limit, so they only have 60secs to get the highest score they possibly can.

Here's the part of the code I'm referencing:

def pickSong_random():
  score=0
  lives=5
  songFile = open("F_Songs.txt","r")
  songList = songFile.readlines() #Reads from the bridged file
  songFile.close()
  while True:
    chosenSong = random.choice(songList)

    chosenSong = chosenSong.strip("\n")
    artistAndSong = chosenSong.split(":") #Defines song split

    toDisplay = ""
    toDisplay += artistAndSong[0] + ": "
    songTitleWords = artistAndSong[1].split(" ")

    for word in songTitleWords:
      #loop through
      toDisplay += word[0] + " "
    print(toDisplay)
    #print("2" +toDisplay)
    toDisplay = toDisplay.strip("None")
    guesses = 0
    while guesses <2:
        guesses += 1
        guess = input("[Guess]: ")

        #Guess checking
        if guess.lower() == artistAndSong[1].lower():
            print("Correct! The song was " + artistAndSong[1] + " by " + artistAndSong[0])
            print("It took you", guesses, "guess(es)!")
            if guesses == 1:
                print ("(+3 points)")
                print("\n")
                score += 3
                break
            elif guesses == 2:
                print ("(+1 point)")
                print("\n")
                score += 1
                break
        else:
            print("That's incorrect, guess again.\n")
            lives = lives-1
        if lives == 0:
          print ("You have no more lives to continue! Your score was:",score)
          time.sleep(3)
          slow_print ("Would you like to play again?")
          playAgain = input("[Y/N]: ")
          if playAgain == ("n") or playAgain == ("N"):
            sys.exit()
          if playAgain == ("Y") or playAgain == ("y"):
            print ("Your last score was",score,", lets see if you can beat it this time...")
            time.sleep(1)
            print ("\n")
            pickSong_random()

I've tried playing around with this concept, but no luck thus far:

import time
countdown=True
time=60
while countdown == True:
    time = time-1
    time.sleep(1.0)
    print (time)
    countdown=True
    if time == 0:
        print ("You've ran out of time!")

UPDATE 1 My projects code has now changed quite a far bit

#Casey_Neale
import sys
import random
import time
import math
import csv
import time, sys
newaccounts=True
loggedIn=False
yn=True

def tutorial(): #Games introduction
  slow_print("Your aim is to get as many points as possible...")
  print("\n")
  time.sleep(1.5)
  slow_print("You need to guess the name of each song to gain points...")
  print("\n")
  time.sleep(1.5)
  slow_print("You have two guesses for each song...")
  print("\n")
  time.sleep(1.5)
  slow_print ("The artist name is provided for you...")
  time.sleep(0.5)
  print("\n")

def slow_print(s):
  for c in s:
    sys.stdout.write( '%s' % c )
    sys.stdout.flush()
    time.sleep(0.03)

def leaderboard():
  print ("\n")
  print ("⬇ Check out the leaderboard ⬇") #LEADERBOARD SECTION
  f = open('H_Highscore.txt', 'r')
  leaderboard = [line.replace('\n','') for line in f.readlines()]
  for i in leaderboard:
      print(i)
  f.close()
  time.sleep(10)
  sys.exit()

def loginsys():
  doublecheck=True
  while doublecheck == True:
    verifyRegister = input ("➡Welcome | Are you a registered user?\n[Y/N]: ")
    print (" ")
    if verifyRegister == "n" or verifyRegister == "N":  #If the user is not already registered
      if newaccounts == True:
        loop=True
        while loop == True:
            username = input ("Please enter a username\n[User]: ")#Prompts the user to provide a desired username
            print (" ")#Prompts for username
            checkusername = input ("Please retype your username\n[Verify]: ")#Verifys username
            print (" ")#Prompts to verify username
            if checkusername != username:
              print ("Invalid, please try again")
              loop=True
            else:
              loop=False       
              time.sleep(0.5)
              passloop=True
              while passloop == True:
                      password = input ("Please enter a password\n[Password]: ") #Prompts the user to provide a desired password
                      print (" ")#Prompts for password
                      checkpassword = input ("Please retype your password\n[Verify]: ") #Verifys password
                      print (" ")#Prompts to verify password
                      if checkpassword != password:
                        print ("Invalid, please try again")
                        print (" ")
                        passloop=True
                      else:
                        passloop=False
                        file = open("C_AccountData.txt","a") #Opens the file C_AccountData.txt in write mode/opens connection
                        file.write("USRN:") #Prefix Username to make the file easier to read
                        file.write(username) #Writes the username 
                        file.write("|") #Partition for visual ease to make the file easier to read
                        file.write("PSWD:") #Prefix Password to make the file easier to read
                        file.write(password)#Writes the password
                        file.write("\n") #New line to make the file easier to read
                        file.close() #Closes file/ends connection
                        print ("✓Your account has been created") #Verifies that the account has been made to the user
                        time.sleep(2)
                        print ("\n")
                        doublecheck=True #Loop

    if verifyRegister == "Y" or verifyRegister == "y":
      loop=True
      if loop == True:
          user = input("[User]: ")
          passw = input("[Password]: ")
          f = open("C_AccountData.txt", "r")
          for line in f.readlines():
            uspwd = line.split("|")
            us = uspwd[0]
            pw = uspwd[1]
            if (user in us) and (passw in pw):
              loop=False
              print("Login successful, welcome",user)
              doublecheck=False
          else:
            if loop == True:
                  print ("\n")
                  print ("Sorry, your account details were not recognised. ")

    else:
      if verifyRegister != "Y" or verifyRegister != "y" or verifyRegister != "N" or verifyRegister != "n" or verifyRegister !="backup":
        print("\n")
        doublecheck=True

def pickSong_random():
  score=0
  lives=5
  songFile = open("F_Songs.txt","r")
  songList = songFile.readlines() #Reads from the bridged file
  songFile.close()
  while True:
    chosenSong = random.choice(songList)

    chosenSong = chosenSong.strip("\n")
    artistAndSong = chosenSong.split(":") #Defines song split

    toDisplay = ""
    toDisplay += artistAndSong[0] + ": "
    songTitleWords = artistAndSong[1].split(" ")

    for word in songTitleWords:
      #loop through
      toDisplay += word[0] + " "
    print(toDisplay)
    #print("2" +toDisplay)
    toDisplay = toDisplay.strip("None")
    guesses = 0
    while guesses <2:
        guesses += 1
        guess = input("[Enter your guess]: ")

        #Guess checking
        if guess.lower() == artistAndSong[1].lower():
            print("✓Correct! The song was " + artistAndSong[1] + " by " + artistAndSong[0])
            print("It took you", guesses, "guess(es)!")
            if guesses == 1:
                print ("\n")
                print ("⬆(+3 points)⬆")
                print("\n")
                score += 3
                break
            elif guesses == 2:
                print ("\n")
                print ("⬆(+1 point)⬆")
                print("\n")
                score += 1
                break
        else:
            print("❌The song name isn't",guess,"\n")
            lives = lives-1
            if guesses == 2:
              print ("Sorry, you couldn't guess the song.")
              print ("\n")
        if lives == 0:
          print ("You have no more lives to continue! Your score was:",score)
          time.sleep(3)
          print("\n")
          slow_print ("Would you like to play again?")
          playAgain = input("\n[Y/N]: ")
          if playAgain == ("n") or playAgain == ("N"):
            print ("\n")
            user = str(input("Enter a name to save your highscore: ")) #user variable is not saved from the login system as it is defined as a function separately
            file = open ("H_Highscore.txt","a")
            file.write(user)
            file.write(",")      
            file.write(str(score)) #(int(x)) can not be written
            file.write("pts")
            file.write("\n")
            file.close()
            time.sleep(0.5)
            leaderboard()
            sys.exit()
          if playAgain == ("Y") or playAgain == ("y"):
            print ("Your last score was",score,", lets see if you can beat it this time...")
            time.sleep(1)
            print ("\n")
            pickSong_random()
loginsys() #LOGIN PROTOCOL
time.sleep(3)
print("\n")
tutorial() #TUTORIAL PROTOCOL
slow_print ("Prepare yourself! The game will begin in...\n")
time.sleep(0.5)
print("\n")
slow_print("5...")
time.sleep(0.5)
print("\n")
slow_print("4...")
time.sleep(0.5)
print("\n")
slow_print ("3...")
time.sleep(0.5)
print("\n")
slow_print ("2...")
time.sleep(0.5)
print("\n")
slow_print ("1...")
time.sleep(0.5)
print("\n")

pickSong_random() #GAME PROTOCOL
sys.exit() #EXIT PROTOCOL

It turns out you were actually reassigning the "time" module to an integer of 60, overwriting the library, which is why it had no attribute ".sleep()". Also the countdown part is irrelevant and a bit redundant. Anyways, this revised bit of code worked for me:

import time
sec=60
while sec != 0:            
    print(sec)
    sec = sec-1
    time.sleep(1)
print ("You've ran out of time!")

Hope this helps!

Simply record the start time, and break from your loop if the time is up. By sleeping you make your program hibernate and the user can not do anything. So "fasteness" does not make any difference because you can't do anything while the program sleeps:

import random 
import datetime
correct = 0
start = datetime.datetime.now()
while True:
    print("Math test. Add , dont screw up, you got {}s left".
          format(20-(datetime.datetime.now()-start).seconds)) 
    a,b = random.choices(range(1,20),k=2)
    c = input("  {:>2} + {:>2} = ".format(a,b))

    if (datetime.datetime.now()-start).seconds > 20:
        print("Times up. Score: {}".format(correct))
        break
    try: 
        if a+b == int(c): 
            correct += 1
            print("Correct")
        else:
            print("Wrong")
    except:
        print("Wrong")

Output:

Math test. Add , dont screw up, you got 20s left
  17 +  8 = 23
Wrong
Math test. Add , dont screw up, you got 18s left
  10 +  2 = 12
Correct
Math test. Add , dont screw up, you got 14s left
   1 +  7 = 8
Correct
Math test. Add , dont screw up, you got 12s left
   5 + 19 = 24
Correct
Math test. Add , dont screw up, you got 8s left
   4 +  3 = 7
Correct
Math test. Add , dont screw up, you got 5s left
   3 + 18 = 21
Correct
Math test. Add , dont screw up, you got 3s left
  15 + 12 = 27
Correct
Math test. Add , dont screw up, you got 1s left
   7 +  8 = 15
Times up. Score: 6 

While Om Agarwal may have a possible solution, you may also want to consider using a non-blocking approach in your game using the built-in pygame time .

start_ticks = pygame.time.get_ticks()
while guesses < 2:
    # OTHER GAME CODE HERE
    seconds = (pygame.time.get_ticks() - start_ticks) / 1000
    if seconds > 60:
        print ("You've ran out of time!")
        break

Cheers!

Edit 1: Added example modification.

import pygame
import time
import random
import sys


def pickSong_random():
    score = 0
    lives = 5
    songFile = open("F_Songs.txt", "r")
    songList = songFile.readlines()  # Reads from the bridged file
    songFile.close()
    while True:
        chosenSong = random.choice(songList)

        chosenSong = chosenSong.strip("\n")
        artistAndSong = chosenSong.split(":")  # Defines song split

        toDisplay = ""
        toDisplay += artistAndSong[0] + ": "
        songTitleWords = artistAndSong[1].split(" ")

        for word in songTitleWords:
            # loop through
            toDisplay += word[0] + " "
        print(toDisplay)
        # print("2" +toDisplay)
        toDisplay = toDisplay.strip("None")
        guesses = 0
        start_ticks = pygame.time.get_ticks()
        while guesses < 2:
            guesses += 1
            guess = input("[Guess]: ")

            seconds = (pygame.time.get_ticks() - start_ticks) / 1000

            if seconds > 60:
                print("You've ran out of time!")
                break

            # Guess checking
            if guess.lower() == artistAndSong[1].lower():
                print("Correct! The song was " + artistAndSong[1] + " by " + artistAndSong[0])
                print("It took you", guesses, "guess(es)!")
                if guesses == 1:
                    print("(+3 points)")
                    print("\n")
                    score += 3
                    break
                elif guesses == 2:
                    print("(+1 point)")
                    print("\n")
                    score += 1
                    break
            else:
                print("That's incorrect, guess again.\n")
                lives = lives - 1
            if lives == 0:
                print("You have no more lives to continue! Your score was:", score)
                time.sleep(3)
                slow_print("Would you like to play again?")
                playAgain = input("[Y/N]: ")
                if playAgain == "n" or playAgain == "N":
                    sys.exit()
                if playAgain == "Y" or playAgain == "y":
                    print("Your last score was", score, ", lets see if you can beat it this time...")
                    time.sleep(1)
                    print("\n")
                    pickSong_random()

Here's how to do it with the threading.Timer() class I suggested in a comment. These can be configured to delay a specified amount of time and the call as function of your choosing.

In the code below I've defined a callback function named timeout() and a global variable named time_ran_out that it sets to True when the timer expires. There's comments in the added code describing what's being done. All the callback function does is set the value of a variable. Other code in the pickSong_random() function checks the value of this variable to determine if the callback function got called or not.

The nice thing about Timer instances (and functions they callback) is that their execution occurs in the background, in parallel with the the main thread which is running the game itself—so using them doesn't impact game's execution or code very much.

Note I also reformatted your code so it follows PEP 8 - Style Guide for Python Code guides so it's a lot more readable (and easier to work on) in my opinion.

import random
import sys
import time
from threading import Timer

TIMELIMIT = 10.0  # Seconds (set low for testing).


def slow_print(s):
    for c in s:
        sys.stdout.write('%s' % c)
        sys.stdout.flush()
        time.sleep(0.03)


def pickSong_random():
    # Local Timer callback function.
    def timeout():
        nonlocal time_ran_out  # Reference variable defined in enclosing scope
                               # (so a local one isn't created automatically).
        time_ran_out = True

    score = 0
    lives = 5
    songFile = open("F_Songs.txt", "r")
    songList = songFile.readlines() # Reads from the bridged file
    songFile.close()

    while True:
        chosenSong = random.choice(songList)
        chosenSong = chosenSong.strip("\n")
        artistAndSong = chosenSong.split(":") # Defines song split

        toDisplay = ""
        toDisplay += artistAndSong[0] + ": "
        songTitleWords = artistAndSong[1].split(" ")

        for word in songTitleWords:
            # loop through
            toDisplay += word[0] + " "
        print(toDisplay)
        # print("2" +toDisplay)
        toDisplay = toDisplay.strip("None")

        guesses = 0
        timer = Timer(TIMELIMIT, timeout)  # Create a timer thread object.
        time_ran_out = False  # Define local variable the callback function modifies.

        timer.start()  # Start the background timer.
        while guesses < 2:
            if time_ran_out:
                print('Times up!')
                break

            guesses += 1
            guess = input("[Enter your guess]: ")

            # Guess checking
            if guess.lower() == artistAndSong[1].lower():
                print("✓Correct! The song was " + artistAndSong[1]
                        + " by " + artistAndSong[0])
                print("It took you", guesses, "guess(es)!")
                if guesses == 1:
                    print("\n")
                    print("↑(+3 points)↑")
                    print("\n")
                    score += 3
                    break
                elif guesses == 2:
                    print("\n")
                    print("↑(+1 point)↑")
                    print("\n")
                    score += 1
                    break
            else:
                print("╳The song name isn't", guess, "\n")
                lives = lives-1
                if guesses == 2:
                    print("Sorry, you couldn't guess the song.")
                    print("\n")
            if lives == 0:
                print("You have no more lives to continue! Your score was:", score)
                time.sleep(3)
                print("\n")
                slow_print("Would you like to play again?")
                playAgain = input("\n[Y/N]: ")
                if playAgain == ("n") or playAgain == ("N"):
                    print("\n")
                    # user variable is not saved from the login system as it is
                    # defined as a function separately
                    user = str(input("Enter a name to save your highscore: "))
                    file = open ("H_Highscore.txt", "a")
                    file.write(user)
                    file.write(",")
                    file.write(str(score)) # (int(x)) can not be written
                    file.write("pts")
                    file.write("\n")
                    file.close()
                    time.sleep(0.5)
                    leaderboard()
                    sys.exit()
                if playAgain == ("Y") or playAgain == ("y"):
                    print("Your last score was", score,", lets see if you can beat it this time...")
                    time.sleep(1)
                    print("\n")
                    pickSong_random()

if __name__ == '__main__':
    pickSong_random()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM