I asked how to make a cooldown before, but I am still somewhat of a beginner in Python. Could someone suggest a way to make a cooldown with an example? What I mean by a cooldown is so somebody could still use a command with something else still charging. An example is this:
while True:
dummy=300
standopt=input("Choose between TWHV and SP (DUMMY MECHANIC UNFINISHED FOR SP).\nIf you already chose a Stand, you're choosing again due to the dummy's hospitalisation.")
if standopt=="TWHV" or standopt=="twhv" or standopt=="Twhv":
while True:
if dummy>=1:
Action = str(input("Your Stand awaits instructions...(e, r)"))
if Action=="e" or Action=="E":
print("Barrage (28)")
dummy=dummy-28
print("Your dummy is now on",dummy,"HP.")
elif Action=="r" or Action=="R":
print("Heavy Punch (30)")
dummy=dummy-30
print("Your dummy is now on",dummy,"HP.")
What I want is for the code to keep running, but have a simple way of putting one of the commands on a timer before it runs out and is able to be used again, while in the meantime, other moves could be used.
First, I set up two functions to update the cooldown time and to check if the action is available for use. We will use a dictionary to store the available time of every action.
import time
cooldown = {}
def update(action, cool):
cooldown.update({action: time.time() + cool})
def validate(action):
return cooldown.get(action, 0) - time.time() <= 0
You can learn more about the dict.get and dict.update method.
Implementation
We will try it out on the punch function.
def punch():
if validate("punch"):
print("Heavy Punch.")
update("punch", cool=5)
else:
print("Cooling down.")
Demonstration
Let's do two simultaneous punches, wait for six seconds, and then punch again. The first two punches are done simultaneously so it does not allow you to punch the second time. However, after you wait for six seconds, the punch ability is already cooled down (the cooldown time is five seconds).
punch()
punch()
time.sleep(6)
punch()
It gives the following result.
Heavy Punch.
Cooling down.
Heavy Punch.
The complete code
To apply it to your use case, you can do the following.
cooldown = {}
def update(action, cool):
cooldown.update({action: time.time() + cool})
def validate(action):
return cooldown.get(action, 0) - time.time() <= 0
while True:
dummy = 300
standopt = input("Choose between TWHV and SP (DUMMY MECHANIC"
"UNFINISHED FOR SP).\nIf you already chose a Stand, you're"
"choosing again due to the dummy's hospitalisation.")
if standopt.lower() == "twhv":
while True:
if dummy >= 1:
action = str(input("Your Stand awaits instructions...(e, r)"))
if validate(action):
if action.lower() == "e":
print("Barrage (28)")
dummy -= 28
print("Your dummy is now on", dummy, "HP.")
elif action.lower() == "r":
print("Heavy Punch (30)")
dummy -= 30
print("Your dummy is now on", dummy, "HP.")
update(action, cool=5)
else:
print("Cooling down.")
Related
I want to make it so that after a certain time (depending on the difficulty that the user has chosen) the program continues with the code and the user can no longer enter anything.
This is what I have so far:
t = Timer(
getTime(),
print,
("Calculating...",)
)
t.start()
answer = input()
t.cancel()
This is the getTime function:
def getTime():
if difficulty == "easy":
time = 1
elif difficulty == "intermediate":
time = 0.75
elif difficulty == "hard":
time = 0.5
return time
What happens currently is that the thread ends and prints out "Calculating..." but the user is still allowed to input.
Thank you.
My task is to create a program, which will turn heater on if temperature in the house is less than 16°C or turning it off if it's more than 16°C. I decided to make it a bit useful and import the timer. I want to know how is it possible to repeat function, which allows to turn heater on or off, after "n" time inputted by user.
My current code is:
import time
import random
def main():
temp = random.randint(-15, 35)
print("Current temperature in the house:", temp,"°C")
time.sleep(1)
if temp <= 16:
print("It's cold in the house!")
t = input("How long should the heating work? Enter time in 1.00 (hours.minutes) format:")
print("Heating will work for:", t)
print("House Heating status: ON")
time.sleep() //The timer should start here for the time entered by the user
if temp > 16 and temp <= 25:
print("House Heating status: OFF")
if temp => 26:
print("House Cooler status: ON")
main()
Which technique should I use to add this timer?
Assuming your main function handles the call to time.sleep already, a simple way to repeat over and over would be to put your function in an infinite loop:
while True:
main()
Another way would be to have your main function return an integer of how long to wait until it should be called again. This decouples the waiting from the main logic.
def main():
...
t = input("How long should the heating work? Enter time in 1.00 (hours.minutes) format:")
...
return int(t)
while True:
wait_time = main()
time.sleep(wait_time)
So I would like to run two programs, a timer and a math question. But always the input seems to be stopping the timer funtion or not even run at all. Is there any ways for it to get around that?
I'll keep the example simple.
import time
start_time = time.time()
timer=0
correct = answer
answer = input("9 + 9 = ")
#technically a math question here
#so here until i enter the input prevents computer reading the code
while True:
timer = time.time() - start_time
if timer > 3:
#3 seconds is the limit
print('Wrong!')
quit()
So recap i would like the player to answer the question in less than 3 seconds.
after the 3 seconds the game will print wrong and exit
if the player answer within three seconds the timer would be 'terminated' or stopped before it triggers 'wrong' and quit
hope you understand, and really appreciate your help
On Windows you can use the msvcrt module's kbhit and getch functions (I modernized this code example a little bit):
import sys
import time
import msvcrt
def read_input(caption, timeout=5):
start_time = time.time()
print(caption)
inpt = ''
while True:
if msvcrt.kbhit(): # Check if a key press is waiting.
# Check which key was pressed and turn it into a unicode string.
char = msvcrt.getche().decode(encoding='utf-8')
# If enter was pressed, return the inpt.
if char in ('\n', '\r'): # enter key
return inpt
# If another key was pressed, concatenate with previous chars.
elif char >= ' ': # Keys greater or equal to space key.
inpt += char
# If time is up, return the inpt.
if time.time()-start_time > timeout:
print('\nTime is up.')
return inpt
# and some examples of usage
ans = read_input('Please type a name', timeout=4)
print('The name is {}'.format(ans))
ans = read_input('Please enter a number', timeout=3)
print('The number is {}'.format(ans))
I'm not sure what exactly you have to do on other operating systems (research termios, tty, select).
Another possibility would be the curses module which has a getch function as well and you can set it to nodelay(1) (non-blocking), but for Windows you first have to download curses from Christopher Gohlke's website.
import time
import curses
def main(stdscr):
curses.noecho() # Now curses doesn't display the pressed key anymore.
stdscr.nodelay(1) # Makes the `getch` method non-blocking.
stdscr.scrollok(True) # When bottom of screen is reached scroll the window.
# We use `addstr` instead of `print`.
stdscr.addstr('Press "q" to exit...\n')
# Tuples of question and answer.
question_list = [('4 + 5 = ', '9'), ('7 - 4 = ', '3')]
question_index = 0
# Unpack the first question-answer tuple.
question, correct_answer = question_list[question_index]
stdscr.addstr(question) # Display the question.
answer = '' # Here we store the current answer of the user.
# A set of numbers to check if the user has entered a number.
# We have to convert the number strings to ordinals, because
# that's what `getch` returns.
numbers = {ord(str(n)) for n in range(10)}
start_time = time.time() # Start the timer.
while True:
timer = time.time() - start_time
inpt = stdscr.getch() # Here we get the pressed key.
if inpt == ord('q'): # 'q' quits the game.
break
if inpt in numbers:
answer += chr(inpt)
stdscr.addstr(chr(inpt), curses.A_BOLD)
if inpt in (ord('\n'), ord('\r')): # Enter pressed.
if answer == correct_answer:
stdscr.addstr('\nCorrect\n', curses.A_BOLD)
else:
stdscr.addstr('\nWrong\n', curses.A_BOLD)
if timer > 3:
stdscr.addstr('\nToo late. Next question.\n')
if timer > 3 or inpt in (ord('\n'), ord('\r')):
# Time is up or enter was pressed; reset and show next question.
answer = ''
start_time = time.time() # Reset the timer.
question_index += 1
# Keep question index in the correct range.
question_index %= len(question_list)
question, correct_answer = question_list[question_index]
stdscr.addstr(question)
# We use wrapper to start the program.
# It handles exceptions and resets the terminal after the game.
curses.wrapper(main)
Use time.time(), it returns the epoch time (that is, the number of seconds since January 1, 1970 UNIX Time). You can compare it to a start time to get the number of seconds:
start = time.time()
while time.time() - start < 60:
# stuff
You can have a timer pull you out of your code at any point (even if the user is inputting info) with signals but it is a little more complicated. One way is to use the signal library:
import signal
def timeout_handler(signal, frame):
raise Exception('Time is up!')
signal.signal(signal.SIGALRM, timeout_handler)
This defines a function that raises an exception and is called when the timeout occurs. Now you can put your while loop in a try catch block and set the timer:
signal.alarm.timeout(60)
try:
while lives > 0
# stuff
except:
# print score
I'm trying to make a little text based game, but I am having trouble with a while loop. I have experimented for many hours now! I would much appreciate it if you could kindly help me out. Thank-you for reading :D
I basically want it so that the user has to press a button before the timer runs out, and if he doesn't do it in time then the bear eats him. :')
Here is my code:
import time
cash = 0
def dead():
print("You are dead!")
main()
points = 0
def adventure_1(inventory, cash):
points = 0
time1 = 2
if time1 < 3:
time.sleep(1)
time1 -= 1
bear = input("A bear is near... Hide Quickly! Enter: (C) to CLIMB a Tree")
#Ran out of time death
if time1 == 0:
dead()
#Climb away from bear
elif bear == 'c' or 'C':
print("Your safe from the bear")
points += 1
print("You recieved +2 points")#Recieve points
print("You now have : ",points,"points")
adventure_2()#continue to adventure 2
#Invalid input death
elif bear != 's' or 'S':
dead()
def adventure_2(inventory, cash):
points = 2
time = 5
In python the input statement makes it so the programs flow waits until the player has entered a value.
if time1 < 3:
time.sleep(1)
time1 -= 1
#line below causes the error
bear = input("A bear is near... Hide Quickly! Enter: (C) to CLIMB a Tree")
To over come this you can use something similar to the code below which is a working example. We can over come the break in the program flow by using a Timer to see if the player has inputted anything, if he has not we catch the exception and continue with the programs flow.
from threading import Timer
def input_with_timeout(x):
t = Timer(x,time_up) # x is amount of time in seconds
t.start()
try:
answer = input("enter answer : ")
except Exception:
print 'pass\n'
answer = None
if answer != True:
t.cancel()
def time_up():
print 'time up...'
input_with_timeout(5)
So as you can see we can over come the issue of waiting for our player to input a value by using a timer to count how long the player is taking, then proceeding to catch the exception from no input being sent, and finally, continuing with our program.
t_0 = time.time()
bear = input("A bear is near... Hide Quickly! Enter: (C) to CLIMB a Tree")
if abs(t_0 - time.time()) > time_threshold:
#player has died
I am trying to make a text based game in which the user is a pilot in space. I want to create a movement system but am unsure how to do it. I want the user to be able to put in the desired grid coordinates, and his vehicle will begin to change its grid coords to get closer and closer to the ones he inputted.
Now, to do this I will probably need multithreading and a time element. But I am unsure how I can use a time element. Any advice is greatly appreciate, i'm just trying to learn here. Thanks guys!
from Gundam2 import Mobilesuits
#Main Variable/Object declarations:
Leo1=Mobilesuits(100,100,"Leo","leo desc","dockpit desc",100,[100,100,100])
Leo2=Mobilesuits(100,100,"Leo","leo desc","dockpit desc",100,[300,100,100])
Leo3=Mobilesuits(100,100,"Leo","leo desc","dockpit desc",100,[100,150,100])
currentmobilesuit=Leo1
#Main Function declarations
def commands(user_input,currentmobilesuit):
if user_input == "radar":
currentmobilesuit.radar()
elif user_input == "commands":
print("Command list:\nradar")
else:
print("Invalid command\nType 'commands' for a list of valid commands")
#Main execution
while True:
commands(raw_input(),currentmobilesuit)
class Mobilesuits:
#class global variables/methods here
instances = [] #grid cords here
def __init__(self,armor,speed,name,description,cockpit_description,\
radar_range, coordinates):
Mobilesuits.instances.append(self)
self.armor=armor
self.speed=speed
self.name=name
self.description=description
self.cockpit_description=cockpit_description
self.radar_range=radar_range
self.coordinates=coordinates
def can_detect(self, other):
for own_coord, other_coord in zip(self.coordinates, other.coordinates):
if abs(own_coord - other_coord) > self.radar_range:
return False
return True
def radar(self):
for other in Mobilesuits.instances:
if other is not self and self.can_detect(other):
print "%s detected at %s" % (other.description, other.coordinates)
Games typically have a "master loop" of some kind; yours does here:
#Main execution
while True:
commands(raw_input(),currentmobilesuit)
The simplest thing to do is to count in the loop:
#Main execution
turn_count = 0
while True:
commands(raw_input(),currentmobilesuit)
turn_count += 1
If you wanted the real time taken to have some impact on the counter, or be the counter, you can get the current time from the time module calling time.time().
#Main execution
import time
time_start = time.time()
time_elapsed = 0
while True:
commands(raw_input(),currentmobilesuit)
time_elapsed = time.time() - time_start
A couple other thoughts:
Make a Game class, and put the turn counter and game loop in that.
Have the commands function return a number that is the number of time units that took place during the command; for example, entering an invalid command might take 0 turns, while repairing a robot might take 5.
#Main execution
turn_count = 0
while True:
turns_taken = commands(raw_input(),currentmobilesuit)
turn_count += turns_taken
You can use non-blocking I/O. This will help you avoid the complications of threading. Here's your sample code implemented with a non-blocking read of stdin:
#!/usr/bin/python
import sys
import select
call_count = 0
#Main Function declarations
def commands(user_input):
global call_count
if len(user_input) > 0:
print('call count: ' + str(call_count) + ' user entered: ' + user_input)
def raw_input_no_block():
global call_count
call_count = call_count + 1
input_avail = select.select([sys.stdin], [], [], 0.1)[0] #wait for 0.1 seconds
if input_avail:
return sys.stdin.readline()
else:
return ''
#Main execution
while True:
commands(raw_input_no_block())