Python 3 Game Bug: Holding down the enter key - python

I have another question related to this game, here it is:
https://stackoverflow.com/questions/28545444/python-3-game-bug-message-repeating
I made a game thats a knock off of Cookie Clicker (just for coding practice!). And I ran into a problem where the user can hold down the enter key, and get coins really fast. I'd like to prevent that. here is my code:
coin = 0
keepgoing = True
while keepgoing == True:
print('You have ' + str(coin) + ' cmd-coins' )
response = input('Press enter to get a coin!')
if response == 'q':
keepgoing = False
print('Thanks for playing!')
coin = coin + 1

I wrote a rather "gimmicky" solution to your problem, which works to an extent but definitely isn't flawless. Based on your compiler you may have to change the conditional value for start-end such that it is a value which allows you to static press as fast as humanly possible without breaking but not allow the user to hold the enter key. For me in WingIde, 0.03 is the optimal value.
Were you to import a module such as Pygame you would find this sort of game much easier to make.
import time
coins = 0
keepgoing = True
end = -1
while keepgoing:
print('You have ' + str(coins) + ' cmd-coins' )
response = input('Press enter to get a coin!')
start = time.time()
if start-end < 0.03:
print ("Don't hold down the Enter key you cheater!")
keepgoing = False
if response == 'q':
print('Thanks for Playing!')
keepgoing = False
coins = coins + 1
end = time.time()
NOTE: This solution is for Python 3, for < Python 3 you'll have to substitute raw_input() for input(). Also, I wouldn't advise trying to use it on an online compiler.

G Force dog,
You could change your game a bit by making a few changes till someone or I figure out a good solution(Mom gave orders to go to bed). Till we don't find a solution, use this code which isn't exactly a solution.
coins = 0
real = 0
while real == 0:
if True:
print('You have ' + str(coins) + ' cmd-coins' )
response = input('Press c to get a coin, then press ENTER!')
if response == 'c' or response == 'C':
coins = coins + 1
if response == 'q':
print('Thanks for playing!')
real = 1
And 2 things:-
Nice answer Yeniaul! Good try!
Elizion, nice try but your method isn't working. But it is a good idea.
I have used time too, but it seems that when one presses ENTER key for a long time, it just comes out on the screen all together.
I think I do have somewhat of an idea forming... if we make another while loop, after importing 'time', with a condition which makes the loop active every 2 seconds by assigning a variable 'time.clock()' and when its value is a multiple of 2, it activates!
Got it? I know what to do, but can't seem to put it in code. See if you can, reader(especially Elizion and Yeniaul)

Try using time.sleep(seconds of delay) for slowdown
So you could do
coin = 0
keepgoing = True
while keepgoing == True:
time.sleep(0.25)
print('You have ' + str(coin) + ' cmd-coins' )
response = input('Press enter to get a coin!')
if response == 'q':
keepgoing = False
print('Thanks for playing!')
coin = coin + 1
This would make it a quarter-second delay before they could get another coin.

Related

How do I Run a Background Timer for Each Prompt in My Word Game?

I'm making an unoriginal game for a first project that just runs in my python terminal. The user is randomly given a set of 2-3 letters and the user has to come up with a real word (checked by the Webster dictionary) that contains the given set of letters within 5 seconds. For example, if the game generates "le" the user can input "elephant" within 5 seconds as a correct word and gives them a point.
The problem is that I can't seem to implement the 5 second timer function to run in the back for every time a prompt is given without messing up some other part or running into another problem. I've looked into threading and can't seem to make use of it.
Here is the code for the main game:
from letters import letter_sets_list
fhand = open("words_dictionary.json")
data = fhand.read()
global score
score = int(0)
game_over = False
while game_over is False:
import random
random_letters = random.choice(letter_sets_list)
print('Word that contains:', random_letters)
answer = input("Type a word:")
if answer in data and random_letters in answer:
score += 1
print("nice one")
else:
game_over = True
print("Game Over \n Score:", score)
fhand.close()
exit()
Here is the timer function I found off YouTube and tried to implement:
def countdown():
global my_timer
my_timer = int(5)
for x in range(5):
my_timer -= 1
sleep(1)
countdown_thread = threading.Thread(target=countdown)
countdown_thread.start()
Take a look at that. Especially check if that will work for you:
import time
from threading import Thread
answer = None
def check():
time.sleep(2)
if answer != None:
return
print("Too Slow")
Thread(target = check).start()
answer = input("Input something: ")
Edit: I tried to implement code from my previous answer to your code but with a little different approach:
import time, threading
#from letters import letter_sets_list
#import random
#fhand = open("words_dictionary.json")
#data = fhand.read()
data = ["answer"]
answer = [None]
random_letters = [None]
global score
score = int(0)
game_over = False
x = 0
def game(answer, random_letters):
#random_letters = random.choice(letter_sets_list)
print('Word that contains:', random_letters)
while True:
answer[0] = input("Type a word: ")
mythread = threading.Thread(target=game, args=(answer, random_letters))
mythread.daemon = True
mythread.start()
for increment in range(5):
time.sleep(1)
if answer[0] in data: # and random_letters in answer
score += 1
print("Good answer")
x = 1
break
if x != 1:
print("\nTime is up")
else:
x = 0
game_over = True
In this approach I didnt use time.sleep() inside threaded function but outside of it which helps with killing it. Also i assumed that if your answer is incorrect you would like to have another chance to answer untill time is up or answer is correct so I just used while loop in threaded function. The code is quite simple so I think if you spend a little time analysing your parts of the code you will figure it out.
Some parts of the code I didn't use as I dont have access to your json files ect., but if I understand correctly what you're trying to do, it shoud work. Also check how will behave your kernel. In my case sometimes it shows some problems but my PC is not the best and so it might be only problem with RAM or other part of my computer as it happens quite often with my projects.

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

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.
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")

keep tracking time in while loop and interacting with other commands in python3

So i created a while loop that the user input and an output is returned
choice = input()
while True:
if choice == "Mark":
print("Zuckerberg")
elif choice == "Sundar":
print("Pichai")
and i want to keep time so when i hit Facebook is going to keep time for FB and when i type Google is going to keep time for google like this
import time
choice = input()
while True:
if choice == "Facebook":
endb = time.time()
starta = time.time()
if choice == "google":
enda = time.time()
startb = time.time()
if choice == "Mark":
print("Zuckerberg")
elif choice == "Sundar":
print("Pichai")
if i make this like above when i get to print the elapsed time is going to print
the same number but is going to be minus instead of plus, and vice versa
elapseda = enda - starta
elapsedb = endb - startb
print(elapseda)
print(elapsedb)
How do i keep track of the time but be able to interact with my other input/outputs?
Thanks
##############################################################################
Edit: Sorry for making it not clear. What i meant by tracking time it that instead of print an output when you type a keyword is going to track time. This will be used to take the possession time of a sport match but meanwhile count other stats like Penalty Kicks and stuff. I cant post my code due to character limit but here is an idea:
while True:
choice = input()
if choice == "pk":
print("pk")
elif choice == "fk":
print("fk")
elif choice == "q":
break
and in there i should put possession time but meanwhile i want to interact with the others
In the while loop you could count seconds like so.
import time
a = 0
while True:
a = a + 1
time.sleep(1)
That would mean that a is about how many seconds it look to do the while loop.

How to make while loop keep going while still looking for input in Python

I am making a Cookie clicker like game in Python, and I am trying to have the while loop keep going so it checks if a second has gone (so it adds "cookies") while still looking if the user is making an input (clicking on "Cookie").
Whenever I try this it waits for the input instead of doing the rest of the loop.
This is what my current code looks like (There's more of course):
While True:
console.clear()
cookieText = "You have " + str(cookies) + " cookies"
print cookieText
clicker = raw_input("")
if clicker == "":
cookies += clickerPower
more...
This is what I want to add:
While True:
last = time()
if last == timer:
timer = last
more...
this worked for me (source)
import msvcrt
num = 0
done = False
while not done:
print num
num += 1
if msvcrt.kbhit():
print msvcrt.getch()
done = True
The answer is threading. But it's not simple.

Python custom modules - error with example code

I am reading the book "Python Programming for the Absolute Beginner (3rd edition)". I am in the chapter introducing custom modules and I believe this may be an error in the coding in the book, because I have checked it 5 or 6 times and matched it exactly.
First we have a custom module games.py
class Player(object):
""" A player for a game. """
def __init__(self, name, score = 0):
self.name = name
self.score = score
def __str__(self):
rep = self.name + ":\t" + str(self.score)
return rep
def ask_yes_no(question):
""" Ask a yes or no question. """
response = None
while response not in ("y", "n"):
response = input(question).lower()
return response
def ask_number(question, low, high):
""" Ask for a number within a range """
response = None
while response not in range (low, high):
response = int(input(question))
return response
if __name__ == "__main__":
print("You ran this module directly (and did not 'import' it).")
input("\n\nPress the enter key to exit.")
And now the SimpleGame.py
import games, random
print("Welcome to the world's simplest game!\n")
again = None
while again != "n":
players = []
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
name = input("Player name: ")
score = random.randrange(100) + 1
player = games.Player(name, score)
players.append(player)
print("\nHere are the game results:")
for player in players:
print(player)
again = games.ask_yes_no("\nDo you want to play again? (y/n): ")
input("\n\nPress the enter key to exit.")
So this is exactly how the code appears in the book. When I run the program I get the error IndentationError at for i in range(num):. I expected this would happen so I changed it and removed 1 tab or 4 spaces in front of each line from for i in range(num) to again = games.ask_yes_no("\nDo you want to play again? (y/n): ").
After this the output is "Welcome to the world's simplest game!" and that's it.
I was wondering if someone could let me know why this is happening?
Also, the import games module, is recognized in Eclipse after I added the path to PYTHONPATH.
I actually have this book myself. And yes, it is a typo. Here is how to fix it:
# SimpleGame.py
import games, random
print("Welcome to the world's simplest game!\n")
again = None
while again != "n":
players = []
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
name = input("Player name: ")
score = random.randrange(100) + 1
player = games.Player(name, score)
players.append(player)
print("\nHere are the game results:")
for player in players:
print(player)
again = games.ask_yes_no("\nDo you want to play again? (y/n): ")
input("\n\nPress the enter key to exit.")
All I did was indent num 4 spaces and lined it up with the first for-loop.
You have an infinite loop here:
again = None
while again != "n":
players = []
If this is exactly the way it's printed in the book, the book does have an error.
You've got these two lines:
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
The second one is more indented than the first. That's only legal if the first one is a block-introducer like a for or while or if. Since it's not, this is an IndentationError. And that's exactly what Python is telling you.
(It's possible that you've copied things wrong. It's also possible that you're mixing tabs and spaces, so it actually looks right in your editor, but it looks wrong to Python. But if neither of those is true, the book is wrong.)
So, you attempted to fix it by dedenting everything from that for loop on.
But when you do that, only one line is still left under the while loop:
while again != "n":
players = []
There's nothing that can possibly change again to "n", so this will just spin forever, doing nothing, and not moving on to the rest of the program.
So, what you probably want to do is to indent the num = … line to the same level as the for i… line, so both of them (and all the stuff after) ends up inside the while loop.

Categories