Composition and Hero battle implementation
Composition
- A way to create objects made up of other objects.
- In composition, a class contains one or more objects of another class as instance variables.
- Provide layered functionality to the object.
- Known as a HAS-A relationship
Code example:
Engine class
class Engine:
def __init__(self, engineType):
self.engineType = engineType
def startEngine(self):
print("Engine is running")
def stopEngine(self):
print("Engine is off")
class Vehicle:
def __init__(self, type, forSale, engine):
self.type = type
self.forSale = forSale
self.engine = engine
Sample code to validate it.
engine = Engine("V6")
vehicle = Vehicle("Car", True, engine)
vehicle.engine.startEngine()
- Using composition here because the vehicle HAS-A engine.
- This is different from an interface IS-A relationship.
- A vehicle must have a engine, but an engine does not need to have a vehicle.
Composition implementation?
- We will create a new Hero class
- We will create a new Weapon class
- Our Hero will have a HAS-A(composition) relationship with our Weapon class
Code sample:
class Weapon:
def __init__(self, weapon_type, attack_increase):
self.weapon_type = weapon_type
self.attach_increase = attack_increase
class Hero:
def __init__(self, health_points, attack_damage):
self.health_points = health_points
self.attack_damage = attack_damage
self.is_weapon_equipped = False
self.weapon: Weapon = None
def equipWeapon(self):
if self.weapon is not None and not self.is_weapon_equipped:
self.attack_damage += self.weapon.attack_increase
self.is_weapon_equipped = True
main.py
def hero_battle(hero: Hero, enemy: Enemy):
while hero.health_points > 0 and enemy.health_points > 0:
enemy.special_attak()
enemy.attack()
hero.health_points -= enemy.attack_damage
hero.attack()
enemy.health_points -= hero.attack_damage
if hero.health_points > 0:
print("Hero Wins!")
else:
print("Enemy2 Wins!")
zombie = Zombie(10,1)
hero = Hero(10,1)
weapon = Weapon('Sword', 5)
hero.weapon = weapon
hero.equip_weapon()
hero_battle(hero, zombie)
Running code example:
Enemy class:
# Parent class Enemy is also known as super class or base class.
class Enemy:
def __init__(self, typeOfEnemy: str,
healthPoints: int = 10,
attack_damage: int = 1):
self.__typeOfEnemy = typeOfEnemy
self.healthPoints = healthPoints
self.attack_damage = attack_damage
def get_typeOfEnemy(self):
return self.__typeOfEnemy
def talk(self):
print(f"I am a {self.__typeOfEnemy}. Be prepared to fight!")
def walk_forward(self):
print(f"{self.__typeOfEnemy} moves closer to you!")
def attack(self):
print(f"{self.__typeOfEnemy} attacks you for {self.attack_damage} damage!")
def special_attack(self):
print(f"{self.__typeOfEnemy} has no special attack!")
Hero class:
# hero class file
from Weapon import Weapon
class Hero:
def __init__(self, health_points, attack_damage):
self.health_points = health_points
self.attack_damage = attack_damage
self.is_weapon_equipped = False
self.weapon: Weapon = None
print(f'New hero created! Health: {self.health_points}, Attack Damage: {self.attack_damage}')
def equip_weapon(self):
if self.weapon is not None and not self.is_weapon_equipped:
self.attack_damage += self.weapon.attack_increase
self.is_weapon_equipped = True
print(f'Hero has equipped a {self.weapon.weapon_type}.')
def attack(self):
print(f'Hero attacks for {self.attack_damage} damage!')
Ogre class:
# Child class of Enemy Ogre
from Enemy import Enemy
import random
class Orge(Enemy):
def __init__(self, healthPoints, attack_damage):
super().__init__(typeOfEnemy='Ogre', healthPoints=healthPoints,
attack_damage=attack_damage)
self.healthPoints = healthPoints
self.attack_damage = attack_damage
# method overriding
# This method is overriding the talk method of parent class Enemy
def talk(self):
print(f"Ogre: Smash them!")
def special_attack(self):
did_special_attack_work = random.random() < 0.20
if did_special_attack_work:
self.attack_damage += 4
print('Ogre attack has increased by 4!')
Weapon class:
# Weapon class file
class Weapon:
def __init__(self, weapon_type: str, attack_increase: int):
self.weapon_type = weapon_type
self.attack_increase = attack_increase
print(f'New weapon created! Type: {self.weapon_type}, Attack Increase:
{self.attack_increase}')
Zombie class:
# Child class of Enemy Zombie
from Enemy import Enemy
import random
class Zombie(Enemy):
def __init__(self, healthPoints, attack_damage):
super().__init__(typeOfEnemy='Zombie', healthPoints=healthPoints,
attack_damage=attack_damage)
self.healthPoints = healthPoints
self.attack_damage = attack_damage
# method overriding
# This method is overriding the talk method of parent class Enemy
def talk(self):
print(f"Zombie: Braaaains!")
# new method specific to Zombie class
def spread_diesease(self):
print(f"Zombie: Spreading disease!")
def special_attack(self):
did_special_attack_work = random.random() < 0.5
if did_special_attack_work:
self.healthPoints += 2
print('Zombie regerated 2 HP!')
main2.py
from Enemy import Enemy
from Zombie import Zombie
from Ogre import Orge
from Hero import Hero
from Weapon import Weapon
def battle(e1: Enemy, e2: Enemy): # We are passing parent object as parameter
e1.talk()
e2.talk()
while e1.healthPoints > 0 and e2.healthPoints > 0:
e1.special_attack()
e2.special_attack()
e2.attack()
e1.healthPoints -= e2.attack_damage
e1.attack()
e2.healthPoints -= e1.attack_damage
if e1.healthPoints > 0:
print("Enemy 1 wins!")
else:
print("Enemy 2 wins!")
zombie = Zombie(healthPoints=15, attack_damage=3)
ogre = Orge(healthPoints=25, attack_damage=7)
#battle(zombie, ogre)
def hero_battle(hero: Hero, enemy: Enemy): # We are passing parent object as parameter
while hero.health_points > 0 and enemy.healthPoints > 0:
print('-------------')
print(f'Hero: {hero.health_points} HP left')
print(f'{enemy.get_typeOfEnemy()}: {enemy.healthPoints} HP left')
print('-------------')
enemy.attack()
hero.health_points -= enemy.attack_damage
hero.attack()
enemy.healthPoints -= hero.attack_damage
if hero.health_points > 0:
print("Hero wins!")
else:
print(f"{enemy.get_typeOfEnemy()} wins!")
hero = Hero(health_points=20, attack_damage=1)
weapon = Weapon(weapon_type='Sword', attack_increase=15)
hero.weapon = weapon
hero.equip_weapon()
hero_battle(hero, ogre)


Comments
Post a Comment