Variable adding and subtracting/randomizing problems - python

#Variables
enemy=['Dummy','Ghost','Warrior','Zombie','Skeleton']
current_enemy=random.choice(enemy)
enemy_health=randint(1,100)
dmg=randint(0,50)
current_enemy_health=enemy_health-dmg
#Functions
def enemy_stats(current_enemy_health):
if current_enemy_health<=0:
print(current_enemy,"died.")
if current_enemy_health>0:
dmg=randint(0,50)
current_enemy_health=enemy_health-dmg
print(current_enemy,"has",current_enemy_health,"health left.")
#Meeting an enemy - Attack / Defend Option
def encounter(current_enemy):
print(name,"encountered a",current_enemy,"with",current_enemy_health,"health.","What do you do?")
print("Attack? or Defend?")
def battle():
encounter(current_enemy)
#Attack Or Defend?
choice=input("What do you do?")
if choice!="Attack" or choice!="Defend": #If the choice isn't attack then ask again
print("Do you attack or defend?")
choice=input("What do you do?")
#Say correct sentence depending on what you do.
if choice=="Attack": #If the choice was attack then do a random number of dmg to it
print(name,choice+"s",current_enemy,".","You deal",dmg,"damage","to it.")
enemy_stats(current_enemy_health)
if choice=="Defend": #If ... to it
print(name,choice+"s.")
#Check to see if the enemy is still alive
while current_enemy_health>1:
#Attack Or Defend?
choice=input("What do you do?")
if choice!="Attack" or choice!="Defend": #If the choice isn't attack then ask again
print("Do you attack or defend?")
choice=input("What do you do?")
#Say correct sentence depending on what you do
if choice=="Attack": #If the choice was attack then do a random number of dmg to it
print(name,choice+"s",current_enemy,".","You deal",dmg,"damage","to it.")
enemy_stats(current_enemy_health)
if choice=="Defend": #If ... to it
print(name,choice+"s.")
#Checks to see if the enemy is dead
if current_enemy_health<=0:
print(name,"successfully killed a",current_enemy)
battle(
)
So i'm making a text-based RPG game. All going well but there is one thing I can't fix, i've tried a lot of things to try and fix the problem, basically when you encounter and enemy it spawns with a random amount of health. You then hit it for some damage. 'Zombie with 20 health spawned. What will you do?' I attack and say I deal 9 damage. What happens is that the health just goes to a random number instead of 20-9. Or say I did 21 damages. What happens this time is that the health once again goes to a random number instead of 20-21 and dieing. Basically what I can't manage to fix is the health-dmg part. I haven't managed to see if the health<0 works as I can never get the enemy to 0 health.
Any help would be appreciated.

In your function:
def enemy_stats(current_enemy_health):
if current_enemy_health<=0:
print(current_enemy,"died.")
if current_enemy_health>0:
dmg=randint(0,50)
current_enemy_health=enemy_health-dmg
print(current_enemy,"has",current_enemy_health,"health left.")
You have these two lines:
dmg=randint(0,50)
current_enemy_health=enemy_health-dmg
What this essentially does is subtract a random number from the current health of the enemy, which would result in the random number you reported having. To fix this, have whatever weapon a player is using be assigned a "damage" that it does that and put that into the function as an argument. Your new function would look like this:
def enemy_stats(current_enemy_health, dmg):
if current_enemy_health<=0:
print(current_enemy,"died.")
elif current_enemy_health>0:
current_enemy_health=enemy_health-dmg
print(current_enemy,"has",current_enemy_health,"health left.")
And would be implemented like this:
enemy_stats(var_for_current_enemy_health, damage_of_weapon)
Best of luck, and happy coding!

Related

Multiple changes to the same variable within different if statements

SOLVED: I read through my code, it was a 'bug'. When I copied the dice roll method from the 'player character', since it uses the same mechanics for the enemies, I set the damage to 0 if it rolls with one die on accident.
Beginner here. (Python crash course halfway of chapter 9)
I am trying to build a simple turn based text game to practice (classes,if statement, modifying dictionaries/lists etc).
I will copy two snippets from my code, so you can understand my problem better.
(I'm really sorry that I can't give a short description, my best try was the title, but that still doesn't make it good enough. If you want an abridged tldr, go to the bottom with the bold texts.)
First, I have two characters, that you can choose from as an if-elif-else statement.
I used the same "player_xy" (xy being like health, damage etc) for the two characters, but assigning different values to them based on the player's choice. (My reasoning being is so I only have to reference the same variable in the code later in the battle system, making my job easier.)
(The variables fighter_max_hp.. etc are defined earlier, but it doesn't matter (tried moving it to before/inside the if statements.)
while select_repeat == True:
print("Type 'f' for fighter , 'm' for mage, or 'q' to quit!")
character = input("TYPE: ")
#player chooses fighter
if character == 'f':
player_max_hp = fighter_max_hp
player_max_mana = fighter_max_mana
#this goes on for a while, setting up all the stats
#player chooses mage
elif character == 'm':
player_max_hp = mage_max_hp
player_max_mana = mage_max_mana
#this goes on for a while, setting up all the stats
#player chooses to quit
elif character == 'q':
select_repeat = False
#invalid input
else:
print("\nPlease choose a valid option!")
Later in the code, I have a part where a randomizer sets up enemies to fight.
I used the same "enemy_xy" (xy being like health, damage etc) for the enemies. (My reasoning was the same here as for the characters.)
(Same, as with the player variables (tried moving it to before/inside the if statements.)
while enemy_select == True:
#game chooses an enemy to fight!
min = 1
max = 3
enemy_chooser = int(random.randint(min, max))
if enemy_chooser == 1:
#choose werewolf
enemy_hp = werewolf_hp
enemy_dice = werewolf_dice
#this goes on for a while, setting up all the stats
if enemy_chooser == 2:
#choose lesser mimic
enemy_hp = int(player_max_hp / 2)
enemy_dice = player_dice
elif enemy_chooser == 3:
#choose zombie
enemy_hp = zombie_hp
enemy_dice = zombie_dice
#this goes on for a while, setting up all the stats
Keep in mind, all of these enemies use the same "enemy_hp", "enemy_dice" etc. variables, within the same battle system, just assigned as "enemy_hp = werewolf_hp" or "enemy_hp = "zombie_hp".
The fight happens, and:
If your enemy is the werewolf:
you deal damage to it
you receive damage from it
you can kill it
you can get killed by it
If your enemy is the lesser mimic:
you deal damage to it
you can ONLY receive damage from it if you are a fighter (mage's hp doesn't decrease)
you can kill it
you can ONLY get killed by it if you are a fighter (obviously, since it doesn't deal damage to mage hp)
If your enemy is the zombie:
you deal damage to it
you CAN NOT receive damage from it (not the fighter, or the mage)
you can kill it
you can not get killed by it (obviously, since no damage)
Otherwise, it prints out the different variable values as assigned (different stats for each monster) as expected, and it uses correct calculations to deal damage.. it just can't in the two cases mentioned above.
Now comes the main part of my question...
If I change the variables like this:
elif enemy_chooser == 2:
#choose zombie
enemy_hp = werewolf_hp ##CHANGE
enemy_dice = werewolf_dice ##CHANGE
#this goes on for a while, setting up all the stats
Then the zombie can finally deal damage to the player (with the werewolf's stats).
It's as if because the lines
enemy_hp = werewolf_hp
enemy_dice = werewolf_dice
#etc
are written earlier than:
enemy_hp = zombie_hp
enemy_dice = zombie_dice
#etc
it somehow effects the variable (regardless or not if the "if" statement is true).
because werewolf_xy was defined earlier than zombie_xy
#enemy werewolf defined first in the code
werewolf_hp = 20
werewolf_dice = 2
#etc
#enemy zombie defined right after
zombie_hp = 35
zombie_dice = 1
#etc
Same happens with the fighter and mage selection.
Somehow the player_hp = xy_hp only works if xy = fighter, because the fighters variables are defined earlier in the code, and thus making the "lesser mimic" deal damage only to the fighter.
My question is "simply".. why?
I tried everything in my power, to no avail.
As you have seen, I could identify what causes the problem (and thus I >could< potentionally work around it), but I still don't know why Python does what it does, and that bothers me.
Any help or input from more experienced users would be greatly appreciated.
Thank you in advance!
Tankerka
You have a bug.
There's not enough details in this (long!) narrative to identify the bug.
Here's how you fix it:
breakpoint()
Put that near the top of your code,
and use n next, plus p print var,
to see what your code is doing.
It is quicker and more flexible than print( ... ).
Read up on that pair of commands here:
https://docs.python.org/3/library/pdb.html
Separate item: refactor your code as you go along.
You're starting to have enough if / elif logic
that it won't all fit in a single screenful
with no scrolling.
That suggests that it's a good time to use def
to break out a helper function.
You might def get_enemy_hp( ... ):, for example,
and also define get_enemy_dice().
Other things you might choose to study:
a class can be a good way to organize the variables you're defining -- embrace the self syntax!
a dict could map from enemy type to hp, or to dice
The nice thing about helper functions is they're
the perfect target for unit tests.
It takes a minute to write a test, but it winds up saving you time.
https://docs.python.org/3/library/unittest.html
When you identify and fix the problem, let us know!
https://stackoverflow.com/help/self-answer

Betting system won't seem to process the user input correctly, how can this be improved?

I'm trying to code a game of craps in which the player has a virtual 'wallet' to gamble with. I've gotten to the user input part and it's not going as planned.
Here is what I have so far:
import random
import sys
money = "500"
# start the game
a = input("Hello travler, to start the game, please type 'yes'. If you are not ready to begin your journey, type 'no' ")
if a.lower() == "no":
sys.exit()
else:
print("Welcome")
print("Hold on... I'm missing something,")
name = input("What is your name, traveler?: ")
print("Welcome,", (name))
# those who need instructions can ask for it,
# others can start the game directly.
a = input("Welcome to a game that'll determine the rest of your life. Do you need instructions? (yes) or (no)? \n")
if a.lower() == "yes":
print('''1. the player will roll two six sided dice. the sum of the two dice is the player's number for the round.
2. rolling a 7 or an 11 as your first roll win you the game, but be weary, a 2, 3, or 12 automatically causes the player to lose. no more game for you. If a 4, 5, 6, 8, 9, or 10 are rolled on this first roll, that number becomes the 'point.'
3. the fated player continues to roll the two dice again until one of two things occur: either they roll the 'point' again, causing them to win the game; or they roll a 7, causing them to be doomed to the eternals.''')
elif a.lower() == "no":
print("may luck be with you on this fateful day,", name)
print("You will start off with 500 pieces of luck, if you leave this game with over 1000 pieces of luck, you will be fated for sucsess. On the other hand, should you drop below 0 peices of luck, you will find yourself in debt to the universe, a misfortune that few recover from.")
print("You currently have", money, "luck to spare")
# betting time
while True:
bet = input("How much luck do you wish to bet? ")
if bet.isdigit() is True:
if money > bet:
print("Bet accepted")
if bet.isdigit() is True:
if bet > money:
print("How unfortunate, you do not have the luck to make this bet.")
elif bet.isdigit() is False:
print ("Sorry, luck can only be quantitated in number values.")
# if you bet higher than your money, it wont allow you to bet within after that.
The code below the line # betting time is where I am hitting my head over.
I need the code to do the following:
check if the user input is in fact a number, if it's not a number, make them enter a new input
if the user input is a number, determine if it is within the amount they have in their 'wallet' (if not, make them input a new number)
if the number is within the amount in their 'wallet' and is a digit, give the user the option to "roll dice" triggering the game to start.
If they win, they need to be granted double what they bet, if they lose, they need to lose the amount they bet. The wallet will need to update after each play, giving the user the option to play again with their updated wallet (so if they bet 50 and win, their new balance will be 550. The process continues until the user either reaches 1000 or 0, causing the game to end either way.)
For checking if the user's bet is a number use the .isnumeric() function on your bet like:
bet.isnumeric()
to do the second thing you needed help with you could do:
if bet < wallet: blah blah blah elif
bet > wallet: print("You do not enough money")
around like that it with actual good syntax
to do dice you could use the random.randint() function like this:
random.randint(1,6)
I hope that helps!

Choose your own adventure - choice function?

I'm working on a choose-your-own-adventure game in Python to try to learn how to code. I might be doing this entirely wrong, but I thought rather than just nesting if-elif-else statements endlessly, I could write some sort of function that would be a template for all choices in the game.
My ideas was to have every decision in a given scene to generate two lists - choices and outcomes. The "multitemplate" function would then load the choose and outcomes lists, present the options to the player, take in the answer, and call the correct function for the outcome given.
My issue is that the outcome list is a list of functions, which Python doesn't seem to like. It says I've not defined the functions properly, but when I define my outcome functions before calling "multitemplate", it just prints them first.
Here's my code:
#Function to allow the adventurer to make choices
def refusal():
print("You stop at the roadsign you passed on your way into town. There are only two directions - towards Tarroway, or towards Angion, the town from whence you came.")
def guards():
print("The guards stop you.")
def theinn():
print("You follow the joyful chatter down the deserted street. Its source is a squat, one story building. A sign above the door reads \"The Forked Tongue\"")
choose = ["I walk towards the merry sounds.", "I turn on my heels and head back where I came from.","I stay where I am and watch the night quietly."]
outcome = [theinn(), refusal(), guards()]
def multitemplate(choose,outcome):
global mychoice
global carryon
for x in range(len(choose)):
print (f"{x+1}) " + choose[x], end="\n")
mychoice = (input())-1
while True:
if (mychoice) in range(len(choose)):
carryon = True
outcome[mychoice]
carrion()
else:
print("Please enter the number of the choice you wish to make.")
carryon = False
mychoice = int((input()))-1
I'd appreciate any input on how this should work properly, or if I'm going down a completely blind alley here.
Thanks!

Trying to make a small dice game - only works for one player, want to implement multiple players

I'm totally new to Python and programming in general, and just starting to learn how to crawl, basically. I decided to learn programming by doing, and so I tried to develop a little dice game.
The main intention (i did not manage to succeed in making the code like i wanted it to) was to make a game with the following rules:
The game is played by two or more players
There is only one dice involved in the game
Object of the game is to be the first to get at least 100 points
A player is chosen by random to go first: The player can roll the dice as many times as s/he likes, and the points are accumulated. However, if the dice returns 1, the player loses the accumulated points. At any time, the player can choose to stop rolling the dice and secure the points. By doing this, the player loses its turn, and the next player can start rolling. Points that are secured, can never be lost.
When first trying to make this code, I wanted to make it with classes and functions, but I just couldn't make that work. Also I couldn't figure out how to design the game for multiple players. I tried working with lists and dictionaries, but I just kept pulling my hair. So I just tried to make the game for 1 player, where the objective is to reach a 100 points in fewest rounds (a new round starts everytime you secure points). Not very fun, but at least I got it to work (well, sort of).
I would highly appreciate any comments to my little program. Please note it's my first code, and I know it is really badly written. I want to hear how you guys think the code could be improved, and how I should go about in organizing the code for multiple players. I'm interested in learning to program for mobile devices at a later stage, and want to eventually turn this little game into an app so I can play with friends (for fun and as a way to learn the how-to's).
Hope the indents are adjusted properly.
from random import choice # Importing the random element to create the dice
score = 0
rounds = 1
secured = 0
unsecured = 0
ask = "N/A"
while secured+unsecured < 100:  # Check if the total score is below 100
a = int(choice([1,2,3,4,5,6])) # Choose a dice number
if a == 1: # Check if the dice is one
if ask == "s": # Check if the player secured the last score
print ("Good thing you just secured your score, because you now rolled a 1.")
print ("Because of this, you only lost your round, not any points! :)")
if ask =="N/A": # Check if the player rolled a one on the first throw
print ("************* Round 1 ***********")
print ("Tough luck, you rolled a ONE on your first roll. You lost one round.")
rounds +=1
if ask == "r": # Check if the player lost points that was unsecured
print ("")
print ("***** UH UH UH UH UH - YO ROLLED A ONE ******")
print ("You lost the", unsecured,"points you didn't secure")
unsecured = 0  # Player loses the unsecured points
rounds +=1 # Increase round number
else:
unsecured = unsecured + a # If the dice returned something else than one, the player wins the points
print ("")
print ("")
print ("************ Round ", rounds, "**************")
print ("")
if a > 1: # Only display the dice if the dice is higher than one (if it's one it has already been printed)
print ("You rolled a ", a)
print ("")
print ("Unsecured points: ", unsecured)
print ("Secured points:" , secured)
print ("The sum of secured and unsecured pointsare:",secured+unsecured, "points")
print ("")
ask = input ("Roll the dice or secure? (r/s) ")
if ask == "s":
secured = secured+unsecured # If player chooses to secure the points, the points are added
score = 0
rounds +=1 # Increase round
if unsecured == 0: # Check if player was an idiot and chose to secure 0 points
print ("You chose to secure zero points, not very clever! You wouldn't risk anything by rolling the dice, and you lost the round!")
else:
print ("You chose to secure your", unsecured, "points, and you have secured", secured, "points in total")
print ("")
unsecured = 0 # Reset unsecured points, since it is added to secure points
input ("Press Enter to roll the dice:")
else:
if ask == "r":
score = unsecured+a
else:
print ("Congrats!  You made ",secured+unsecured, "points in", rounds , "rounds")

Creating a while loop for a Game

I am new to Python and I had a quick question about a code I have been working on today. I am creating a game that uses a while loop where the two opponents will have turns to "hit" one another until one of the players have 0 health points.
This is the code I have so far, although it is not working. Can anyone help?
done=False
while not done:
if You.Hit_points>Opponent.Hit_points:
move=raw_input("Would you like to make a move? (y/n) ")
if move=="y":
print "",You.name,"hit ",Opponent.name," by",You.Hit_points," hit points!"
Opponent.Health=You.Hit_points+You.Skill_points+Opponent.Health
print "Due to the hit",Opponent.name,"is left with",Opponent.Health," health points."
print ("The Mighty Beast will make a move.")
print "",Opponent.name,"hits",You.name,"by",Opponent.Hit_points,"points"
You.Health=(Opponent.Hit_points-Opponent.Skill_points)+You.Health
print "Due to the hit",You.name,"loses",Opponent.Hit_points,"points.Leaving",You.name,"with",You.Health,"health points."
print "Now it is",Opponent.name,"'s turn to make a move"
You.Health=You.Health-(Opponent.Hit_points+Opponent.Skill_points)
print "Due to the hit",You.name,"is left with",You.Health,"health points."
else:
You.Hit_points==0
move=="n"
done=True
if You.Hit_points>Opponent.Hit_points:
should probably be
if You.Hit_points > 0 and Opponent.Hit_points > 0
right? Otherwise as soon as You's HP drops below Opponent's--which could be after the first turn--the fight will end.

Categories