BWAPI
BasicAIModule/source/Managers/CombatManager.cpp
Go to the documentation of this file.
00001 #include "CombatManager.h"
00002 #include "Common.h"
00003 #include "Squad.h"
00004 
00005 #include <BWAPI.h>
00006 #include <BWTA.h>
00007 
00008 #include <string>
00009 
00010 using namespace BWAPI;
00011 using BWTA::Chokepoint;
00012 
00013 using namespace std;
00014 
00015 
00016 void CombatManager::onMatchStart()
00017 {
00018     Player* enemy = Broodwar->enemy();
00019     if( enemy != NULL )
00020     {
00021         // Get the likely enemy base location (furthest from myStart)
00022         // TODO - this should probably be calculated only once, 
00023         // maybe we should have a Manager::onMatchStart() method?
00024         TilePosition myStart = Broodwar->self()->getStartLocation();
00025         TilePosition target;
00026         double maxDistance = 0.0;
00027         set<TilePosition>& startPositions = Broodwar->getStartLocations();
00028         set<TilePosition>::iterator pit  = startPositions.begin();
00029         set<TilePosition>::iterator pend = startPositions.end();
00030         for(; pit != pend; ++pit)
00031         {
00032             TilePosition pos = *pit;
00033             const double distance = pos.getDistance(myStart);
00034             if( distance > maxDistance )
00035             {
00036                 target = pos;
00037                 maxDistance = distance;
00038             }
00039         }
00040 
00041         enemyBase = Position(target);
00042     }
00043 }
00044 
00045 void CombatManager::update()
00046 {
00047         // Get new agents into state
00048         addNewAgents();  
00049 
00050         // TODO : Merge squads
00051 
00052         // Attack?
00053         const int numTroops = agents.size();
00054     const int threshold = 50;
00055 
00056     if( numTroops >= threshold )
00057     {
00058         // Attack with full force (adjust to lower)
00059                 for (SquadVectorIter it = squads.begin(); it != squads.end(); it++)
00060                 {
00061                         Agent *a = (*it)->getLeader();
00062                         if (a != NULL)
00063                         {
00064                                 a->setState(AttackState);
00065                                 a->setPositionTarget(enemyBase);
00066                         }
00067                 }
00068         }
00069 
00070         /* Update squads */
00071         for (SquadVectorIter it = squads.begin(); it != squads.end(); it++)
00072         {
00073                 (*it)->update();
00074         }
00075         /* Base class updates Agents */
00076         Manager::update();
00077 }
00078 
00079 
00080 void CombatManager::addNewAgents()
00081 {
00082         // If we have any new Agents, they should go in the unassigned set
00083     AgentSetIter it  = agents.begin();
00084     AgentSetIter end = agents.end();
00085     for(; it != end; ++it)
00086     {
00087         Agent *agent = *it;
00088         if( assignedAgents.find(agent) == assignedAgents.end() ) 
00089         {
00090             unassignedAgents.insert(agent);
00091             // TODO - this is a hack to make them defend in the right place
00092             Chokepoint *cp = BWTA::getNearestChokepoint(agent->getUnit().getPosition());
00093             if( cp != NULL )
00094                 agent->setPositionTarget(cp->getCenter());
00095             else 
00096                 agent->setPositionTarget(Position(Broodwar->self()->getStartLocation()));
00097 
00098                         // Assign Agent to a Squad (only 1 atm)
00099                         if (squads.empty())
00100                         {
00101                                 squads.push_back(new Squad());
00102                         }
00103                         // Create a new squad if current is full
00104                         if (squads.back()->getAgents().size() > 10)
00105                         {
00106                                 squads.push_back(new Squad());
00107                         }
00108                         Squad *squad = squads.back();
00109 
00110                         squad->addAgent(*it);
00111                         if (squad->getLeader() == NULL)
00112                         {
00113                                 squad->setLeader(*it);
00114                         }
00115                 unassignedAgents.erase(agent);
00116                 assignedAgents.insert(agent);
00117                 }
00118         }
00119 }
00120 
00121 void CombatManager::draw()
00122 {
00123         Broodwar->drawTextScreen(2, 20, 
00124        "\x11 CM : (SCV=%d) (Marine=%d) (Firebat=%d) (Medic=%d)", 
00125         numAgents(UnitTypes::Terran_SCV), 
00126         numAgents(UnitTypes::Terran_Marine), 
00127     numAgents(UnitTypes::Terran_Firebat), 
00128     numAgents(UnitTypes::Terran_Medic));
00129 
00130         for (SquadVectorIter it = squads.begin(); it != squads.end(); it++)
00131         {
00132                 (*it)->draw();
00133         }
00134 
00135         Manager::draw();
00136 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines