I have defined the below code but there seems to be issues regarding methods load and damage.
(edited based on suggestions by ShadowRanger):
class RangedWeapon(Weapon):
def __init__(self, name, min_dmg, max_dmg):
super().__init__(name, min_dmg, max_dmg)
self.shots=0
def shots_left(self):
return self.shots
def load(self, ammo):
if ammo.weapon_type()==self.name:
self.shots+=ammo.get_quantity()
ammo.remove_all()
def damage(self):
if self.shots==0:
return 0
else:
self.shots-=1
return super().damage()
_
bow = RangedWeapon('bow', 10, 40)
crossbow = RangedWeapon('crossbow', 15, 45)
arrows = Ammo('arrow', bow, 5)
bolts = Ammo('bolt', crossbow, 10)
bow.load(arrows)
print(bow.shots_left()) # should return 5
print(arrows.get_quantity()) #should return 0
But for print(bow.shots_left()) I got 0 and print(arrows.get_quantity()) I got 5 instead. They are reversed. I think my problem is that I didn't load the Ammo quantity? I'm not very sure. Any help would be appreciated. Thank you!
class Ammo(Thing):
def __init__(self, name, weapon, quantity):
self.name=name
self.weapon=weapon
self.quantity=quantity
def get_quantity(self):
return self.quantity
def weapon_type(self):
return self.weapon.name
def remove_all(self):
self.quantity=0
1 Answer 1
Primary problem: Ammo's weapon_type is a method, not an attribute or property, and you didn't call it, so you're comparing the method itself to the name, not the result of calling it. This is the reason why load does nothing; no method is ever equal to a string.
Other issues:
It looks like you're calling methods on the class, not on the instances. You pass ammo (an instance) as an argument, then call methods on Ammo (the class).
Similarly, your damage method should probably be calling super().damage() not Weapon.damage(), since the latter doesn't use your instance state. And you've got typos (shots vs. shot) that should make this code non-functional in other ways.
Short version: This code is broken in a million ways, and you'll run into each of them as you fix the previous issues.
3 Comments
damage works well, but after calling weapon_type by callingammo.weapon_type()==self.name, the outputs are still reversed. How can I improve my code? thanks!Weapon or Thing. I just ran your code (substituting a trivial definition of Weapon, and just not inheriting from the irrelevant Thing) and it worked exactly as it is supposed to, the bow is loaded, the arrows are empty.get_quantity. Just access the quantity attribute directly. If you ever need to give it more logic, you can just reimplement as an @property (renaming any attribute to _quantity without changing the interface exposed to consumers of your class.
Ammoclass look like?ammovariable not the classAmmo