Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

AI.cpp

Go to the documentation of this file.
00001 /*
00002 CS Senior Project 2003
00003 Team : Leftfield
00004 Project : ModernWarfare
00005 Members :
00006 - Russ Christensen              <rchriste@cs.utah.edu>
00007 - Todd Smith                    <tcsmith@cs.utah.edu>
00008 - Usit Duongsaa                 <duongsaa@cs.utah.edu>
00009 Copyright 2003 Russ Christensen, Usit Duongsaa, and Todd Smith. All rights reserved.
00010 
00011 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00012 
00013 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
00014 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
00015 THIS SOFTWARE IS PROVIDED BY RUSS CHRISTENSEN, USIT DUONGSAA, AND TODD SMITH ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RUSS, USIT, TODD OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00016 */
00017 
00022 #include "AI.h"
00023 #include "globals.h"
00024 #include <utility>
00025 
00026 namespace AI
00027 {
00028   typedef vector<City*>::iterator CityIter;
00029   typedef vector<MilitaryUnit*>::iterator UnitIter;
00030 
00031   //-- PUBLIC 
00032 
00033   
00034   Player::Player(const Vec3D teamColor,
00035                  vector<MilitaryUnit*>  &units, 
00036                  vector<City*> &cities,
00037                  Map::WorldMap wm)      :        m_teamColor(teamColor),        
00038                                        m_units(units),
00039                                        m_cities(cities),
00040                                        m_threatMap(wm.gridWidth, vector<FLOAT>(wm.gridHeight)),
00041                                        m_worldMap(wm) 
00042   {
00043     //clearThreatMap();
00044   }
00045   
00046 
00047   
00048   void Player::update() 
00049   {
00050     buildThreatMap();
00051 
00052     // build list of units i own
00054     //                     access to each list of units.
00055     vector<MilitaryUnit*> myUnits;
00056     UnitIter unitIter;
00057     for(unitIter = m_units.begin(); unitIter != m_units.end(); ++unitIter)
00058     {
00059       if( (*unitIter)->color() == m_teamColor ) myUnits.push_back((*unitIter));
00060     }
00061 
00062     // find least threatened neutral city
00063     vector<City*> neutralCities;
00064     vector<City*> enemyCities;
00065     CityIter cityIter;
00066     for(cityIter = m_cities.begin(); cityIter != m_cities.end(); ++cityIter)
00067     {
00068       if( (*cityIter)->color() == Globals::NO_OWNER ) 
00069         neutralCities.push_back(*cityIter);
00070       else if( (*cityIter)->color() != m_teamColor )
00071         enemyCities.push_back(*cityIter);
00072     }
00073 
00074     if( !neutralCities.empty() )
00075     {
00076       // sort cities by their threatened valued. less threatened cities first
00077       sort(neutralCities.begin(), neutralCities.end(), CityLessThreatened(m_threatMap, m_worldMap) );
00078       // send units to the cities
00079       size_t numCities = neutralCities.size();
00080       size_t city;
00081       for(unitIter = myUnits.begin(), city=0; (unitIter != myUnits.end()) && city < numCities; ++unitIter, ++city)
00082       {
00083             if(!(*unitIter)->isIdle()) (*unitIter)->goal( neutralCities[city]->position() );
00084       }
00085 
00086     }
00087     // send the units to the enemy cites
00088     else
00089     {
00090       // sort cities by their threatened valued. less threatened cities first
00091       sort(enemyCities.begin(), enemyCities.end(), CityLessThreatened(m_threatMap, m_worldMap) );
00092       // send the two closest units to each of the cities
00093       //size_t numCities = enemyCities.size();
00094       //size_t city;
00095       //for(unitIter = myUnits.begin(), city=0; (unitIter != myUnits.end()) && city < numCities; ++unitIter, ++city)
00096       //{
00097       //  if( (*unitIter)->currState != MilitaryUnit::BUSY )
00098       //    (*unitIter)->goal( enemyCities[city]->position() );
00099       //}
00100       for(cityIter = enemyCities.begin(); cityIter != enemyCities.end(); ++cityIter)
00101       {
00102         sendUnitsToCity(myUnits, *cityIter);
00103       }
00104     }
00105 
00106   }
00107   
00108 
00109   
00110   Vec3D Player::color() const   {       return m_teamColor;     }
00111   
00112   const ThreatMap &Player::threatMap() { return m_threatMap; }
00113   
00114 
00115 
00116   //-- PRIVATE
00117 
00118   Player::CityLessThreatened::CityLessThreatened(ThreatMap &tm, Map::WorldMap &wm):
00119     m_threatMap(tm), m_worldMap(wm) { }
00120 
00121   // compare the grid cells of each city and see if c1 is in less threatened cell than c2
00122   BOOL Player::CityLessThreatened::operator ()(City *c1, City *c2) const
00123   {
00124     Int2Tuple c1Coords = m_worldMap.worldToGridCoord(c1->position());
00125     Int2Tuple c2Coords = m_worldMap.worldToGridCoord(c2->position());
00126     return m_threatMap[c1Coords.a][c1Coords.b] < m_threatMap[c2Coords.a][c2Coords.b];
00127   }
00128 
00129   
00130   void Player::clearThreatMap()
00131   {
00132     for(int     i=0; i < m_worldMap.gridHeight; ++i)
00133       for(int   j=0; j < m_worldMap.gridWidth;  ++j)
00134                           m_threatMap[i][j] = 0.0f;
00135   }
00136   
00137   
00138   
00139   // for now just find out which tile an enemy unit is in and increment the corresponding
00140   // cell in the threat map.
00141   void Player::buildThreatMap()
00142   {
00143     clearThreatMap();   
00144     for(UnitIter iter=m_units.begin(); iter != m_units.end(); ++iter)
00145     {
00146       
00147       // dont calculate my units
00148       if( (*iter)->color() != m_teamColor )
00149       {
00150         // a unit should have a great affect on the grid cell its in and 
00151         // a lesser affect to each neighbor cell. so increment the containing cell twice.
00152         Int2Tuple gridCoord = m_worldMap.worldToGridCoord((*iter)->position());
00153         m_threatMap[gridCoord.a][gridCoord.b] += AI::unitThreatIncr;
00154         // calculate value for surrounding cells
00155         int endRow = gridCoord.a+1 <= m_worldMap.gridHeight-1 ? gridCoord.a+1 : m_worldMap.gridHeight-1;
00156         int endCol = gridCoord.b+1 <= m_worldMap.gridWidth-1 ? gridCoord.b+1 : m_worldMap.gridWidth-1;
00157         for(int row=(gridCoord.a-1 >= 0 ? gridCoord.a-1 : 0); row <= endRow; ++row)
00158         {
00159           for(int col=(gridCoord.b-1 >= 0 ? gridCoord.b-1 : 0); col <= endCol; ++col)
00160             m_threatMap[row][col] += AI::unitThreatIncr;
00161         }
00162      
00163       }
00164     }
00165  
00166   }
00167   
00168 
00169   typedef pair<MilitaryUnit*, FLOAT> UnitDist;
00170 
00171   class SmallerDistToCity
00172   {
00173   public:
00174     BOOL operator()(UnitDist &ud1, UnitDist ud2) { return ud1.second < ud2.second; }
00175   };
00176 
00180   void Player::sendUnitsToCity(vector<MilitaryUnit*> &units, const City *city)
00181   {
00182     // list of units and and there distance to the target city
00183     vector<UnitDist> unitDists;
00184     for(UnitIter iter=units.begin(); iter != units.end(); ++iter)
00185     {
00186       unitDists.push_back(UnitDist((*iter), Helper::distXY((*iter)->position(), city->position())));
00187     }
00188 
00189     // sort the units by the distance to the target city
00190     sort(unitDists.begin(), unitDists.end(), SmallerDistToCity());
00191 
00192     if(unitDists.size() > 0 && (!unitDists[0].first->isIdle())) unitDists[0].first->goal(city->position());
00193     if(unitDists.size() >= 2 && !unitDists[1].first->isIdle()) 
00194     {
00195       unitDists[1].first->goal(city->position());
00196     }
00197       
00198   }
00199 
00200 
00201 } // end namespace AI

Generated on Wed Apr 23 05:50:13 2003 for Modern Warfare by doxygen1.3-rc2