Unable to get out of loops - python-3.x

I'm trying to write a MasterMind game using classes and objects and I'm currently stuck around some of my loops.
while True:
# create a combination
# test the combination
while game_won == False:
print(scoreboard)
# player input combination
# combination is tested then added to scoreboard
tries_left = tries_left+1
if game_won == True:
print(You Won!)
input = Play Again? Y/N
if tries_left == 10:
print(You Lost!)
input = Play Again? Y/N
How do I do to go back to my while True -> create combination from my last if statement? (if tries_left == 10:)

What's wrong
Your first while True doesn't have anything in it, You need to indent code under it if you want it to be inside the loop.
There is a few typos, missing comment characters, and quotation marks.
What needs to happen
When the nested while loop while game_won == True exits, the code will return looping the parent loop while True, which will replay the game, if the user wishes.
Your code fixed (with a few improvements)
Following is how you can loop the game forever (given the user wishes it).
# Assume user wants to play when the program runs
user_wants_to_play = True
ans = ""
# loop the entire game while the user wishes to play
while user_wants_to_play:
# Create the combination
# Test the combination
# Game isn't done when started
game_done = False
tries_left = 10 # Arbitrary number I chose
while not game_done:
# Play the game
print("Scoreboard")
# Subtract one to tries left
tries_left -= 1
if game_done:
print("You won!")
elif tries_left == 0:
print("You lost!")
game_done = True
# if users answer was 'n'
ans = input("Play again? Y/N \n")
if ans.strip().upper() == 'N':
user_wants_to_play = False
Improvements
Boolean logic is more pythonic using not instead of myBool == False
while True: changed to while user_wants_to_play:
User input is scrubbed to ignore white-space and lower case
Changed game_won to game_done
Made tries_left count down instead

Related

Do I need to look for a key down and up event to avoid double occurrence of my else block?

Wondering why its printing my else statement twice in this scenario. In theory it should just execute it once after an incorrect key is read, and loop back.
the out put I am getting after pressing a non 'enter' key How can I avoid this?
import random
import keyboard
#Constant values to assign as a win or loss
_WIN = 1
_LOSE = 0
#Create and store game hand choices
handChoice = ['Spock', 'Lizard', 'Rock', 'Paper', 'Scissors']
print('\nThis is advanced Rock, Paper, Scissors! Press ENTER to start the automated game->')
while True:
if keyboard.read_key() == 'enter':
break
else:
print('Please press ENTER!')
#Hand choices randomly assigned to player 1
player1 = random.choice(handChoice)
print('Player 1 uses ' + player1 + '!\n')
Looking true the docs you could use this:
keyboard.wait('enter')
It will also use less cpu. But you would need the async library with timeout to also give output.
you could also use this:
while True:
if keyboard.read_key() == 'enter':
break
elif event.event_type == keyboard.KEY_DOWN:
print('Please press ENTER!')

Python 3 How to Ask user for specific input and reject invalid inputs

I have a question on how to check a user's input and make sure they are returning a specific string. Currently, the function when called will ask the user for their input. However, if they choose a string that is not part of the function, the else statement will execute and continue the code. I am trying to figure out how to loop this function, until a user inputs one of the strings that the function is looking for. Can anyone help me with this? I am new to python and would appreciate any help.
def dwarf_class_definer(dwarf_class):
if dwarf_class == "Thane":
print("'Ahhh Nobility'")
elif dwarf_class == "Mekanik":
print("'Interesting a Mechanic'")
elif dwarf_class == "Ancestrite":
print("'A spiritualist. I see...'")
elif dwarf_class == "Prisoner":
print("'Never met a gen-u-ine 'Last chancer.'")
elif dwarf_class == "Civilian":
print("'ehhh a civilian? Wut you doing here?'")
else:
print("You aren't choosing a valid class.")
dwarf_class = input("Which Class will you choose?: ")
dwarf_class_definer(dwarf_class)
A while loop will keep going until you tell it not to anymore. You can see when an expected value is supplied, the break command will terminate the while loop. A dictionary can also make your code a lot cleaner and easier to maintain compared to a bunch of if statements.
dwarf_classes = {
"Thane": "'Ahhh Nobility'",
"Mekanik": "'Interesting a Mechanic'",
"Ancestrite": "'A spiritualist. I see...'",
"Prisoner": "'Never met a gen-u-ine 'Last chancer.'",
"Civilian": "'ehhh a civilian? Wut you doing here?'",
}
while True:
dwarf_class = input("Which Class will you choose?: ")
if dwarf_class in dwarf_classes.keys():
print(dwarf_classes[dwarf_class])
break
print("You aren't choosing a valid class.")
example:
$ python3 so.py
Which Class will you choose?: Python!
You aren't choosing a valid class.
Which Class will you choose?: Prisoner
'Never met a gen-u-ine 'Last chancer.'

Pygame- Keys held down : some caracters are written more than once when pressing a key

I'm trying to make an input box.
So we can type something in it.
The first problem I get was when we try to keep a key held for a while, it is repeated only once.
Now this was resolved with the help of the answers done on this link : Pygame key hold down?
However, the problem encountered now, is that when we try to press a key only once, sometimes it is repeated more than once (twice or more commonly).
The pseudo-code looks like this:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
self.quit_screen = True
# events related to the input box
if event.type == pygame.MOUSEBUTTONDOWN:
#Things related to it
#Disactivate the typing on the input box if KEYUP activated
if event.type == pygame.KEYUP:
self.typing = False
self.backspace_pressed = False
if event.type == pygame.KEYDOWN:
print("KEYDOWN\n")
if self.user_input_box.input_box_active:
# If we press 'enter', we save
if event.key == pygame.K_RETURN:
#save the text in some variables
# If we press the key '\b' (backspace), we delete a caracter
elif event.key == pygame.K_BACKSPACE:
self.backspace_pressed = True
else: #Get the current letter
self.typing = True
self.cur_letter = event.unicode
if self.typing: #Adding the letter saved in cur_letter to the current text(user_entry)
self.user_input.user_entry += self.cur_letter
if self.backspace_pressed:
self.user_input.user_entry = self.user_input.user_entry[:-1]
You could make a delay to differentiate between pressing once and holding down. You can define some variables like this:
self.press_timer = 0
self.already_pressed = False
and then, in the key code you can continue to add on this number until it reaches a certain threshold. So...
if event.type == pygame.KEYDOWN:
self.press_timer += 1
if press_timer < 50 and not self.already_pressed:
# Typing code
self.already_pressed = True
elif press_timer > 50 and self.already_pressed:
# Same code, but without setting already_pressed to True
Then, in the pygame.KEYUP code...
if event.type == pygame.KEYUP:
self.typing = False
self.backspace_pressed = False
self.press_timer = 0
self.already_pressed = False
This should allow the leeway to press one key, and then after holding it for a set amount of time, allow the letters to be added endlessly.
If you want to get key repeats what you are doing is not really the right way to go about it. It is preferable to have the system send you multiple events when it has sensed that a key has been held down. You can get the system to send you repeated KEYDOWN events for a held down key by setting this before you start the event checking loop:
pygame.key.set_repeat(delay, interval)
You can see more here in the docs
It is turned off by default so you have to enable it.
With respect your current code and why it is repeating when you do nor want it to, you are running the lines:
if self.typing: #Adding the letter saved in cur_letter to the current text(user_entry)
self.user_input.user_entry += self.cur_letter
every pass through the event loop, which means that anything event will cause you to execute it. There may events that come through that you may not be expecting. Some like mouse movement events but also other behind the scenes ones you may not realize can occur. You can see what those events are by adding this line at the top of your loop for debugging:
print(f"event: {pygame.event.event_name(event.type)}")

defining a function in python 3

the moment you guess the correct number, it freezes and doesn't proceed further, however if I don't define the function do_guess_round and instead simply write the code after the second while True statement it works perfectly. I guess I am incorrectly defining the function
import random
computers_number = random.randint(1,100)
prompt=('what is your guess? ')
def do_guess_round():
"""choose a random number, prompt the user to guess it
check whether the user is true,
and repeat the pocess untill the user is correct"""
while True:
players_guess=input (prompt)
if computers_number == int(players_guess):
print ('correct! well done')
break
elif computers_number<int(players_guess):
print ("incorrect, your guess is higher")
else:
print ('incorrect, your guess is lower')
print ("Starting a new round ")
print ("let the guessing game begin")
while True:
do_guess_round()
Current your do_guess_round() function does not do anything. You need to indent the code that is supposed to be contained in it. The while True beneath it is not indented, so the body of the function currently only consists of the string:
"""choose a random number, prompt the user to guess it
check whether the user is true,
and repeat the pocess untill the user is correct"""
At the moment you guess the correct number, your code collapses to
def do_guess_round():
while True:
break
while True:
do_guess_round()
No surprise it freezes, you haven't built any way for it to quit - break only leaves one level of loop. Presumably you're going to move the code to generate numbers into the function? You need something more like
def do_guess_round():
# read player guess here
if guess matches:
return True
else:
return False
result = False
while result != True:
result = do_guess_round()
def do_guess_round():
"""choose a random number, prompt the user to guess it
check whether the user is true,
and repeat the pocess untill the user is correct"""
while True:
The "while True" loop isn't indented, so it isn't in the function, indent the loop an it's contents, then you should be fine.

Text Game - if text input isnot "Var1" or "Var2" then - Python 3

This question references info from my previous question:
Text Game - If statement based of input text - Python
So, now I have this:
#Choice Number1
def introchoice():
print()
print("Do you 'Hesitate? or do you 'Walk forward")
print()
def Hesitate():
print()
print("You hesistate, startled by the sudden illumination of the room. Focusing on the old man who has his back turned to you. He gestures for you to come closer. \n ''Come in, Come in, don't be frightened. I'm but a frail old man'' he says.")
print()
#
def Walk():
print()
print("DEFAULT")
print()
#
def pick():
while True:
Input = input("")
if Input == "Hesitate":
Hesitate()
break
if Input == "Walk":
Walk()
break
#
#
pick()
#-#-#-#-#-#-#-#-#-#-#-#-#
#Clean-up
#-#-#-#-#-#-#-#-#-#-#-#-#
Now what I want to do is this;
def pick():
while True:
Input = input("")
if Input == "Hesitate":
Hesitate()
break
if Input == "Walk":
Walk()
break
if Input is not "Walk" or "Hesitate":
print("INVALID")
break
#
#
pick()
#-#-#-#-#-#-#-#-#-#-#-#-#
#Clean-up
#-#-#-#-#-#-#-#-#-#-#-#-#
Now that I have the game determine specific text inputs, I want it to be able to detect if the input was not one of the choices. That way, as typed in the above code, If the input text is not either "Walk" or "hesitate", print Text "INVALID"
How would I do this exactly?
I guess you want to still receiving input if it is "invalid", so the break statements have to be inside the ifs. Otherwise, the loop will only iterate one time.
Also, I would recommend you to use a if-elif-else structure so your code looks more organized.
You can't use is or is not in this case, because these operators are used to check if the objects are the same (same reference). Use the operators == and != to check for equality.
while True:
my_input = input("> ")
if my_input == "Hesitate":
hesitate()
break
elif my_input == "Walk":
walk()
break
else:
print("INVALID")
Notes:
I would recommend you to follow Python naming conventions. Names of variables and methods should start in lowercase.

Resources