Game Character Development
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 90 of 91.
Challenge
EasyLet's build a Game Character Development system where different character classes battle using unique abilities. You'll create a hierarchy of characters with an experience and leveling system, demonstrating how inheritance, interfaces, traits, and encapsulation work together in a game context.
You'll organize your code across six files:
Ability.php— Define anAbilityinterface with two methods:getName(): stringanduse(Character $target): string. This contract ensures all abilities can be used consistently regardless of their specific effects.CombatLogger.php— Create aCombatLoggertrait that provides alogAction(string $action): stringmethod. This method should return the action string prefixed with"[COMBAT] ". Characters will use this trait to format their combat messages consistently.Character.php— Include the Ability and CombatLogger files. Create an abstractCharacterclass that uses theCombatLoggertrait. Use constructor promotion forname(string, public readonly). Include private properties forhealth(int, starting at 100),level(int, starting at 1), andexperience(int, starting at 0). Implement:getHealth(): intandgetLevel(): int— getters for the private propertiestakeDamage(int $amount): void— reduces health but never below 0heal(int $amount): void— increases health but never above 100gainExperience(int $xp): string— adds XP; if experience reaches 100 or more, level up (reset XP to 0, increase level, heal 20 HP), return"[name] leveled up to [level]!"; otherwise return"[name] gained [xp] XP"isAlive(): bool— returns true if health is greater than 0abstract getSpecialAbility(): Ability— each character type provides their unique abilityattack(Character $target): string— deals 10 damage to target, useslogAction()to return"[COMBAT] [name] attacks [target name] for 10 damage"
Warrior.php— Include the Character file. Create aWarriorclass extendingCharacter. ImplementgetSpecialAbility()to return an anonymous class implementingAbility:getName()returns"Shield Bash"use()deals 25 damage and returns"[COMBAT] Shield Bash hits [target name] for 25 damage!"(use the trait'slogAction())
Mage.php— Include the Character file. Create aMageclass extendingCharacter. ImplementgetSpecialAbility()to return an anonymous class implementingAbility:getName()returns"Fireball"use()deals 35 damage and returns"[COMBAT] Fireball engulfs [target name] for 35 damage!"
main.php— Include the Warrior and Mage files. You'll receive two inputs: character data (JSON) and a sequence of combat actions (JSON).Characters JSON format:
[{"type": "warrior", "name": "Thorin"}, {"type": "mage", "name": "Gandalf"}]Actions JSON format:
[{"action": "attack", "attacker": 0, "target": 1}, {"action": "special", "attacker": 1, "target": 0}, {"action": "xp", "character": 0, "amount": 100}, {"action": "status", "character": 0}]Create all characters and store them in an array (index 0, 1, etc.). Process each action:
"attack"— Character at attacker index attacks target; print the result"special"— Character uses their special ability on target; print the result"xp"— Character gains experience; print the result"heal"— Character heals by the given amount; print"[name] healed to [health] HP""status"— Print"[name] - Level [level], HP: [health], Alive: [Yes/No]"
Print each result on a new line.
This system demonstrates how abstract classes define shared character behavior, interfaces ensure abilities follow a consistent contract, traits provide reusable logging functionality, and anonymous classes create unique ability implementations without cluttering your codebase with single-use classes.
Try it yourself
<?php
require_once 'Warrior.php';
require_once 'Mage.php';
// Read input
$charactersJson = trim(fgets(STDIN));
$actionsJson = trim(fgets(STDIN));
// Parse JSON inputs
$charactersData = (array)json_decode($charactersJson, true);
$actionsData = (array)json_decode($actionsJson, true);
// TODO: Create an array to store character objects
$characters = [];
// TODO: Loop through $charactersData and create Warrior or Mage objects
// based on the "type" field, store them in $characters array
// TODO: Process each action in $actionsData
// Handle these action types:
// - "attack": Character at attacker index attacks target; print result
// - "special": Character uses getSpecialAbility()->use() on target; print result
// - "xp": Character gains experience; print result
// - "heal": Character heals; print "[name] healed to [health] HP"
// - "status": Print "[name] - Level [level], HP: [health], Alive: [Yes/No]"
?>All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern