BWAPI
Public Member Functions | Private Attributes
DefenseSquadTask Class Reference

#include <DefenseSquad.h>

Inheritance diagram for DefenseSquadTask:
Inheritance graph
[legend]
Collaboration diagram for DefenseSquadTask:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 DefenseSquadTask (ArmyBehaviour behaviour)
virtual int getEndTime () const
virtual int getEndTime (Unit unit) const
virtual int getPriority (Unit unit) const
virtual Position getStartLocation (Unit unit) const
virtual Position getEndLocation (Unit unit) const
virtual bool preUpdate ()
virtual bool update ()
virtual bool waitingForUnit (Unit unit) const
virtual void giveUnit (Unit unit)
virtual void returnUnit (Unit unit)
virtual bool morph (Unit unit, BWAPI::UnitType previousType)
virtual UnitGroup getFinishedUnits ()
virtual std::string getTaskName () const
virtual std::string getOutputName () const
unsigned int controlSize ()
virtual void updateRequirements ()
void setGoal (Goal goal)

Private Attributes

UnitGroup mUnits
std::map< Unit, BehaviourmUnitBehaviours
int mNeededWorkers
bool mNeedsAntiAir
bool mNeedsAntiGround
UnitGroup mWorkerDefenders
Unit mObserver
Goal mDefenseGoal

Detailed Description

Definition at line 8 of file DefenseSquad.h.


Constructor & Destructor Documentation

Definition at line 9 of file DefenseSquad.cpp.

        : BaseSquadTask(behaviour)
        , mNeededWorkers(0)
        , mDefenseGoal()
{
}

Member Function Documentation

unsigned int DefenseSquadTask::controlSize ( ) [inline, virtual]

Implements BaseSquadTask.

Definition at line 33 of file DefenseSquad.h.

References mUnits, and UnitGroup::size().

{ return mUnits.size(); }

Here is the call graph for this function:

Position DefenseSquadTask::getEndLocation ( Unit  unit) const [virtual]

Implements BaseSquadTask.

Definition at line 67 of file DefenseSquad.cpp.

{
        return unit->getPosition();
}
int DefenseSquadTask::getEndTime ( ) const [virtual]

Implements BaseSquadTask.

Definition at line 16 of file DefenseSquad.cpp.

References Requirement::maxTime.

int DefenseSquadTask::getEndTime ( Unit  unit) const [virtual]

Implements BaseSquadTask.

Definition at line 21 of file DefenseSquad.cpp.

References Requirement::maxTime.

Implements BaseSquadTask.

Definition at line 126 of file DefenseSquad.cpp.

References mUnits.

{
        return mUnits;
}
virtual std::string DefenseSquadTask::getOutputName ( ) const [inline, virtual]

Implements BaseSquadTask.

Definition at line 31 of file DefenseSquad.h.

{ return ""; }
int DefenseSquadTask::getPriority ( Unit  unit) const [virtual]

Implements BaseSquadTask.

Definition at line 26 of file DefenseSquad.cpp.

References mNeededWorkers, mNeedsAntiAir, mNeedsAntiGround, mWorkerDefenders, and UnitGroup::size().

{
        if(!unit->getType().isWorker())
        {
                bool isNeeded = false;
                if(mNeedsAntiAir && unit->canAttackAir())
                        isNeeded = true;
                
                if(mNeedsAntiGround && unit->canAttackGround())
                        isNeeded = true;

                if(isNeeded)
                        return 30;
                else
                        return 1;
        }

        int workersToReturn = int(mWorkerDefenders.size()) - mNeededWorkers;
        if(workersToReturn > 0)
        {
                int count = 1;
                for each(Unit worker in mWorkerDefenders)
                {
                        if(worker == unit)
                        {
                                if(count <= workersToReturn)
                                        return 1;
                                break;
                        }
                        ++count;
                }
        }

        return 30;
}

Here is the call graph for this function:

Implements BaseSquadTask.

Definition at line 62 of file DefenseSquad.cpp.

{
        return unit->getPosition();
}
virtual std::string DefenseSquadTask::getTaskName ( ) const [inline, virtual]

Implements BaseSquadTask.

Definition at line 30 of file DefenseSquad.h.

{ return "Defense Squad"; }
void DefenseSquadTask::giveUnit ( Unit  unit) [virtual]

Implements BaseSquadTask.

Definition at line 96 of file DefenseSquad.cpp.

References UnitGroup::insert(), mObserver, mUnitBehaviours, mUnits, mWorkerDefenders, and BWAPI::UnitTypes::Protoss_Observer.

{
        if(unit->getType() == BWAPI::UnitTypes::Protoss_Observer)
                mObserver = unit;
        else if(unit->getType().isWorker())
                mWorkerDefenders.insert(unit);

        mUnits.insert(unit);

        mUnitBehaviours[unit] = Behaviour(unit);
}

Here is the call graph for this function:

bool DefenseSquadTask::morph ( Unit  unit,
BWAPI::UnitType  previousType 
) [virtual]

Implements BaseSquadTask.

Definition at line 121 of file DefenseSquad.cpp.

{
        return false;
}
bool DefenseSquadTask::preUpdate ( ) [virtual]

Implements BaseSquadTask.

Definition at line 72 of file DefenseSquad.cpp.

References Task::hasEnded(), and updateRequirements().

{
        updateRequirements();

        return hasEnded();
}

Here is the call graph for this function:

void DefenseSquadTask::returnUnit ( Unit  unit) [virtual]

Implements BaseSquadTask.

Definition at line 108 of file DefenseSquad.cpp.

References UnitGroup::erase(), mObserver, mUnitBehaviours, mUnits, mWorkerDefenders, and StaticUnits::nullunit.

{
        mUnits.erase(unit);

        mUnitBehaviours[unit].onDeleted();
        mUnitBehaviours.erase(unit);

        mWorkerDefenders.erase(unit);

        if(unit == mObserver)
                mObserver = StaticUnits::nullunit;
}

Here is the call graph for this function:

void DefenseSquadTask::setGoal ( Goal  goal) [inline]

Definition at line 37 of file DefenseSquad.h.

References mDefenseGoal.

Referenced by SquadManagerClass::update().

{ mDefenseGoal = goal; }

Here is the caller graph for this function:

bool DefenseSquadTask::update ( ) [virtual]

Implements BaseSquadTask.

Definition at line 79 of file DefenseSquad.cpp.

References ActionTypeDef::Attack, UnitGroup::empty(), Goal::getActionType(), Goal::getBase(), Task::hasEnded(), mDefenseGoal, mUnitBehaviours, mUnits, and BWAPI::BulletTypes::None.

{
        if(mDefenseGoal.getActionType() != ActionType::None)
        {
                Goal enemiesGoal(ActionType::Attack, mDefenseGoal.getBase()->getEnemyThreats());
                for(std::map<Unit, Behaviour>::iterator it = mUnitBehaviours.begin(); it != mUnitBehaviours.end(); ++it)
                        it->second.update(enemiesGoal, mUnits);
        }

        return hasEnded() && mUnits.empty();
}

Here is the call graph for this function:

Reimplemented from BaseSquadTask.

Definition at line 131 of file DefenseSquad.cpp.

References Task::addRequirement(), RequirementGroup::addUnitFilterRequirement(), BWAPI::Broodwar, UnitFilterFlags::CanAttackAir, UnitFilterFlags::CanAttackGround, Task::clearRequirements(), BWAPI::Game::drawTextMap(), Goal::getActionType(), Goal::getBase(), Task::hasEnded(), UnitFilterFlags::IsArmyUnit, UnitFilterFlags::IsComplete, UnitFilterFlags::IsWorker, Requirement::maxTime, mDefenseGoal, mNeededWorkers, mNeedsAntiAir, mNeedsAntiGround, mObserver, mUnits, mWorkerDefenders, BWAPI::BulletTypes::None, BWAPI::UnitTypes::Protoss_Observer, UnitGroup::size(), BWAPI::Position::x(), BWAPI::Position::y(), BWAPI::Races::Zerg, and BWAPI::UnitTypes::Zerg_Lurker.

Referenced by preUpdate().

{
        clearRequirements();
        mNeededWorkers = 0;
        mNeedsAntiAir = false;
        mNeedsAntiGround = false;

        // Basic idea is to have a defense goal for each base that will take only the amount of units it needs to take out the threat
        // and also take workers if it cannot take out the threat with the number of units it has

        // This should make it do important things such as kill the threat while the rest of the army in the default squad stay at the choke
        // stopping any other units from entering
        if(!hasEnded() && mDefenseGoal.getActionType() != ActionType::None)
        {
                //TODO: currently picks units based on it getting units with a score higher than 100, if its zerg it could get zerglings in which case it wont have enough
                // TODO: maybe do some modification based on current units health
                int AirThreatScore = 0;
                int GroundThreatScore = 0;
                int GroundThreatCount = 0;
                bool needsDetection = false;
                for each(Unit enemy in mDefenseGoal.getBase()->getEnemyThreats())
                {
                        if(!needsDetection && (enemy->getType().isCloakable() || enemy->getType().hasPermanentCloak() || enemy->isBurrowed() || enemy->getType() == BWAPI::UnitTypes::Zerg_Lurker))
                                needsDetection = true;

                        if(enemy->isLifted() || enemy->getType().isFlyer())
                        {
                                if(enemy->canAttackGround())
                                        AirThreatScore += enemy->getType().buildScore();
                                else if(enemy->getType().spaceProvided() > 0)
                                {
                                        if(enemy->getPlayer()->getRace() != BWAPI::Races::Zerg)
                                                AirThreatScore += 400;
                                        else if(BWAPI::Broodwar->getFrameCount() > 24*60*6) //TODO: has the player researched drop?
                                                AirThreatScore += 250;
                                        else
                                                AirThreatScore += 50;
                                }
                                else
                                        AirThreatScore += 50;
                        }
                        else
                        {
                                ++GroundThreatCount;
                                if(enemy->canAttackGround())
                                        GroundThreatScore += enemy->getType().buildScore();
                                else
                                        GroundThreatScore += 50;
                        }
                }

                // Temp till defense squad is good enough to use army units and not just workers
                if(needsDetection)
                        return;

                if(GroundThreatScore > 0)
                        mNeedsAntiGround = true;
                if(AirThreatScore > 0)
                        mNeedsAntiAir = true;

                int AntiAirScore = 0;
                int AntiGroundScore = 0;
                for each(Unit unit in mUnits)
                {
                        if(unit->getType().isWorker())
                                continue;

                        if(unit->canAttackGround())
                        {
                                --GroundThreatCount;
                                AntiGroundScore += unit->getType().buildScore();
                        }
                        if(unit->canAttackAir())
                                AntiAirScore += unit->getType().buildScore();
                }

                mNeededWorkers = std::max((GroundThreatScore - AntiGroundScore) / 50, 0);
                if(mNeededWorkers == 0 && (GroundThreatScore - AntiGroundScore) > 0)
                        mNeededWorkers = 1;

                if(mNeededWorkers < GroundThreatCount)
                        mNeededWorkers = GroundThreatCount;

                int canAttackGroundNeeded = mNeededWorkers / 2;

                if(mNeededWorkers > 14) mNeededWorkers = 0; //If we cannot defend with 14 workers, don't try, probably not worth possible losses
                if(mNeededWorkers > 1) mNeededWorkers += 1;
                if(mNeededWorkers > 2) mNeededWorkers += 1;
                if(mNeededWorkers > 14) mNeededWorkers = 14;

                int workersNeeded = std::max(mNeededWorkers - int(mWorkerDefenders.size()), 0);

                canAttackGroundNeeded -= (int(mWorkerDefenders.size()) / 2);

                // Get as many as we can for now
                // TODO: maybe check if its our only mining base or do something better
                for(int i = 0; i < workersNeeded; ++i)
                {
                        RequirementGroup reqWorkers;
                        reqWorkers.addUnitFilterRequirement(30, Requirement::maxTime, UnitFilter(UnitFilterFlags::type(UnitFilterFlags::IsWorker | UnitFilterFlags::IsComplete)), mDefenseGoal.getBase()->getCenterLocation());
                        addRequirement(reqWorkers);
                }

                // Temp till defense squad is good enough to use army units and not just workers
                // in the below state can cause the bots army to get too seperated and cause the main army to get possibly destroyed engaging a group elsewhere
                return;

                RequirementGroup reqMain;
                if(canAttackGroundNeeded > 0)
                        reqMain.addUnitFilterRequirement(30, Requirement::maxTime, UnitFilter(UnitFilterFlags::type(UnitFilterFlags::IsArmyUnit | UnitFilterFlags::CanAttackGround | UnitFilterFlags::IsComplete)), canAttackGroundNeeded, mDefenseGoal.getBase()->getCenterLocation());

                int canAttackAirNeeded = std::max((AirThreatScore - AntiAirScore) / 100, 0);
                if(canAttackAirNeeded > 0)
                        reqMain.addUnitFilterRequirement(30, Requirement::maxTime, UnitFilter(UnitFilterFlags::type(UnitFilterFlags::IsArmyUnit | UnitFilterFlags::CanAttackAir | UnitFilterFlags::IsComplete)), canAttackAirNeeded, mDefenseGoal.getBase()->getCenterLocation());

                if(!mObserver && needsDetection)
                        reqMain.addUnitFilterRequirement(30, Requirement::maxTime, UnitFilter(BWAPI::UnitTypes::Protoss_Observer) && UnitFilter(UnitFilterFlags::IsComplete), mDefenseGoal.getBase()->getCenterLocation());

                addRequirement(reqMain);

                Position goalpos = mDefenseGoal.getBase()->getCenterLocation();
                const int x = goalpos.x();
                const int y = goalpos.y();

                BWAPI::Broodwar->drawTextMap(x, y, "canAttackGroundNeeded : %d", canAttackGroundNeeded);
                BWAPI::Broodwar->drawTextMap(x, y+10, "canAttackAirNeeded : %d", canAttackAirNeeded);
                BWAPI::Broodwar->drawTextMap(x, y+20, "workersNeeded : %d", workersNeeded);
                BWAPI::Broodwar->drawTextMap(x, y+30, "workers Have : %d", int(mWorkerDefenders.size()));
                BWAPI::Broodwar->drawTextMap(x, y+40, "Units Have : %d", int(mUnits.size()));
                if(!mObserver && needsDetection)
                        BWAPI::Broodwar->drawTextMap(x, y+50, "Needs Observer");
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool DefenseSquadTask::waitingForUnit ( Unit  unit) const [virtual]

Implements BaseSquadTask.

Definition at line 91 of file DefenseSquad.cpp.

{
        return false;
}

Member Data Documentation

Definition at line 49 of file DefenseSquad.h.

Referenced by setGoal(), update(), and updateRequirements().

Definition at line 43 of file DefenseSquad.h.

Referenced by getPriority(), and updateRequirements().

Definition at line 44 of file DefenseSquad.h.

Referenced by getPriority(), and updateRequirements().

Definition at line 45 of file DefenseSquad.h.

Referenced by getPriority(), and updateRequirements().

Definition at line 48 of file DefenseSquad.h.

Referenced by giveUnit(), returnUnit(), and updateRequirements().

Definition at line 41 of file DefenseSquad.h.

Referenced by giveUnit(), returnUnit(), and update().

Definition at line 47 of file DefenseSquad.h.

Referenced by getPriority(), giveUnit(), returnUnit(), and updateRequirements().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines