How to use variables from one class in another class - python

I know this question has been asked before but for the life of me I can't seem to understand the answers so I'm here asking for some help with an example. I am not trying to waste anybodies time here so please don't internet yell at me!
I have a class called Enemy with variables. How do I access these variables in another class?
Heres my example.
import tkinter
from tkinter import ttk
class Enemy(object):
def __init__ (self, name, attack, defence, gold, health, experience):
self.name = name
self.attack = attack
self.defence = defence
self.gold = gold
self.health = health
self.experience = experience
Enemy1 = Enemy("Enemy Soldier", "5", "1", "10", "10", "30")
class Application(object):
def __init__(self):
self.enemyLabel = tkinter.Label(text= self.Enemy1.name)
self.enemyLabel.pack()
myApp = Application()
myApp.root.mainloop()
This is a very narrowed down version of my code.

You have to define enemy1 in the scope of Application.__init__:
class Enemy(object):
def init (self, name, attack, defence, gold, health, experience):
self.name = name
self.attack = attack
self.defence = defence
self.gold = gold
self.health = health
self.experience = experience
class Application(object):
def __init__(self):
self.enemy1 = Enemy("Enemy Soldier", "5", "1", "10", "10", "30")
self.enemyLabel = tkinter.Label(text=self.enemy1.name)
self.enemyLabel.pack()

Anywhere within the scope of where you created Enemy1, you can simply use Enemy1.name, Enemy1.attack, etc.

Related

How would I use multiple classes together without inheritance?

I am currently learning classes and applying it as I go but I have come across an issue I am not sure how to get past:
I do not know how would I define a character having a weapon.
I have looked into the problem elsewhere but it always leads to inheritance which I want to avoid as it would not make sense. Is there any way to do this? I will be showing both the relevant code to the issue and then below, the full code for classes used.
Relevant Code
Weapon Class
class weapon:
def __init__ (self):
<constructor>
def set_attack (self, attack):
self.attack = attack
def get_attack (self):
return self.attack
Character Class
class character:
def __init__ (self):
<constructor>
def set_attack (self, amount):
self.attack = amount
def get_attack (self):
return self.attack
Full Code
Weapon Class
class weapon:
def __init__ (self, name, attack, crit_chance, crit_bonus, rarity, type_bonus):
self.name = name
self.attack = attack
self.crit_chance = crit_chance
self.crit_bonus = crit_bonus
self.rarity = rarity
self.type_bonus = type_bonus
def set_name (self, name):
self.name = name
def set_attack (self, attack):
self.attack = attack
def set_crit_chance (self, crit_chance):
self.crit_chance = crit_chance
def set_crit_bonus (self, crit_bonus):
self.crit_bonus = crit_bonus
def set_rarity (self, rarity):
self.rarity = rarity
def set_type_bonus (self, type_bonus):
self.type_bonus = type_bonus
def get_name (self):
return self.name
def get_attack (self):
return self.attack
def get_crit_chance (self):
return self.crit_chance
def get_crit_bonus (self):
return self.crit_bonus
def get_rarity (self):
return self.rarity
def get_type_bonus (self):
return self.type_bonus
Character Class
class character:
def __init__ (self, name, max_health, current_health, attack):
self.name = name
self.max_health = max_health
self.current_health = current_health
self.attack = attack
def set_name (self, name):
self.name = name
def set_max_health (self, amount):
self.max_amount = amount
def set_current_health (self, amount):
self.current_health = amount
def set_attack (self, amount):
self.attack = amount
def get_name (self):
return self.name
def get_max_health (self):
return self.max_health
def get_current_health (self):
return self.current_health
def get_attack (self):
return self.attack
Player Class Inheriting From Character Class
class player (character):
def __init__ (self, name, max_health, current_health, attack, money, level, xp):
super().__init__(name, max_health, current_health, attack)
self.money = money
self.level = level
self.xp = xp
def set_money (self, amount):
self.money = amount
def set_level (self, amount):
self.level = amount
def set_xp (self, amount):
self.xp = amount
def get_money (self):
return self.money
def get_level (self):
return self.level
def get_xp (self):
return self.xp
I am expecting the player, which inherits from character, to be able to attack using the value of a weapon object tied to that character.
Any info is appreciated.emphasized text
To begin with you can get rid of all those getters and setters and make your classes as
class Weapon:
def __init__ (self, name, attack, crit_chance, crit_bonus, rarity, type_bonus):
self.name = name
self.attack = attack
self.crit_chance = crit_chance
self.crit_bonus = crit_bonus
self.rarity = rarity
self.type_bonus = type_bonus
class Character:
def __init__ (self, name, max_health, current_health, attack):
self.name = name
self.max_health = max_health
self.current_health = current_health
self.attack = attack
Then pass a weapon object to your player class, and use that to attack the player, here weapon represents the Weapon with the player
class Player (character):
def __init__ (self, name, max_health, current_health, attack, money, level, xp, weapon):
super().__init__(name, max_health, current_health, attack)
self.money = money
self.level = level
self.xp = xp
self.weapon = weapon
#For e.g. A weapon attacks and reduces the current health of the player
def attack(self):
self.current_health -= self.weapon.attack
Or pass both a weapon and character class object to your player class, otherplayer is the Player attacked, and weapon is the Weapon with the player
class Player (character):
def __init__ (self, name, max_health, current_health, attack, money, level, xp, otherplayer, weapon):
super().__init__(name, max_health, current_health, attack)
self.money = money
self.level = level
self.xp = xp
self.otherplayer = otherplayer
self.weapon = weapon
def attack(self):
self.otherplayer.current_health -= self.weapon.attack
The Character class would have a field that's an instance of the Weapon class, like this:
class Character:
def __init__ (self, name, max_health, current_health, attack, weapon):
self.name = name
self.max_health = max_health
self.current_health = current_health
self.attack = attack
self.weapon = weapon # this line
def set_name(self, name):
self.name = name
def set_weapon(self, weapon):
self.weapon = weapon
You'd just build a Weapon object and pass it to the Character object when constructing it (or via the setter method):
weapon = Weapon()
character = Character('Char Name', 100, 100, 20, weapon)
Now, as a side note, please name your classes using uppercase for the initial letter, it's a PEP8 convention. It helps differentiating class names from instances, otherwise you wouldn't be able to call the instances weapon and character in my example above.

Unresolved attribute reference '...' for class '...'

When I call the render() method in the Zombie class, I want to add an instance of the Zombie object into ZombieList.list. When I try to do this, it says
Unresolved attribute reference list for class ZombieList.
Should I try to do this another way?
class ZombieList:
def __init__(self):
self.list = []
for zombie in self.list:
ds.blit(zombie.image, (1000, random.randint(10, 790)))
class Zombie(object):
def __init__(self):
self.attack = 3
self.speed = 5
self.health = 30
self.image = pygame.image.load("Assets/green zombie.png")
self.zombieList = []
def render(self):
ZombieList.list.append(self)
You've to create a ZombieList object, where you can append the Zombie objects to.
You can add a Class Objects to to the class Zombie:
class Zombie(object):
zombies = ZombieList()
def __init__(self):
self.attack = 3
self.speed = 5
self.health = 30
self.image = pygame.image.load("Assets/green zombie.png")
def render(self):
Zombie.zombies.list.append(self)
You cannot append to a list of a class. You need to append to an instance of a class. For instance:
class ZombieList:
def __init__(self):
self.list = []
for zombie in self.list:
ds.blit(zombie.image, (1000, random.randint(10, 790)))
my_zombie_list = ZombieList() # create an instance
class Zombie(object):
def __init__(self):
self.attack = 3
self.speed = 5
self.health = 30
self.image = pygame.image.load("Assets/green zombie.png")
self.zombieList = []
def render(self):
my_zombie_list.list.append(self) # refer to the previously created instance
There is no attribute list in ZombieList. Only once you've created a ZombieList through e.g. self.zombie_list = ZombieList() will you be able to make use of your list through self.zombie_list.list.
Even then, though, I imagine this probably isn't the design you're aiming for: I imagine that you don't want a ZombieList for each individual Zombie. Rather, whoever is initializing the Zombie objects should probably be in charge of maintaining the ZombieList instance as well.
You will also run into other issues. For example, the loop in
self.list = []
for zombie in self.list:
ds.blit(zombie.image, (1000, random.randint(10, 790)))
will never have any effect since self.list is always empty when that code is executed (since you've defined it to be empty on the previous line).

How update variable within another class

I have these classes :
class Game():
def __init__(self):
self.player = Player("name")
class Turn():
def __init__(self):
pass
def end(self):
#how update xp player
class Player():
def __init__(self, name):
self.name = name
self.xp = 0
And my question is how when turn is terminated, how update the player
If these classes are in the same module you can define a global variable in the module that can be used in both classes. Otherwise you need to explicitly pass the variable on the instances of both classes.
Your Game class appears to have a reference to a player in its self.player attribute. If you want to update that player's xp attribute, you can do something like this:
def end(self):
self.player.xp += 5

How to add additional attributes to a class?

How would I add additional locationx and locationy variables to the lists while the program is running?
Example of the class:
class Building:
'Common base class for all buildings'
def __init__(self, name, hp, img, locationx, locationy, height, width):
self.name = name
self.hp = hp
self.img = img
self.locationx = locationx
self.locationy = locationy
self.height = height
self.width = width
building_shipyard = Building("Shipyard",500,shipyard,[1000,2500,5000],[1000,2500,5000],300,300)
For instance, after a user places a new building, I might want self.locationx and self.locationy to be updated from [1000,2500,5000] to [1000,2500,5000,7000].
Just access these attributes:
...
def place_building ():
global building_shipyard
...
building_shipyard.locationx = [1000,2500,5000,7000]
# or
building_shipyard.locationx.append(7000)

How to determinate whose turn is? Card game (tkinter)

I'm making Palace card game with 4 players, I'm not sure how should I determinate whose on turn for throwing a card? Should I use smoething like counter or what ?
Use a simple counter modulo the number of players.
class Game(object):
def __init__(self):
self.count = 4
self.current_player = 0
def next_turn(self):
self.current_player += 1
self.current_player %= self.count
Since different cards may lead to different players having the next turn, and to the game switching between going clockwise and counterclockwise, I suggest you leave the decision to the card object.
from abc import ABCMeta, abstractmethod
class Card(object):
__metaclass__ = ABCMeta
def __init__(self, color, value):
"""
Color is either "r", "b", "g", or "y". Value is 0-9.
"""
self.color = color
self.value = value
def is_valid(self, color, value=None):
return color in self.color or value == self.value
#abstractmethod
def card_effect(self, game):
pass
This base class for all cards is the "contract" that a class has to fulfill to be considered a card. Since we're not planning on instantiating this class we make it an abstract class.
class Normal(Card):
def card_effect(self, game):
game.increment_player_index(1)
class Skip(Card):
def __init__(self, color):
super(Skip, self).__init__(color, "skip")
def card_effect(self, game):
game.increment_player_index(2)
class Turn(Card):
def __init__(self, color):
super(Turn, self).__init__(color, "turn")
def card_effect(self, game):
game.toggle_direction()
game.increment_player_index(2)
class PlusTwo(Card):
def __init__(self, color):
super(PlusTwo, self).__init__(color, "+2")
def card_effect(self, game):
game.increment_player_index(1)
game.current_player().punish(2)
game.increment_player_index(1)
For the black cards we do it like this:
class PlusFour(Card):
def __init__(self):
super(PlusFour, self).__init__("rbgy", "+4")
def card_effect(self, game):
color = game.current_player().choose_color()
game.set_color(color)
game.increment_player_index(1)
game.current_player().punish(4)
game.increment_player_index(1)

Categories