Instance variable resets after modification - python-3.x

I'm having difficulty with one small part of my code. I'm modifying a player's HP while they're in combat, but when exiting combat the HP resets to 100. This is odd because the enemy's HP is preserved. By using print(id(player.hp)) I can see that a new instance of player.hp is being created, I just don't know why. I've tried googling the issue but I can't find an example that fits my problem. I'll try to only include the pertinent parts of the code below (there's a lot of superfluous writing that isn't necessary here), but if I need to include everything I will.
class Alleyway(Scene):
room_items = []
room_characters = []
room_enemies = ["hobo"]
def __init__(self):
self.fresh_arrival = True
self.north = False
self.east = True
self.south = True
self.west = False
self.enemy = Hobo()
def fight(self, player, weapon): #Lots of what makes this fun is edited out
while True:
if self.enemy.hp > 0:
print("Do you attack or flee?")
words = input("> ").lower()
if words == "flee":
map_ = Map("alleyway")
game = Engine(map_)
game.play()
if words == "attack":
miss = randint(1,4)
if miss == 1:
print("Too bad, you miss!")
else:
print("You got him!")
self.enemy.hp -= weapon.damage
print("Hobo's HP: {}".format(max(self.enemy.hp, 0)))
if self.enemy.hp > 0:
print("The hobo takes a swing at you.")
hobomiss = randint(1,5)
if hobomiss == 1:
print("He missed!")
else:
print("Ouch, he got you!")
player.hp -= self.enemy.damage
print("Your HP: {}".format(max(player.hp, 0)))
else:
print("No idea what you mean. Attack the man or flee.")
else:
print("You defeat the hobo!")
print()
print("Dirty shoes and shank added to inventory.")
print()
shoes = DirtyShoes()
shank = Shank()
player.inventory.append(shoes)
player.inventory.append(shank)
self.room_enemies.remove("hobo")
map_ = Map("alleyway")
game = Engine(map_)
game.play()
When fight() is called, an instance of Player() is sent in as an argument, which has an instance variable of self.hp = 100.
This is still a work in progress so please gloss over the fact that it doesn't exit when the player dies and other silly things like that (:
Now, when the player flees in the middle of the fight, my goal is for the enemy's HP to be preserved, the player's HP to be preserved, and the items to be added to the player's inventory. So far, the enemy's HP is accurately preserved and everything else in my code regarding the enemy's HP and his alive/dead status work great when combat is exited. My issue is with player.hp -= enemy.damage, player.inventory.append(shoes), and player.inventory.append(shank). None of them work. The player.hp displays correctly during the fight and decreases as expected, however once the player exits combat the HP is reset to 100 and there is nothing added to the inventory. I've tried player.hp = player.hp - enemy.damage for the HP issue and it still creates a new variable. I'm just not sure what's going on since the enemy portions are working fine.
If more information is needed please let me know. And if there are any obvious ways my code can be improved I'm totally open to suggestions.

Got it! I was defining player = Player() inside of a method, so it only created the instance for that method (I think). So I defined it outside of the method and now the modified values stick!

Related

trying to get the "print("Which will you choose?")" to go to a new set of choices which will lead to other choices

The assignment is to create a text based game. The goal of this game is to open the locked door inner to access the rest of the house. When the door has been unlocked the player can return to the entrance room and open the door to the rest of the house.
in each room (the pantry and the kitchen) there are a set of locks of which you must turn to the corect postions to unlock the central door).
Now i think im on the right track however, as the question states, im stuck on trying to get teh final part of the ##if option == "1":## to get to a set of choices.
Here is what i got..im not looking for answers just help to be lead in the right direction.
do i define a new set of functions like #def choices():#, then list the available options?
import random
import time
def displayIntro():
print("Welcome to the")
time.sleep (1)
print("Dungeon of Doom")
print()
time.sleep (1.5)
displayIntro()
#need to defin the path choices and what they lead to# also need to make sure it validates the inputs so no errors is user inputs a false input#
def choosePaths():
path = ""
while path != "1" and path != "2" and path != "3":
path = input("Which path will you choose? (1,2 or 3): ")
return path
def checkPath():
print("You head down the hallway into the pantry.")
time.sleep(2)
print("")
time.sleep(2)
print("")
print()
time.sleep(2)
def menu():
print('Choose your option')
time.sleep (1)
print("[1] Enter The Dungeon")
print("[2] Run away.")
menu()
option = ""
while option != "1" and option != "2":
option = input("Enter The temple or run away? (1 or 2): ")
option
if option == "1":
print("You step inside the ominous and dank dungeon.")
time.sleep (3)
print("as you enter the dungeon you hear a mysterious whisper in your ear")
time.sleep (3)
print("the voice says that you may not leave until you find the treasure within the central hall of the dungeon.")
time.sleep (3)
print("You turn around as see that the door behind you has magically disappeared.")
time.sleep (3)
print("You begin to look around the room")
time.sleep (3)
print("you see three hallways, one to the left, one to the right and one down the center.")
time.sleep (3)
print("The one on the right looks like it leads you towards what may be the kitchen")
time.sleep (3)
print("the other on the left may lead to the pantry")
time.sleep (3)
print("the very center hallway leads to what looks like the central hall.")
time.sleep (3)
print("Which will you choose?")
if option == "2":
print("You have left the Dungeon of Doom")

calling defined functions in another function in Python3

I am just starting to code. Got a job as a junior developer thanks to other skills. And right now I am self studying to learn Python 3, Django and React. I am 3 weeks in, and i like it thus far.
While learning to code i found some exercises to do and gave my own swing at it. So I am trying to make kind of a lite rpg, where the player and comp chooses an attack and it gets executed in random order.
But i am having trouble making the attacks and everything else to be in callable functions. I could write out the whole code to the length of times, but i want to make it easier to code and expand on. This is what i have at the moment. I think the mistake is in the parameters in the functions? Which make some local instead of global values.
anyways, thank you in advance.
So i tried a lot of different parameters in different places. cant figure it out. also tried to call the move functions inside the player_move function.
import random
def tackle():
dmg = random.randint(150, 280)
return dmg
def bite():
dmg = random.randint(110, 350)
return dmg
def heal():
dmg = random.randint(130, 260)
return dmg
player_health = 1000
comp_health = 1000
alive = True
def player_move():
move = input("Use one of the following moves: \n"
"1. Tackle\n"
"2. Bite\n"
"3. Heal\n"
"Choose the Move: ")
if move == 1 or move == "Tackle" or move == "tackle":
comp_health -= tackle()
elif move == 2 or move == "Bite" or move == "bite":
comp_health -= bite()
elif move == 3 or move == "Heal" or move == "heal":
comp_health -= heal()
return comp_health
player_move()
print(comp_health)
So i figured a few things out. Most of it was in the scope of the functions. Had to call the functions before using them. I ended up rewriting most of it, but got it to work. (edit) The question still stands though. How can I call a function out of scope??

How to get Python 3 to register a random word from a external file as a variable

I'm a computer science student at secondary school currently struggling with a certain aspect of my NEA, we are permitted to get help with the code. The aim of the NEA is to create a game which can choose a random song and artist from an external file and then get the user to guess which song it is. The issue I have run into is when I run the program the random aspect of the code (The Song name and artist chosen from the external file) does not seem to be registered by the if statement. I cannot think of a better way to explain my issue, but if you run the code I believe you will see the issue I'm having. I have taken out most of the excess code that is not part of the problem to make it easier to understand because like I said before I am still a novice at this. I have looked around for a while now and cannot seem to find an answer. Any sort of help would be very much appreciated.
username = 'Player1'
password = 'Password'
userInput = input("What is your username? (Case Sensitive)\n")
if userInput == username:
userInput = input("What Is Your Password? (Case Sensitive)\n")
if userInput == password:
print(
"Welcome! In this game you need to guess each songs name after being given its first letter and its artist. Good luck!"
)
else:
print("That is the wrong password. Goodbye ;)")
exit()
else:
print("That is the wrong username. Goodbye ;)")
exit()
startgame = 'Start' 'start'
userInput1 = input("Click Any Button And Click Enter To Begin Game:")
if userInput1 == startgame: 'Start'
print("Welcome To The Game")
import random
Song = [line.strip() for line in open("Songnames.txt")] #Currently in the external file I have removed all of the other songs apart from H______ By Ed Sherran.
print(random.choice(Song))
userguess = input("Whats Your Answer?\n")
if userguess == ("Happier") and (random.choice(Song)) == "H______ By Ed Sherran": #The program will continue to return 'Incorrect'.
print("Nice One")
else:
print ("Incorrect")
Any sort of help would be very much appreciated , I have looked for a while on this site and others for an answer however if it seems I have missed an obvious answer I do apologise.
When I run the code it seems to work. (My Songnames.txt contains one line, H______ By Ed Sherran.)
Is it possible that your Songnames.txt contains at least one empty line? If so, filtering the empty lines might fix the problem:
Song = [line.strip() for line in open("Songnames.txt") if line.strip()]
A few other suggestions for your code:
startgame = 'Start' 'start'
userInput1 = input("Click Any Button And Click Enter To Begin Game:")
if userInput1 == startgame: 'Start'
print("Welcome To The Game")
This doesn't make sense. Besides the misleading prompt about buttons and clicks, the if userInput1 == startgame: 'Start' doesn't do anything, not even print start. And the game starts regardless of what the user enters.
The actual game has a few issues as well, most importantly for when you actually have multiple songs is the fact that you choose a random song twice. Given enough songs, these will almost always be two different songs, so the print will be utterly misleading. Better choose one song and assign it to a variable:
import random
songs = [line.strip() for line in open("Songnames.txt") if line.strip()]
computer_choice = random.choice(songs)
print(computer_choice)
userguess = input("Whats Your Answer?\n")
if userguess.lower() == computer_choice.lower():
print("Nice One")
else:
print("Incorrect")
I took the liberty to make the comparison case insensitive by comparing the lowercase versions of the user guess and the computer's choice.

Unable to get out of loops

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

Pygame head-on collisions not detecting

Im really new to Python and recently I've been working on creating a small, space invaders style game in pygame. I've almost reached the end however, I want to make it so if the enemy ships (block) collide with my ship (player), a collision is detected, removing my both ships and displaying a short "Game Over" message.
So far I have the code for detecting when a bullet and an enemy ship collides, I have rewritten this for if my ship and an enemy ship collides but this code only works if I fire no shots, I also have to be moving from side to side for the collision to be detected (head on collisions do nothing) once the collision is detected and both ships disappear I am still able to fire bullets from the position at which the collision was detected. I have no idea why this happens. If anyone could help me out Id definitely appreciate it.
Heres the code in question:
for i in range(15):
block = Block(BLACK)
block.rect.x = random.randrange(screen_width)
block.rect.y = random.randrange(55) # change to 155 collisions fixed
block_list.add(block)
all_sprites_list.add(block)
for i in range(1):
player = Player()
player.rect.y = 480
player_list.add(player)
all_sprites_list.add(player)
...
for player in player_list:
player_hit_list = pygame.sprite.spritecollide(block, player_list, True)
for player in player_hit_list:
gameover.play()
player_list.remove(player)
all_sprites_list.remove(player)
block_list.remove(block)
all_sprites_list.remove(block)
for bullet in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
for block in block_hit_list:
explosion.play()
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
score += 10
UPDATE
I have now managed to get the collision to detect properly, however I am still able to fire once the ships have disappeared (due to collision) is there any way I can hide the bullet once the collision has taken place?
Heres my updated code:
for i in range(15):
block = Block(BLACK)
block.rect.x = random.randrange(screen_width)
block.rect.y = random.randrange(55) # change to 155 collisions fixed
block_list.add(block)
all_sprites_list.add(block)
for i in range(1):
player = Player()
player.rect.y = 480
player_list.add(player)
all_sprites_list.add(player)
...
for player in player_list:
block_hit_list = pygame.sprite.spritecollide(player, block_list, True)
for block in block_hit_list:
gameover.play()
player_list.remove(player)
all_sprites_list.remove(player)
block_list.remove(block)
all_sprites_list.remove(block)
for bullet in bullet_list:
block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)
for block in block_hit_list:
explosion.play()
bullet_list.remove(bullet)
all_sprites_list.remove(bullet)
score += 10
Since you are working with groups, you might want to use this function, for handling collisions between groups:
Would be something like this (I haven't tried your code)
pygame.sprite.groupcollide(bullet_list, block_up_list, True, True, collided = None)
With both arguments True you remove both from the list. When you learn how to use groupcollide, you are going to notice that it's very useful.
Anyways, look for the function description in the pygame documentation and see some examples.
Hope that helps ;)

Resources