Skip to content
Advertisement

How can I keep all objects updated in this OOP example?

I don’t know exactly how to explain it, but I’ll try my best.

Here is a simple OOP example where you create players to kill a dragon. The point is to assign to each player a specific amount of damage to inflict on a dragon, in order to kill it.

For instance, if a dragon has 200 health and 2 players are chosen to attack it, the players will be assigned to deal 100 damage each.

Here’s the structure of the OOP:

class Player:

    def __init__(self, name):
        self.name = name
        self.damage_to_deal = {} #Format: {'dragon': damage to deal to him}

class Dragon:

    def __init__(self, name, health):
        self.name = name
        self.health = health
        self.number_of_players_attacking = 0

    #Add a player as someone who'll attack this dragon
    def add_player(self, player):
        self.number_of_players_attacking += 1
        player.damage_to_deal[self.name] = self.calculate_partition_damage()

    def calculate_partition_damage(self):
        if self.number_of_players_attacking == 0:
            self.partition_damage = 0
        else:
            self.partition_damage = self.health/self.number_of_players_attacking #health / number of players = damage to do for each player
        return self.partition_damage

Here are manipulations I’m testing:

#Create 3 players
player_A = Player(name='Josh')
player_B = Player(name='Steven')
player_C = Player(name='Robert')

#Create 2 Dragons
dragon_A = Dragon(name='Gamacial', health=475)
dragon_B = Dragon(name='Nibiru', health=150)

#All 3 players will attack the dragon A
dragon_A.add_player(player_A)
dragon_A.add_player(player_B)
dragon_A.add_player(player_C)

#Only player A and B will attack dragon B
dragon_B.add_player(player_A)
dragon_B.add_player(player_B)

#The damage each player will have to... {'to this dragon': x damage} to kill the dragons
print(f'{player_A.name} will have to do: {player_A.damage_to_deal}')
print(f'{player_B.name} will have to do: {player_B.damage_to_deal}')
print(f'{player_C.name} will have to do: {player_C.damage_to_deal}')

This prints the following:

Josh will have to do: {'Gamacial': 475.0, 'Nibiru': 150.0}
Steven will have to do: {'Gamacial': 237.5, 'Nibiru': 75.0}
Robert will have to do: {'Gamacial': 158.33333333333334}

The issue is that, since Josh is the first player to be tasked with killing Gamacial and Nibiru, he’s assigned to deal the full damage on these dragons, despite the fact that Steven and Robert are also tasked with killing that dragon.(Same issue with the dragon Nibiru).

In other words, it’ll always be the last player that’ll have the actual correct damage to deal, while the others will always be one step behind the calculation because they’ve been assigned the task before taking into count the next player.

It should therefore print:

Josh will have to do: {'Gamacial': 158.33333333333334, 'Nibiru': 75.0}
Steven will have to do: {'Gamacial': 158.33333333333334, 'Nibiru': 75.0}
Robert will have to do: {'Gamacial': 158.33333333333334}

Is there any way I keep ALL players in sync with each other? So after Steven gets assigned the same dragon as Josh, Josh gets updated, etc.?

Advertisement

Answer

maybe you should calculate later, after all player registered to dragons:

class Player:

    def __init__(self, name):
        self.name = name
        self.damage_to_deal = {} #Format: {'dragon': damage to deal to him}

    def deal_damage(self):
        for name in self.damage_to_deal:
            target = self.damage_to_deal[name] 
            self.damage_to_deal[name] = target.health / target.number_of_players_attacking
        return self.damage_to_deal 
        
class Dragon:

    def __init__(self, name, health):
        self.name = name
        self.health = health
        self.number_of_players_attacking = 0

    #Add a player as someone who'll attack this dragon
    def add_player(self, player):
        self.number_of_players_attacking += 1
        player.damage_to_deal[self.name] = self #  calculate later

register:

#Create 3 players
player_A = Player(name='Josh')
player_B = Player(name='Steven')
player_C = Player(name='Robert')

#Create 2 Dragons
dragon_A = Dragon(name='Gamacial', health=475)
dragon_B = Dragon(name='Nibiru', health=150)

#All 3 players will attack the dragon A
dragon_A.add_player(player_A)
dragon_A.add_player(player_B)
dragon_A.add_player(player_C)

#Only player A and B will attack dragon B
dragon_B.add_player(player_A)
dragon_B.add_player(player_B)

then calculate:

#The damage each player will have to... {'to this dragon': x damage} to kill the dragons
print(f'{player_A.name} will have to do: {player_A.deal_damage()}')
print(f'{player_B.name} will have to do: {player_B.deal_damage()}')
print(f'{player_C.name} will have to do: {player_C.deal_damage()}')
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement