Trouble with a playerhealth function - python

So I'm making a little python game in class.
Anyways, I have this as a function:
def checkplayerhealth (playerhealth):
while playerhealth < 1000:
if playerhealth < 0:
input ("Looks like you died. Better luck next time! Press any key to exit")
sys.exit()
Whenever I call it, the game stops. Obviously this is because I need to find a way to run the loop, or at least be constantly checking playerhealth and let the rest of the game continue running.
Is there a way to do this?

The statements
while playerhealth < 1000:
if playerhealth < 0:
will put you in an infinite loop if the function was called with anything greater than or equal to 0 and less than 1000. If you want to break that loop, you need code that changes the value of playerhealth in the loop to something that is less than 0 or equal to or greater than 1000.
Perhaps, you meant the function to be:
def checkplayerhealth (playerhealth):
if playerhealth < 0:
input ("Looks like you died. Better luck next time! Press any key to exit")
sys.exit()

Related

How do I fix my (supposedly while-loop or if-statement) dice-simulator in Python so it prints the amount of tries its taken before landing on a 6?

So, I'm a little stuck on a coding assignment of mine – I'm supposed to write a code in Python simulating the throw of a dice, in which the program randomizes numbers between 1-6 until it "lands" on the number 6; the program is furthermore supposed to count the number of tries it has "thrown the dice" before "landing" on a 6, and print out print("It took", n, "tries to get a six.") in which n = the number of tries it has thrown the dice before landing on a 6.
This is what I've come up with thus far:
import random
dice = random.randint(1,6)
n = 0
while dice == 6:
n = n + 1
print("It took", n, "tries to get a 6.")
break
But, alas, it only prints out "It took 1 try to get a 6." in the result window and shows blank in the result window whenever the "dice" doesn't land on a 6. I guess what my question is, is: how do I get it to count all the tries before landing on a 6, and subsequently print the said amount of tries in combination with the statement print("It took", n, "amount of tries to get a 6.")?
The usual pattern for repeating an action an unknown number of times is to use a while True loop, and then break out of the loop when the exit condition is satisfied.
rolls = 0
while True:
die = random.randint(1, 6)
rolls += 1
if die == 6:
break
print("It took", rolls, "tries to get a 6.")
You need to write your break command into an if-statement.
In your current code it breaks within the first iteration.
As this is an assigment i dont want to tell you everything.
But that while loop condition won't get you there.
Try writing a blank while loop with a break-condition, think about it.

Why does my while loop end before the final message is printed? Is it my code or...?

I made a guessing game where the player has 10 HP and has to randomly guess a number between 1 and 3 for multiple rounds until they've guessed correctly a total of 3 times.
I coped my code into a notepad file and saved it as 123game.py, then right-clicked and ran it using Python 3.8. When I did this, an odd thing happened.
I wanted a win message to say "It's over! Thank you for playing." But when the player guesses right for the 3rd time, Python just shuts down.
However I did not have the problem when I simply copy/pasted my code into Python. Is it my code that's wrong? Or should I not save a notepad file as .py and tell windows to open it by default with Python 3.8? I didn't have the problem with Pycharm.
import random
HP = 10
finish = 3
correct = [0]
while finish >= 0:
value = random.randint(1, 3)
correct.append(value)
print("\nTry guessing a number 1, 2, or 3:")
answer = int(input())
if finish == 0:
print("It's over! Thank you for playing.")
break
if HP == 0:
print("You lose! Sorry.")
break
if answer > 3 or answer < 1:
print("Out of bounds")
continue
if answer == value:
print("correct")
print(f"The answer was {correct[-1]}.")
print(f"HP left: {HP}")
finish -= 1
print(f"correct answers until finish: {finish}")
else:
print("incorrect")
print(f"The answer was {correct[-1]}.")
HP -= 1
print(f"HP left: {HP}")
print(f"correct answers until finish: {finish}")
continue
Add input() at the end of the script. It waits for any type of input from the user but without prompting him/her like input(”Enter something: ”) for example. Then the program ends (the same way it ended before, because there’s nothing else to execute) after pressing Return/Enter (so just press enter to exit the program). it’s naive, better consider the comments.
input() # or input(”Press Enter to exit”)`

Can i call my function in the while loop?

Generate a random number between 1 and 9 (including 1 and 9). Ask the user to guess the number, then tell them whether they guessed too low, too high, or exactly right. (_Hint: remember to use the user input lessons from the very first exercise
Extras:
Keep the game going until the user types “exit”
Keep track of how many guesses the user has taken, and when the game ends, print this out.
I actually cant figure out why my program is not printing the prints in the if clauses. Did i call wrong the first fucntions in my while loop?
import random
def cpu_guess():
cpu_number=random.randint(1,9)
return cpu_number
print(cpu_guess())
def player_guess():
player_number=input('Digit a number between 1 and 9\n')
return player_number
def game():
r_guesses=0
w_guesses=0
while player_guess()!='exit':
if int(player_guess())>int(cpu_guess()):
print('Higher value than generated')
w_guesses+=1
elif int(player_guess())<int(cpu_guess()):
print('Lower value than generated')
else:
print('You have entered the right value')
r_guesses+=1
return r_guesses,w_guesses
print(game())
I am not sure i can do this while player_guess()!='exit': Do i need to creat a variable like this
guess=player_guess() and write while guess!='exit'
You're calling player_guess over and over, and each time you call it, it will stop and wait for input. It's getting stuck waiting for input potentially three times per loop. Call the function once and save the result in a variable:
def game():
r_guesses = 0
w_guesses = 0
guess = None # Save it here
while guess != 'exit':
guess = player_guess()
if guess > int(cpu_guess()):
print('Higher value than generated')
w_guesses+=1
elif guess < int(cpu_guess()):
print('Lower value than generated')
else:
print('You have entered the right value')
r_guesses += 1
return r_guesses, w_guesses
print(game())
And then, as noted in the comments, do something similar for the computer's guess. The computers turn is changing constantly, so you may get through all the checks and get unexpected results for that reason. Think about what happens when those functions are called.
You keep changing the values in the middle of the loop; this is chaos, not a logic game.
# Get a player guess and see whether it's "exit"
while player_guess()!='exit':
# Get a new guess; also make a new target number.
if int(player_guess())>int(cpu_guess()):
print('Higher value than generated')
w_guesses+=1
# Get a new guess; also make a new target number.
elif int(player_guess())<int(cpu_guess()):
print('Lower value than generated')
else:
print('You have entered the right value')
r_guesses+=1
Instead, you need to make one target number the player is trying to guess. Do not change it during the game. Within the loop, have the player guess once: do not ask for more input until you've properly evaluated that guess and responded.
# Get a player guess and see whether it's "exit"
target = int(cpu_guess())
player_input = player_guess()
while player_input != 'exit':
guessed_num = int(player_input)
if guessed_num > target:
print('Higher value than generated')
w_guesses+=1
elif ...
See how that works? Don't go back to your input routine until you're done with the current guess. Don't go back to the target generation routine until the player is done guessing the previous number.

Coin Acceptor With Python Timer

I'm having trouble figuring out this code. I am currently making a script in python where a it's kind of how an arcade machine works when you have 30 seconds to continue and you can insert more coins to go again. The trouble I'm having is I cant get the coins to count up while the timer counts down. Here is my code so far:
while True:
start = GPIO.input(startBtn)
input_state = GPIO.input(counterPin)
if input_state == False:
coins += 1
print(str(coins) + "¢ inserted")
time.sleep(0.09)
if coins == 100:
coins -= 100
creditss += 1
print("You currently have: " +str(creditss) + " credits")
timer = creditss * 5
if start == False:
if creditss > 0:
print("You have: " +str(timer) + " minutes to play!")
print("Have Fun!")
x = timer
for i in range(x + 1):
time.sleep(1)
print(formatTime(x))
x -= 1
timer -= creditss * 5
creditss = 0
if timer == 0:
pause()
timer += 30
print("Continue? : Insert more money to keep playing!")
x = timer
if input_state == False:
coins += 1
print(str(coins) + "¢ inserted")
time.sleep(0.09)
else:
for i in range(x + 1):
time.sleep(1)
print(formatTime(x))
x -= 1
if coins == 100:
coins -= 100
creditss += 1
print(creditss)
if creditss > 0 & timer != 0:
print("Good")
pause()
else:
print("exit")
os.system('/home/pi/exit.sh')
Thanks for any help!
Okay...the best help I can give you is this:
At this point you need to refactor your code. When you get a program with more than two - three levels of nesting (you have four if statements nested) then you should be defining functions and splitting out different parts of your program into logical chunks. This makes debugging easier, as you can drop I/O print statements to see where your script is failing.
To help you know what to split out first - look for sections where you're repeating yourself. If you type it more than once, it deserves its own function (DRY Principle - Don't repeat yourself).
for example you have:
if coins == 100:
coins -= 100
creditss += 1
print("You currently have: " +str(creditss) + " credits")
timer = creditss * 5
and
if coins == 100:
coins -= 100
creditss += 1
print(creditss)
This functionality is extremely similar and can likely be split off into a function. The other thing you want to think about: You only want /one/ part of the program to be able to change the number of coins so that you know when you're calling it what's happening (explicit is better than implicit). That should be a function and anything that needs to operate it can call it. The easier your program is to read, the easier it will be to debug. At least until you get issues that silently fail.
The sleep function stops execution, so during countdown every time you sleep you stop checking the GPIO state for a whole second and then just check it once more until sleeping again for another second. For this strategy to work you need to be checking your input very fast as to not miss a fast event. My guess is that checking once every one second is probably not enough for what you are doing.
A sightly better solution would be to not sleep and to use time.clock() to check when the play time has ended. So when the game starts you store the current value of time.clock() and after that you continue checking it until enough time has elapsed. There could still be an input which unsets and sets your input pin faster your loop can detect it so it's not bulletproof.
I don't have experience with python on raspberry-pi but a quick google search shows me there are GPIO.add_event_detect() and GPIO.add_event_callback() functions which can be set up so a callback function is called on a GPIO pin state change, which I would guess relies on interrupts so that you wouldn't miss an event. It could be a good idea to look into that.

How to get one function to loop into another one and back again with different randints each time

So I have the following code:
def monsterturn():
global monster
global playerhp
turn = True
print "Rolling for", monster, "...(14 or better to hit)"
time.sleep(1)
if r > 14:
print r, "- The", monster, "hit you!"
playerhp-=1
time.sleep(0.5)
print "Your HP:", playerhp
if playerhp == 0:
turn = False
time.sleep(0.5)
print "YOU HAVE BEEN SLAIN."
else:
turn = False
time.sleep(1.5)
playerturn()
elif r < 14:
print r, "- The", monster, "missed you."
turn = False
playerturn()
r = randrange(1, 21)
The function playerturn() is structured exactly like monsterturn(), except with the global variable monsterhp instead of playerhp, r2 instead of r, and dialogue for the player instead of the monster. The problem is, it calculates a random integer once, and then keeps it, which often winds up with nobody hitting anyone, forever. How can I get it to calculate a different random integer every time?
Also, the function playerturn() is called, and at the end triggers monsterturn(), which triggers playerturn(), and so on, until somebody dies.
I think you should just rethink your overall design, as this would cause you to run into issues. This is largely theoretical, but the longer your fight is, the deeper your call stack would become, in the end possibly resulting in a stack overflow (and also increased memory consumption; even if it continues to run fine).
Instead, I'd suggest you rework the functions to return a boolean value, whether the game should continue. You're then able to just loop as long as both functions return true, essentially meaning the game continues:
while playerturn() and monsterturn():
To make each hit/attack random, you'd reassign r a random value right before using it:
...
time.sleep(1)
r = randrange(1, 21)
if r > 14
...
Calculate r within the loop, instead of outside it.
You can also improve this greatly by factoring out the common material, so that monster and player have the same turn function. You'd do this by avoiding the reference to global variables and passing in the details that change (opponent's hitpoints, the message to print, and so forth)

Categories

Resources