diff --git a/ArmyClasses/Army.cpp b/ArmyClasses/Army.cpp index f10a739..43a16e4 100644 --- a/ArmyClasses/Army.cpp +++ b/ArmyClasses/Army.cpp @@ -2,17 +2,4 @@ #include "../Game.h" Army::Army(Game* gamePtr): gamePtr(gamePtr) -{} - -void Army::printFightingUnits() -{ - Unit* unit = nullptr; - - while (currentAttackers.dequeue(unit)) - unit->printFought(); -} - -int Army::getFightingUnitsCount() const -{ - return currentAttackers.getCount(); -} +{} \ No newline at end of file diff --git a/ArmyClasses/Army.h b/ArmyClasses/Army.h index d7a4711..98fbe77 100644 --- a/ArmyClasses/Army.h +++ b/ArmyClasses/Army.h @@ -24,11 +24,9 @@ class Army virtual bool isDead() const = 0; // Check if the army is dead virtual void printArmy() const = 0; // Print the army units - void printFightingUnits(); // Print the fighting units of the army (current attackers) // Getters virtual int getUnitsCount(UnitType) const = 0; // Get the count of a specific unit type - int getFightingUnitsCount() const; // Get the count of fighting units }; #endif \ No newline at end of file diff --git a/Game.cpp b/Game.cpp index 593f9ae..f349dd9 100644 --- a/Game.cpp +++ b/Game.cpp @@ -100,11 +100,6 @@ bool Game::battleOver(bool didArmiesAttack) const return currentTimestep >= 40 && (anArmyDied || noAttackTie); } -bool Game::areUnitsFighting() const -{ - return earthArmy.getFightingUnitsCount() + alienArmy.getFightingUnitsCount(); -} - void Game::killSaverUnits() { Unit* saverToKill = earthAlliedArmy.removeUnit(UnitType::SU); // Remove a saver from its list @@ -245,6 +240,13 @@ LinkedQueue Game::getEnemyList(ArmyType armyType, UnitType unitType, int return enemyUnits; } +void Game::registerAttack(Unit* currentAttacker, const std::string& currentAction, const std::string& currentFoughtUnits) +{ + attackers.enqueue(currentAttacker); // Store the current attacker + attackActions.enqueue(currentAction); // Store the action it made + foughtUnits.enqueue(currentFoughtUnits); // Store the list of units the action happened on +} + void Game::addToKilledList(Unit* unit) { // Add the unit to the killed list @@ -309,12 +311,17 @@ void Game::printAll() std::cout << std::endl << "============== Earth Allied Army Alive Units ===================" << std::endl; earthAlliedArmy.printArmy(); - if (areUnitsFighting()) + if (!attackers.isEmpty()) { std::cout << std::endl << "============== Units fighting at current step =================" << std::endl; - earthArmy.printFightingUnits(); - alienArmy.printFightingUnits(); - earthAlliedArmy.printFightingUnits(); + Unit* currentAttacker = nullptr; + std::string currentFoughtUnits, currentAction; + + while (attackers.dequeue(currentAttacker) && attackActions.dequeue(currentAction) && foughtUnits.dequeue(currentFoughtUnits)) + { + currentAttacker->printUnit(); + std::cout << " " << currentAction << " [" << currentFoughtUnits << "]" << std::endl; + } } else std::cout << std::endl << "============== No units fighting at current step ==============" << std::endl; diff --git a/Game.h b/Game.h index ce50a37..7228a83 100644 --- a/Game.h +++ b/Game.h @@ -23,6 +23,10 @@ class Game EarthAlliedArmy earthAlliedArmy; RandomGenerator randomGenerator; + LinkedQueue attackers; // Attackers of the current time step + LinkedQueue foughtUnits; // Units attacked by each attacker in the current timestep + LinkedQueue attackActions; // Action done on the unit of the opposite army + LinkedQueue killedList; PriorityQueue unitMaintenanceList; @@ -30,7 +34,6 @@ class Game bool startAttack(); // Makes the two armies attack each other void setGameMode(GameMode); // Change the game mode bool battleOver(bool) const; // Check if the battle is over - bool areUnitsFighting() const; // Check if there are units fighting void killSaverUnits(); // Savers need to be killed once all infected units are healed void printKilledList() const; // Prints the killed list with the console formats @@ -57,6 +60,7 @@ class Game void addUnit(Unit*); // Add a unit to the appropriate army and list Unit* removeUnit(ArmyType, UnitType); // Remove a unit from the appropriate army and list LinkedQueue getEnemyList(ArmyType, UnitType, int); // Get the enemy list for the given army type, unit type and attack capacity + void registerAttack(Unit*, const std::string&, const std::string&); // Store the current attacker along with its fought units void addToKilledList(Unit*); // Add a unit to the killed list diff --git a/UnitClasses/AlienDrone.cpp b/UnitClasses/AlienDrone.cpp index 1328c6a..35a7d54 100644 --- a/UnitClasses/AlienDrone.cpp +++ b/UnitClasses/AlienDrone.cpp @@ -5,16 +5,9 @@ AlienDrone::AlienDrone(Game* gamePtr, double health, int power, int attackCapaci : Unit(gamePtr, UnitType::AD, health, power, attackCapacity) {} -void AlienDrone::printFought() +void AlienDrone::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "AD " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "AD " << id; } bool AlienDrone::attack() @@ -27,6 +20,8 @@ bool AlienDrone::attack() LinkedQueue ETlist = gamePtr->getEnemyList(ArmyType::EARTH, UnitType::ET, ETnumber); LinkedQueue EGlist = gamePtr->getEnemyList(ArmyType::EARTH, UnitType::EG, EGnumber); + std::string foughtUnits = ""; + // Check for a successful attack bool attackCheck = false; @@ -47,7 +42,9 @@ bool AlienDrone::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -56,5 +53,8 @@ bool AlienDrone::attack() attackCheck = true; } + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + return attackCheck; } \ No newline at end of file diff --git a/UnitClasses/AlienDrone.h b/UnitClasses/AlienDrone.h index 6b5a7af..a1cc9e6 100644 --- a/UnitClasses/AlienDrone.h +++ b/UnitClasses/AlienDrone.h @@ -9,7 +9,7 @@ class AlienDrone: public Unit public: AlienDrone(Game*, double, int, int); - void printFought(); // Print the units that the drone has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units }; diff --git a/UnitClasses/AlienMonster.cpp b/UnitClasses/AlienMonster.cpp index dbf8b05..cf02483 100644 --- a/UnitClasses/AlienMonster.cpp +++ b/UnitClasses/AlienMonster.cpp @@ -12,16 +12,9 @@ void AlienMonster::setInfectingProbability(int probability) infectingProbability = probability; } -void AlienMonster::printFought() +void AlienMonster::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "AM " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "AM " << id; } bool AlienMonster::attack() @@ -36,6 +29,8 @@ bool AlienMonster::attack() LinkedQueue tanksList = gamePtr->getEnemyList(ArmyType::EARTH, UnitType::ET, tanksCapacity); LinkedQueue saversList = gamePtr->getEnemyList(ArmyType::EARTH_ALLIED, UnitType::SU, saversCapacity); + std::string foughtUnits = "", infectedSoldiers = ""; + // Check for a successful attack bool attackCheck = false; @@ -51,6 +46,12 @@ bool AlienMonster::attack() { dynamic_cast(enemyUnit)->getInfection(); // The soldier will get infected if not infected already and not immune gamePtr->addUnit(enemyUnit); // The soldier will be re-enqueued to the list & infected soldiers counter will be incremented + + // Store the IDs of the fought units to be printed later + if (infectedSoldiers != "") + infectedSoldiers += ", "; + infectedSoldiers += std::to_string(enemyUnit->getId()); + continue; } @@ -66,7 +67,9 @@ bool AlienMonster::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -75,5 +78,10 @@ bool AlienMonster::attack() attackCheck = true; } + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + if (infectedSoldiers != "") + gamePtr->registerAttack(this, "infects", infectedSoldiers); + return attackCheck; } \ No newline at end of file diff --git a/UnitClasses/AlienMonster.h b/UnitClasses/AlienMonster.h index 80d943f..fda49c4 100644 --- a/UnitClasses/AlienMonster.h +++ b/UnitClasses/AlienMonster.h @@ -15,7 +15,7 @@ class AlienMonster: public Unit // Static functions static void setInfectingProbability(int); // Set the infecting probability - void printFought(); // Print the units that the monster has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units }; diff --git a/UnitClasses/AlienSoldier.cpp b/UnitClasses/AlienSoldier.cpp index 4926669..e514b38 100644 --- a/UnitClasses/AlienSoldier.cpp +++ b/UnitClasses/AlienSoldier.cpp @@ -5,16 +5,9 @@ AlienSoldier::AlienSoldier(Game* gamePtr, double health, int power, int attackCa : Unit(gamePtr, UnitType::AS, health, power, attackCapacity) {} -void AlienSoldier::printFought() +void AlienSoldier::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "AS " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "AS " << id; } bool AlienSoldier::attack() @@ -27,6 +20,8 @@ bool AlienSoldier::attack() LinkedQueue soldiersList = gamePtr->getEnemyList(ArmyType::EARTH, UnitType::ES, soldiersCapacity); LinkedQueue saversList = gamePtr->getEnemyList(ArmyType::EARTH_ALLIED, UnitType::SU, saversCapacity); + std::string foughtUnits = ""; + // Check for a successful attack bool attackCheck = false; @@ -47,7 +42,9 @@ bool AlienSoldier::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -56,5 +53,8 @@ bool AlienSoldier::attack() attackCheck = true; } + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + return attackCheck; } \ No newline at end of file diff --git a/UnitClasses/AlienSoldier.h b/UnitClasses/AlienSoldier.h index 76ab034..820ef3b 100644 --- a/UnitClasses/AlienSoldier.h +++ b/UnitClasses/AlienSoldier.h @@ -9,7 +9,7 @@ class AlienSoldier: public Unit public: AlienSoldier(Game*, double, int, int); - void printFought(); // Print the units that the soldier has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units }; diff --git a/UnitClasses/EarthGunnery.cpp b/UnitClasses/EarthGunnery.cpp index bf45a97..49829dc 100644 --- a/UnitClasses/EarthGunnery.cpp +++ b/UnitClasses/EarthGunnery.cpp @@ -5,16 +5,9 @@ EarthGunnery::EarthGunnery(Game* gamePtr, double health, int power, int attackCa : Unit(gamePtr, UnitType::EG, health, power, attackCapacity) {} -void EarthGunnery::printFought() +void EarthGunnery::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "EG " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "EG " << id; } bool EarthGunnery::attack() @@ -29,6 +22,8 @@ bool EarthGunnery::attack() LinkedQueue dronesList = gamePtr->getEnemyList(ArmyType::ALIEN, UnitType::AD, dronesCapacity); LinkedQueue monstersList = gamePtr->getEnemyList(ArmyType::ALIEN, UnitType::AM, monstersCapacity); + std::string foughtUnits = ""; + // Check for a successful attack bool attackCheck = false; @@ -47,7 +42,9 @@ bool EarthGunnery::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -55,6 +52,10 @@ bool EarthGunnery::attack() // If this line is reached, at least one unit was attacked attackCheck = true; } + + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + return attackCheck; } diff --git a/UnitClasses/EarthGunnery.h b/UnitClasses/EarthGunnery.h index 37fa80e..c1bfa8d 100644 --- a/UnitClasses/EarthGunnery.h +++ b/UnitClasses/EarthGunnery.h @@ -9,7 +9,7 @@ class EarthGunnery: public Unit public: EarthGunnery(Game*, double, int, int); - void printFought(); // Print the units that the gunnery has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units // Getters diff --git a/UnitClasses/EarthSoldier.cpp b/UnitClasses/EarthSoldier.cpp index c3ca4de..29d3569 100644 --- a/UnitClasses/EarthSoldier.cpp +++ b/UnitClasses/EarthSoldier.cpp @@ -6,20 +6,16 @@ EarthSoldier::EarthSoldier(Game* gamePtr, double health, int power, int attackCa : HealableUnit(gamePtr, UnitType::ES, health, power, attackCapacity), infected(false), immune(false) {} -void EarthSoldier::printFought() +void EarthSoldier::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "ES " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "ES " << id; + if (infected) + std::cout << "*"; } bool EarthSoldier::attack() { + std::string foughtUnits = ""; // Check if the unit is infected and decide what to attack ArmyType enemyArmyType = isInfected() ? ArmyType::EARTH : ArmyType::ALIEN; UnitType enemyUnitType = isInfected() ? UnitType::ES : UnitType::AS; @@ -45,7 +41,9 @@ bool EarthSoldier::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -54,6 +52,9 @@ bool EarthSoldier::attack() attackCheck = true; } + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + return attackCheck; } diff --git a/UnitClasses/EarthSoldier.h b/UnitClasses/EarthSoldier.h index b28cab8..3541558 100644 --- a/UnitClasses/EarthSoldier.h +++ b/UnitClasses/EarthSoldier.h @@ -13,7 +13,7 @@ class EarthSoldier: public HealableUnit public: EarthSoldier(Game*, double, int, int); - void printFought(); // Print the units that the soldier has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units // Infection and immunity functions diff --git a/UnitClasses/EarthTank.cpp b/UnitClasses/EarthTank.cpp index 0b581bd..fd2a309 100644 --- a/UnitClasses/EarthTank.cpp +++ b/UnitClasses/EarthTank.cpp @@ -10,16 +10,9 @@ EarthTank::EarthTank(Game* gamePtr, double health, int power, int attackCapacity : HealableUnit(gamePtr, UnitType::ET, health, power, attackCapacity) {} -void EarthTank::printFought() +void EarthTank::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "ET " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "ET " << id; } bool EarthTank::attack() @@ -32,6 +25,8 @@ bool EarthTank::attack() LinkedQueue monsterEnemyList = gamePtr->getEnemyList(ArmyType::ALIEN, UnitType::AM, monstersAttackCapacity); LinkedQueue soldierEnemyList = gamePtr->getEnemyList(ArmyType::ALIEN, UnitType::AS, soldiersAttackCapacity); + std::string foughtUnits = ""; + // Check for a successful attack bool attackCheck = false; @@ -50,7 +45,9 @@ bool EarthTank::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -59,6 +56,9 @@ bool EarthTank::attack() attackCheck = true; } + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + return attackCheck; } diff --git a/UnitClasses/EarthTank.h b/UnitClasses/EarthTank.h index bfcb12e..a82a7ed 100644 --- a/UnitClasses/EarthTank.h +++ b/UnitClasses/EarthTank.h @@ -12,7 +12,7 @@ class EarthTank: public HealableUnit public: EarthTank(Game*, double, int, int); - void printFought(); // Print the units that the tank has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units bool willAttackSoldiers(); // Check if the tank will attack soldiers in the current timestep diff --git a/UnitClasses/HealUnit.cpp b/UnitClasses/HealUnit.cpp index b2dd034..08f4e9d 100644 --- a/UnitClasses/HealUnit.cpp +++ b/UnitClasses/HealUnit.cpp @@ -5,16 +5,9 @@ HealUnit::HealUnit(Game* gamePtr, double health, int power, int attackCapacity) : Unit(gamePtr, UnitType::EH, health, power, attackCapacity) {} -void HealUnit::printFought() +void HealUnit::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "EH " << getId() << " heals ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "HU " << id; } bool HealUnit::attack() @@ -22,6 +15,8 @@ bool HealUnit::attack() // Get the list of units to heal LinkedQueue unitsToHeal = gamePtr->getUnitsToMaintainList(attackCapacity); + std::string healedUnits = ""; + // Create a pointer to the unit to heal HealableUnit* unitToHeal = nullptr; @@ -56,7 +51,9 @@ bool HealUnit::attack() gamePtr->addUnitToMaintenanceList(unitToHeal); // Add it back to the UML if not completely healed // Store the IDs of the units that received heal to be printed later - foughtUnits.enqueue(unitToHeal->getId()); + if (healedUnits != "") + healedUnits += ", "; + healedUnits += std::to_string(unitToHeal->getId()); // Nullify the pointer unitToHeal = nullptr; @@ -65,6 +62,9 @@ bool HealUnit::attack() healCheck = true; } + if (healedUnits != "") + gamePtr->registerAttack(this, "heals", healedUnits); + return healCheck; } diff --git a/UnitClasses/HealUnit.h b/UnitClasses/HealUnit.h index b8d03f0..db83d17 100644 --- a/UnitClasses/HealUnit.h +++ b/UnitClasses/HealUnit.h @@ -10,7 +10,7 @@ class HealUnit: public Unit public: HealUnit(Game*, double, int, int); - void printFought(); // Print the units that the tank has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Heal units from the unit maintenance list void healInfection(EarthSoldier*); // Heal the infection of the soldier diff --git a/UnitClasses/SaverUnit.cpp b/UnitClasses/SaverUnit.cpp index b39151a..3407c50 100644 --- a/UnitClasses/SaverUnit.cpp +++ b/UnitClasses/SaverUnit.cpp @@ -7,16 +7,9 @@ SaverUnit::SaverUnit(Game* gamePtr, double health, int power, int attackCapacity : Unit(gamePtr, UnitType::SU, health, power, attackCapacity) {} -void SaverUnit::printFought() +void SaverUnit::printUnit() { - if (!foughtUnits.isEmpty()) - { - std::cout << "SU " << getId() << " shots ["; - foughtUnits.printList(); - std::cout << "]" << std::endl; - - clearFoughtUnits(); // Clear the list after printing - } + std::cout << "SU " << id; } bool SaverUnit::attack() @@ -24,6 +17,8 @@ bool SaverUnit::attack() // Get the lists of alien soldiers to attack LinkedQueue enemyList = gamePtr->getEnemyList(ArmyType::ALIEN, UnitType::AS, attackCapacity); + std::string foughtUnits = ""; + // Check for a successful attack bool attackCheck = false; @@ -42,7 +37,9 @@ bool SaverUnit::attack() gamePtr->addUnit(enemyUnit); // Store the IDs of the fought units to be printed later - foughtUnits.enqueue(enemyUnit->getId()); + if (foughtUnits != "") + foughtUnits += ", "; + foughtUnits += std::to_string(enemyUnit->getId()); // Nullify the pointer enemyUnit = nullptr; @@ -51,5 +48,8 @@ bool SaverUnit::attack() attackCheck = true; } + if (foughtUnits != "") + gamePtr->registerAttack(this, "shots", foughtUnits); + return attackCheck; } diff --git a/UnitClasses/SaverUnit.h b/UnitClasses/SaverUnit.h index 0844b59..c7bf4d4 100644 --- a/UnitClasses/SaverUnit.h +++ b/UnitClasses/SaverUnit.h @@ -9,7 +9,7 @@ class SaverUnit: public Unit public: SaverUnit(Game*, double, int, int); - void printFought(); // Print the units that the soldier has fought + void printUnit(); // Print the unit's type along with its ID bool attack(); // Attack the enemy units }; diff --git a/UnitClasses/Unit.cpp b/UnitClasses/Unit.cpp index d549e51..c2569dc 100644 --- a/UnitClasses/Unit.cpp +++ b/UnitClasses/Unit.cpp @@ -66,12 +66,6 @@ double Unit::calcUAP(Unit* receivingUnit) const return (power * health / 100) / sqrt(receivingUnit->health); } -void Unit::clearFoughtUnits() -{ - int i = 0; - while (foughtUnits.dequeue(i)); -} - void Unit::receiveDamage(double UAP) { // Decrement the unit's health, force it to its minimum value if it exceeded it diff --git a/UnitClasses/Unit.h b/UnitClasses/Unit.h index 02878e1..0818bc8 100644 --- a/UnitClasses/Unit.h +++ b/UnitClasses/Unit.h @@ -33,14 +33,11 @@ class Unit int power; // Attack power int attackCapacity; // Attack capacity - LinkedQueue foughtUnits; // A list of the units fought in the current timestep to be printed - private: void setHealth(double); // Health setter with range check & initial health saving to be used in constructor protected: double calcUAP(Unit*) const; // Calculates the damage caused when attacked by "attackerUnit" - void clearFoughtUnits(); // Clear the list of fought units public: Unit(Game*, UnitType, double, int, int); @@ -53,7 +50,7 @@ class Unit void receiveDamage(double); // Decrease the health of the unit by "UAP" virtual bool attack() = 0; // Attack the enemy units - virtual void printFought() = 0; // Print the units that the soldier has fought in the current timestep utilizing the foughtUnits list + virtual void printUnit() = 0; // Print the unit's type along with its ID virtual bool needsHeal() const; // Check if the unit is eligible for healing bool isDead() const; // Check if the unit is dead