I am making an RPG and I have a section in my code that prevents me from walking through walls. However I have a gate that can only be entered if I have a Key.
class Item:
def __init__(self,item,x,y,picture,owner):
self.item = item
self.x = x
self.y = y
self.picture = picture
self.owner = owner
Chart.chart.create_image(x,y,image=picture,anchor=NW)
def grab(i,h):
i.owner = h
def discard(i,h):
i.owner = None
class Move:
def checkwallup(x):
global up
global down
global left
global right
global xx
global yy
global marketwall
global castlewall
global bforest2
global bmarket
global bcastle
global bforest1
global forest1wall
global forest2wall
global cave
global cave1doorR
global cave1doorL
global bcave1
global cave1wall
global key1
global Key
global hero
# global treetop
yy = yy - 30
pos = (xx,yy)
if bmarket == True:
if pos in marketwall:
yy = yy + 30
Chart.chart.itemconfigure(x,image=heroupstand)
elif pos == (150,30):
if Key.owner == hero:
Move.moveup(x)
else:
Chart.chart.itemconfigure(x,image=heroupstand)
elif pos == (150,0):
if Key.owner == hero:
castle()
else:
Chart.chart.itemconfigure(x,image=heroupstand)
else:
Move.moveup(x)
When I go to move through the gate nothing happens if I press twice, but if I press a third time I will go right through the gate as if I did not need to have the Key. Also when this happens everything else in my moving starts messing up.
Related
This question already has answers here:
Using global variables in a function
(25 answers)
Closed last year.
So i am making a small game with damage and the terminal always gets printed "Nukupana does 0 damage" Any idea why this would be?
Here is the code:
Strength = 5
Magic = 5
Speed = 5
Lifeforce =5
base_health = Lifeforce *10 +50
damage_done=0
curent_health = base_health - damage_done
##functions for stuff
def glacius():
magic_damage = 5 * random.randint(1,5)
damage_done = magic_damage
def nukapana_moves():
moves = ["Glacius"]
attack = random.choice(moves)
if attack == "Glacius" :
glacius()
print(f"nukapana uses {attack} it does {damage_done}.")
In your glacius function, damage_done is a local variable. The damage_done in global namespace doesn't see the change unless you use the global keyword in the glacius function to tell Python damage_done should be global:
import random
Strength = 5
Magic = 5
Speed = 5
Lifeforce = 5
base_health = Lifeforce * 10 + 50
damage_done = 0
curent_health = base_health - damage_done
##functions for stuff
def glacius():
global damage_done # <---- here
magic_damage = 5 * random.randint(1, 5)
damage_done = magic_damage
def nukapana_moves():
moves = ["Glacius"]
attack = random.choice(moves)
if attack == "Glacius":
glacius()
print(f"nukapana uses {attack} it does {damage_done}.")
nukapana_moves()
note: Often depending on global variables considered a bad practice. Instead you should free your code from depending on a global variable by returning values from functions. Functions should do their jobs independently.
Re-implementation using class:
import random
class Hero:
def __init__(self):
self.strength = 5
self.magic = 5
self.speed = 5
self.lifeforce = 5
self.base_health = self.lifeforce * 10 + 50
self.damage_done = 0
#property
def current_health(self):
return self.base_health - self.damage_done
def glacius(self):
self.damage_done = 5 * random.randint(1, 5)
def nukapana_moves(self, moves):
attack = random.choice(moves)
if attack == "Glacius":
self.glacius()
print(f"nukapana uses {attack} it does {self.damage_done}.")
player = Hero()
print(player.current_health)
player.nukapana_moves(['Glacius'])
print(player.current_health)
output:
100
nukapana uses Glacius it does 25.
75
note: When you hit damage you need to re-calculate the current_health, Or as I've done here use a property that gives you the correct value. Otherwise you hit damage but the self.current_health doesn't change because it calculated once in the initializer.
I saved my variables at the start of my program and allow the functions to access them I believe but when they run the value is not saved when the function repeats.
P1_score = 0
P2_score = 0
round_number = 0
def dice_rolling():
# P1D1 means player ones dice one value and so on with P1D2
import random
# player ones turn
print("player ones turn")
P1D1 = random.randint(1, 6)
print("your number is ", P1D1)
P1D2 = random.randint(1, 6)
print("your second number is", P1D2)
# player twos turn
print("player twos turn")
P2D1 = random.randint(1, 6)
print("your number is", P2D1)
P2D2 = random.randint(1, 6)
print("your second number is", P2D2)
score_calculation(P1D1, P1D2, P2D1, P2D2,P1_score,P2_score,round_number)
def score_calculation(P1D1, P1D2, P2D1, P2D2,P1_score,P2_score,round_number):
import random
round_number = round_number + 1
# player 1 score calculation
total_P1 = P1D1 + P1D2
P1_score = P1_score + total_P1
if total_P1 % 2 == 0:
P1_score = P1_score + 10
else:
P1_score = P1_score + 5
if P1D1 == P1D2:
P1D3 = random.randint(1, 6)
P1_score = P1_score + P1D3
# player 2 score calculation
total_P2 = P2D1 + P2D2
P2_score = P2_score + total_P2
if total_P2 % 2 == 0:
P2_score = P2_score + 10
else:
P2_score = P2_score + 5
if P2D1 == P2D2:
P2D3 = random.randint(1, 6)
P2_score = P2_score + P2D3
print("player ones score at the end of round", round_number, "is", P1_score)
print("player twos score at the end of round",round_number,"is",P2_score)
for x in range(0,5):
dice_rolling()
Any help would be appreciated and if someone could give a simple explanation as to what I'm doing wrong and what to fix would be great.
Python can read from global variables inside a function, but can't assign them without some extra work. In general, when you want to use a global variable, it's a good idea to make it explicit by using the global keyword in your function:
my_global_var = 0
def some_function():
global my_gobal_var
my_global_var = 10
print(my_global_var) # it prints 10
somefunction() # modifies the global var
print(my_global_var) # now it prints 10
Variables are defined and used locally. Consider this example.
x = 1 #initial value
def test(x):
print(x) #print what you got
x += 1
print(x) #print updated value
print(x) #Actual printouts here
test(x)
print(x)
This results in :
1
1 #value when entering the function
2 #Value changed by function
1 #value outside the function did not change
If you want the variables to be maintained in functions, consider using class variables or global variables. (I recommend avoiding globals as you get to more complex problems)
Global example:
global x
x = 1
def test():
global x
x+=1
print(x)
test()
print(x)
test()
print(x)
Results in :
1
2
3
Finally class variables:
class test_class():
def __init__(self):
self.x = 1 #variables defined like this are class variables
def test(self):
self.x += 1 #Advantages of class variables is that you can defined them in the __init__ function
def running(self):
print(self.x) # And you can access it from multiple functions without using globals and much more too.
self.test()
print(self.x)
if __name__ == '__main__':
tclass = test_class()
tclass.running()
So I've been working on this game (I'm a big noob at python and I've only worked on this for like 3 days) and I've been trying to move the Location (Add or Subtract one from Location's x and y values) but the fuction doesn't work. I know because I put a print in the function and the print didn't work at all. What is wrong? (I have created a folder for this project and there is a folder called Decisions containing 2 files.)
Locations.py:
class Location:
def __init__(self, x, y):
self.x = x
self.y = y
def move_forward(self):
self.y = self.y + 1
return self.y
def move_back(self):
self.y = self.y - 1
return self.y
def move_left(self):
self.x = self.x - 1
return self.x
def move_right(self):
self.x = self.x + 1
return self.x
main.py (Main Function):
import Decisions
import Characters
import Locations
def main():
Player = Characters.Character([], 100)
Loc = Locations.Location(0, 0)
answer = Decisions.choice_yes_no.choice_yes_no("You woke up, discovering
that somehow you were in the middle of a dark dungeon. A sword lies to the
left of you, pick it up? (Yes/No) ")
if answer == True:
print("You picked up the sword.")
Player.add_item("Sword")
elif answer == False:
print("You chose not to pick up the sword.")
answer_2 = Decisions.choice_direction.choice_direction("You stood up,
patting the dust off your clothes, you looked around. The room was dark and
you view was limited to a few meters. Where do you go?
\n(Left/Right/Forward/Back) ")
if answer == "forward":
Loc.y = Loc.y + 1
elif answer == "back":
Loc.move_back()
elif answer == "left":
Loc.move_left()
elif answer == "right":
Loc.move_right()
print(Loc.x)
print(Loc.y)
main() #REMOVE BEFORE USING#
The function add_item works just fine, what is wrong? There aren't any errors, it's just when I print the x and y values at the end they stay 0.
I was sitting all week on this and I don't know how to get rid of these global points.
Here I define points.
def init():
global points, hidden_password, hidden_password2, country, used, start_time
points = 0
hidden_password = []
hidden_password2 = []
country = ""
used = []
start_time = datetime.now()
welcome()
choice()
Then it goes to choice() from choice to play_game() than to guessing_capital() and here I use points for the first time, and the program is working until var points reach 5.
def guessing_capital(password, used, user_name):
global points
while points < 5:
checking(password, user_name)
time.sleep(1)
print("\n Letters You failed guessing: ", ", ".join(used), end=".\n")
time.sleep(2)
print("\n *** You lost! Sorry, but the GAME is OVER! ***\n")
time.sleep(3)
init()
Then it goes to checking() and from checking it goes to the letter() and then to checking_password() where if the user didn't guess right letter it adds 1 to points and returns it.
def checking_password(number):
global points, hidden_password2, hidden_password
if hidden_password2 == hidden_password:
points += number
time.sleep(1)
print("\n Boo! You have +", number, "penalty points!")
time.sleep(1)
hidden_password2 = hidden_password
if points < 4:
manage_graphics(points)
elif points == 4:
manage_graphics(points)
print(" Hint: It's a capital of " + country + ".")
elif points >= 5:
manage_graphics(5)
return points
Here is a full code if someone wants: https://codeshare.io/aYBAzb
You can use a class to store attributes.
Class Game:
def __init__():
points = 0
self.hidden_password = []
self.hidden_password2 = []
self.country = ""
self.used = []
self.start_time = datetime.now()
self.welcome() # This should be in main function
self.choice() # This should be in main function
def choice(self, ...):
pass
def welcome(self, ...):
pass
def guessing_capital(self, ...):
pass
def checking_password(self, ...):
pass
Sorry if I don't do this correctly, I am new here. I am trying to make it so that raw_input loops through saving the value of self.x every time so that it asks "r or l"? Whenever you click enter, then raise or lower self.x but I'm not sure how to. If someone could check my work, that would mean a lot. Thank you.
q = raw_input("r or l: ")
class game:
def __init__(self):
self.x = 0
def raise_n(self):
self.x += 1
return self.x
def lower_n(self):
self.x -= 1
return self.x
def main():
g = game()
while q == "r":
print g.raise_n()
break
while q == "l":
print g.lower_n()
break
main()
I also tried this, but it didn't save the value of self.x even if I tried to call main() again.
q = raw_input("r or l: ")
class game:
def __init__(self):
self.x = 0
def raise_n(self):
self.x += 1
return self.x
def lower_n(self):
self.x -= 1
return self.x
def main():
g = game()
while q == "r":
print g.raise_n()
break
while q == "l":
print g.lower_n()
break
main()
Any help would be very useful, thank you!
Your second approach was closer to a valid solution. There are several approaches, and below I show you one, without introducing too many changes. Basically:
The main() function is executed in an endless loop. Change the True condition if you want to change the stop condition.
The question is asked and evaluated every time it enters the main() function. Afterwards, it checks if it has to run the raise_n() or lower_n() methods.
The code:
class game():
def __init__(self):
self.x = 0
def raise_n(self):
self.x += 1
return self.x
def lower_n(self):
self.x -= 1
return self.x
def main():
q = raw_input("r or l: ")
if q == "r":
print g.raise_n()
if q == "l":
print g.lower_n()
g = game()
while True:
main()
EDIT: In order to put as condition for the while loop to iterate a determinated number of times, a constant can be succesively increased and check if it has reached the desired limit:
#... Copy previous code here
g = game()
iterations_limit = 10 #Substitute 10 by any positive integer
while k > iterations_limit:
k += 1 #Increase variable k
main()