Welcome to the dungeon.
It's not a very fun dungeon (yet), but it's an extremely well-structured one.
This project is a classic challenge to demonstrate the four pillars of Object-Oriented Programming (OOP). We don't just write code; we build a system.
And this system has knights, goblins, and spike pits.
This project isn't just a file of code. It's a system built on these four core concepts.
We don't define a vague "thing." We create blueprints.
Entityis an Abstract Base Class (ABC). You can't make a plain "Entity."Combatantis also an ABC. You can't make a plain "Combatant."- They force their children (like
Player) to implement methods likeattack()andtake_damage(). This is our contract.
This is how we stop repeating code. We create a "family tree" of classes.
Entity (ABC)
|
+-- Combatant (ABC)
| |
| +-- Player (Concrete)
| |
| +-- Monster (Concrete)
|
+-- Trap (Concrete)
PlayerandMonsterget all the "Entity" stuff (likename,max_hp) for free.- This makes our code clean and easy to change.
We protect our data.
- Attributes like
_power,_max_hp, and_current_hpare "protected" (using the_convention). - You can't just set a player's health to 999. You must call a method like
take_damage(). - This prevents bugs and keeps our objects in a valid state.
This is the "magic" part. It means "many forms."
The attack() method can target any Entity. But the result is different depending on the object.
hero.attack(goblin): TheMonster.take_damage()method is called.hero.attack(spike_trap): TheTrap.take_damage()method is called, which prints "The attack has no effect!"
Same action. Different behaviors. That's polymorphism.
Here's a quick look at every "blueprint" in the system.
- The Grandparent. Everything in the game is an
Entity. - Abstract Methods:
is_alive(property),take_damage(amount) - Concrete Method:
get_health_percentage()
- The Parent. Any
Entitythat can fight. - Inherits from:
Entity - Attributes:
_power - Abstract Method:
attack(target)
- Our Hero. A concrete class you can create.
- Inherits from:
Combatant - Attributes:
player_class(e.g., "Knight") - Implements:
is_alive,take_damage(amount),attack(target)
- The Baddie. A concrete class for enemies.
- Inherits from:
Combatant - Attributes:
monster_type(e.g., "Goblin") - Implements:
is_alive,take_damage(amount),attack(target)
- The Odd One Out. A trap is an
Entity, but it is not aCombatant. - Inherits from:
Entity - Implements:
is_alive,take_damage(amount)(which just prints "no effect") - Special Method:
spring_trap(target): This is how the trap deals damage and then deactivates itself.
This is a self-contained script. It uses the random library (for attack rolls) but nothing else.
- Make sure you have Python installed.
- Run the file from your terminal: python
python Coding.py
(Or whatever you named the file)
The code doesn't just define classes; it also runs a small test simulation at the bottom.
- It creates Sir Bugsalot (the Player).
- It creates Grumble (the Monster).
- It creates a Spike Pit (the Trap).
- It makes Sir Bugsalot attack Grumble.
- It makes the Spike Pit spring on Sir Bugsalot.
- It prints the final status to prove the whole system works.