00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <utility>
00028 #include <map>
00029 #include <vector>
00030 #include <list>
00031
00032 #include "../typen.h"
00033 #include "../terraintype.h"
00034 #include "../objecttype.h"
00035 #include "../spfst.h"
00036 #include "../unitctrl.h"
00037 #include "../buildingtype.h"
00038 #include "../astar2.h"
00039
00040
00041 class AI : public BaseAI {
00042 bool benchMark;
00043 bool strictChecks;
00044
00045 bool _isRunning;
00046 VisibilityStates _vision;
00047 int unitCounter;
00048 int player;
00049
00050 int maxTrooperMove;
00051 int maxTransportMove;
00052 int maxUnitMove;
00053 int maxWeapDist[8];
00054 int baseThreatsCalculated;
00055
00056 GameMap* activemap;
00057 MapDisplayInterface* mapDisplay;
00058 MapDisplayInterface* rmd;
00059
00060 class ServiceOrder {
00061 AI* ai;
00062 int targetUnitID;
00063 int serviceUnitID;
00064
00066 GameTime time;
00067 int failure;
00068 Building* nextServiceBuilding;
00069 int nextServiceBuildingDistance;
00070 bool active;
00071 public:
00072 VehicleService::Service requiredService;
00073 int position;
00074
00075 ServiceOrder ( ) : ai ( NULL ), targetUnitID ( 0 ), serviceUnitID ( 0 ), failure ( 0 ), nextServiceBuilding ( 0 ), active ( false ) {};
00076 ServiceOrder ( AI* _ai, VehicleService::Service _requiredService, int UnitID, int _pos = -1 );
00077 ServiceOrder ( AI* _ai, tnstream& stream );
00078 AStar3D::Path::iterator lastmatchServiceOrder ( AI* _ai, tnstream& stream );
00079 Vehicle* getTargetUnit ( ) const { return ai->getMap()->getUnit ( targetUnitID );};
00080 Vehicle* getServiceUnit ( ) const { return ai->getMap()->getUnit ( serviceUnitID );};
00081 void setServiceUnit ( Vehicle* veh );
00082 int possible ( Vehicle* supplier );
00083 bool execute1st ( Vehicle* supplier );
00084 bool timeOut ( );
00085 bool canWait ( );
00086
00087 void serviceFailed() { failure++; };
00088 bool completelyFailed();
00089
00090 bool serviceUnitExists();
00091
00092 static void releaseServiceUnit ( ServiceOrder& so );
00093
00094 void write ( tnstream& stream ) const;
00095 void read ( tnstream& read );
00096
00097 static bool targetDestroyed ( const ServiceOrder& so )
00098 {
00099 return !so.getTargetUnit();
00100 };
00101 static bool invalid ( const ServiceOrder& so );
00102 bool valid ( ) const;
00103 static void activate( ServiceOrder& so );
00104
00105 bool operator==( const ServiceOrder& so ) const;
00106 bool operator!=( const ServiceOrder& so ) const;
00107
00108
00109 ~ServiceOrder ();
00110 };
00111 friend class ServiceOrder;
00112
00113 void removeServiceOrdersForUnit ( const Vehicle* veh );
00114
00115 class ServiceTargetEquals : public unary_function<ServiceOrder&,bool> {
00116 const Vehicle* target;
00117 public:
00118 explicit ServiceTargetEquals ( const Vehicle* _target ) : target ( _target ) {};
00119 bool operator() (const ServiceOrder& so ) const;
00120 };
00121
00122
00123
00124 static bool vehicleValueComp ( const Vehicle* v1, const Vehicle* v2 );
00125 static bool buildingValueComp ( const Building* v1, const Building* v2 );
00126
00127 typedef list<ServiceOrder> ServiceOrderContainer;
00128 ServiceOrderContainer serviceOrders;
00130 void issueServices ( );
00131
00133 ServiceOrder& issueService ( VehicleService::Service requiredService, int UnitID, int pos = -1 );
00134
00135 ServiceOrder& issueRefuelOrder ( Vehicle* veh, bool returnImmediately );
00136 void runServiceUnit ( Vehicle* supplyUnit );
00137
00138 class RefuelConstraint {
00139 AI& ai;
00140 Vehicle* veh;
00141 AStar3D* ast;
00142 typedef map<int, Building*> ReachableBuildings;
00143 ReachableBuildings reachableBuildings;
00144
00145 typedef map<int, MapCoordinate3D> LandingPositions;
00146 LandingPositions landingPositions;
00147 bool positionsCalculated;
00148 int maxMove;
00149 public:
00150 RefuelConstraint ( AI& ai_, Vehicle* veh_, int maxMove_ = -1 ) : ai ( ai_ ), veh ( veh_ ), ast(NULL), positionsCalculated(false), maxMove ( maxMove_ ) {};
00151 MapCoordinate3D getNearestRefuellingPosition ( bool buildingRequired, bool refuel, bool repair );
00152 bool returnFromPositionPossible ( const MapCoordinate3D& pos, int theoreticalFuel = -1 );
00154 void findPath();
00155 static bool necessary (const Vehicle* veh, AI& ai );
00156 ~RefuelConstraint() { if (ast) delete ast; };
00157 };
00158 friend class RefuelConstraint;
00159
00160 bool runUnitTask ( Vehicle* veh );
00161
00162
00163 class FieldInformation {
00164 public:
00165 AiThreat threat;
00166 int control;
00167 int units[8];
00168 void reset ( );
00169 FieldInformation ( ) { reset(); };
00170 };
00171
00172 FieldInformation* fieldInformation;
00173 int fieldNum;
00174 AiThreat& getFieldThreat ( int x, int y );
00175 FieldInformation& getFieldInformation ( int x, int y );
00176
00177 class CheckFieldRecon : public SearchFields {
00178 protected:
00179 void testfield ( const MapCoordinate& mc ) ;
00180 int ownFields[3];
00181 int enemyFields[3];
00182 int player;
00183 AI* ai;
00184 public:
00185 CheckFieldRecon ( AI* _ai );
00186 int run ( int x, int y);
00187 };
00188 friend class CheckFieldRecon;
00189
00190
00191 MapCoordinate3D findServiceBuilding ( const ServiceOrder& so, int* distance = NULL );
00192
00193 void checkConquer( );
00194 void runReconUnits();
00195
00197 bool checkReConquer ( Building* bld, Vehicle* veh );
00198 float getCaptureValue ( const Building* bld, int travelTime );
00199 float getCaptureValue ( const Building* bld, Vehicle* veh );
00200
00201 class BuildingCapture {
00202 public:
00203 enum BuildingCaptureState { conq_noUnit,
00204 conq_unitNotConq,
00205 conq_conqUnit,
00206 conq_unreachable } state;
00207 int unit;
00208 vector<int> guards;
00209
00210 float captureValue;
00211 int nearestUnit;
00212
00213 void write ( tnstream& stream ) const;
00214 void read ( tnstream& stream );
00215
00216 BuildingCapture ( ) {
00217 state = conq_noUnit;
00218 unit = 0;
00219 nearestUnit = 0;
00220 captureValue = 0;
00221 };
00222 };
00223
00224 class BuildingValueComp : public binary_function<Building*,Building*,bool> {
00225 AI* ai;
00226 public:
00227 explicit BuildingValueComp ( AI* _ai ) : ai ( _ai ) {};
00228 bool operator() (const Building*& a, const Building*& b ) const {
00229 return ai->buildingCapture[ a->getEntry() ].captureValue > ai->buildingCapture[ b->getEntry() ].captureValue;
00230 };
00231 };
00232 friend class BuildingValueComp;
00233
00234 typedef map<MapCoordinate,BuildingCapture> BuildingCaptureContainer;
00235 BuildingCaptureContainer buildingCapture;
00236
00237
00238 void calculateFieldInformation ( void );
00239 void calculateFieldThreats_SinglePosition ( Vehicle* eht, int x, int y );
00240 class WeaponThreatRange : public SearchFields {
00241 Vehicle* veh;
00242 int weap, height;
00243 AiThreat* threat;
00244 AI* ai;
00245 void testfield ( const MapCoordinate& mc );
00246 public:
00247 void run ( Vehicle* _veh, int x, int y, AiThreat* _threat );
00248 WeaponThreatRange( AI* _ai ) : SearchFields ( _ai->getMap()), ai ( _ai ) {};
00249 };
00250
00251
00252 struct Config {
00253
00254 int lookIntoTransports;
00255 int lookIntoBuildings;
00256 int wholeMapVisible;
00257 float aggressiveness;
00258 int damageLimit;
00259 Resources resourceLimit;
00260 int ammoLimit;
00262 int maxCaptureTime;
00263
00265 int maxTactTime;
00266 int waitForResourcePlus;
00267 } config;
00268
00269 public:
00270 class MoveVariant {
00271 public:
00272 int orgDamage;
00273 int damageAfterMove;
00274 int damageAfterAttack;
00275 MapCoordinate3D movePos;
00276 int attackx, attacky;
00277 Vehicle* enemy;
00278 Vehicle* attacker;
00279 int enemyOrgDamage;
00280 int enemyDamage;
00281 int weapNum;
00282 float result;
00283 int moveDist;
00284 bool neighbouringFieldsReachable[ sidenum ];
00285 float positionThreat;
00286 };
00287 static bool moveVariantComp ( const AI::MoveVariant* mv1, const AI::MoveVariant* mv2 );
00288 private:
00289
00290 typedef vector<MoveVariant> MoveVariantContainer;
00291
00292 class AiResult {
00293 public:
00294 int unitsMoved;
00295 int unitsWaiting;
00296 int unitsDestroyed;
00297 AiResult ( ) : unitsMoved ( 0 ), unitsWaiting ( 0 ), unitsDestroyed( 0 ) {};
00298
00299 AiResult& operator+= ( const AiResult& a ) {
00300 unitsMoved += a.unitsMoved;
00301 unitsWaiting += a.unitsWaiting;
00302 unitsDestroyed += a.unitsDestroyed;
00303 return *this;
00304 };
00305 };
00306
00307
00308
00309 class TargetVector : public std::vector<MoveVariant*> {
00310 public:
00311 ~TargetVector() {
00312 for ( iterator it = begin(); it != end(); it++ )
00313 delete *it;
00314 };
00315 };
00316
00317 bool moveUnit ( Vehicle* veh, const MapCoordinate3D& destination, bool intoBuildings = true, bool intoTransports = true );
00318
00323 int moveUnit ( Vehicle* veh, const AStar3D::Path& path, bool intoBuildings = true, bool intoTransports = true );
00324
00325 void getAttacks ( AStar3D& vm, Vehicle* veh, TargetVector& tv, int hemmingBonus, bool justOne = false, bool executeService = true );
00326 void searchTargets ( Vehicle* veh, const MapCoordinate3D& pos, TargetVector& tl, int moveDist, AStar3D& vm, int hemmingBonus );
00327 bool targetsNear( Vehicle* veh );
00328
00329 AiResult executeMoveAttack ( Vehicle* veh, TargetVector& tv );
00330 int getDirForBestTacticsMove ( const Vehicle* veh, TargetVector& tv );
00331 MapCoordinate getDestination ( Vehicle* veh );
00332 AiResult moveToSavePlace ( Vehicle* veh, VehicleMovement& vm, int preferredHeight = -1 );
00333 int getBestHeight ( Vehicle* veh );
00334 float getAttackValue ( const tfight& battle, const Vehicle* attackingUnit, const Vehicle* attackedUnit, float factor = 1 );
00335
00342 int changeVehicleHeight ( Vehicle* veh, VehicleMovement* vm, int preferredDirection = -1 );
00343
00344 void calculateThreat ( const Vehicletype* vt);
00345 void calculateThreat ( Vehicle* eht );
00346 void calculateThreat ( Building* bld );
00347 void calculateThreat ( Building* bld, int player );
00348
00349 static AiParameter::JobList chooseJob ( const Vehicletype* typ );
00350 friend class CalculateThreat_Vehicle;
00351
00357 void calculateAllThreats( void );
00358 AiResult tactics( void );
00359 void tactics_findBestAttackOrder ( Vehicle** units, int* attackOrder, Vehicle* enemy, int depth, int damage, int& finalDamage, int* finalOrder, int& finalAttackNum );
00360 void tactics_findBestAttackUnits ( const MoveVariantContainer& mvc, MoveVariantContainer::iterator& m, Vehicle** positions, float value, Vehicle** finalposition, float& finalvalue, int unitsPositioned, int recursionDepth, int startTime );
00361
00365 void findStratPath ( vector<MapCoordinate>& path, Vehicle* veh, int x2, int y2 );
00366
00367 class UnitDistribution {
00368 public:
00369 static const int groupCount = 6;
00370 enum Group { attack, rangeattack, conquer, other, recon, service };
00371 bool calculated;
00372 float group[groupCount];
00373 UnitDistribution( ) : calculated ( false ) { for ( int i = 0; i < groupCount; i++ ) group[i] = 0; };
00374 void read( tnstream& stream );
00375 void write ( tnstream& stream ) const;
00376 };
00377 UnitDistribution originalUnitDistribution;
00378 UnitDistribution::Group getUnitDistributionGroup ( Vehicle* veh );
00379 UnitDistribution::Group getUnitDistributionGroup ( Vehicletype* veh );
00380
00381 UnitDistribution calcUnitDistribution();
00382 struct ProductionRating {
00383 const Vehicletype* vt;
00384 Building* bld;
00385 float rating;
00386 bool operator< ( const ProductionRating& pr ) { return rating < pr.rating; };
00387 };
00388
00389 typedef map<int,pair<float,float> > UnitTypeSuccess;
00390 UnitTypeSuccess unitTypeSuccess;
00391
00392 class VehicleTypeEfficiencyCalculator {
00393 AI& ai;
00394 float ownValue;
00395 int ownTypeID;
00396 float enemyValue;
00397 int orgOwnDamage;
00398 int orgEnemyDamage;
00399 int enemyID;
00400 int ownID;
00401 Vehicle* attacker;
00402 Vehicle* target;
00403 public:
00404 VehicleTypeEfficiencyCalculator ( AI& _ai, Vehicle* _attacker, Vehicle* _target );
00405 void calc();
00406 };
00407 friend class VehicleTypeEfficiencyCalculator;
00408
00409 void production();
00410
00411 AiResult strategy();
00412 AiResult buildings ( int process );
00413 AiResult transports ( int process );
00414 AiResult container ( ContainerBase* cb );
00415 AiResult executeServices ();
00416 void setup();
00417
00418 void reset();
00419
00420 typedef map<MapCoordinate,int> ReconPositions;
00421 ReconPositions reconPositions;
00422 void calcReconPositions();
00423
00424 class Section {
00425 AI* ai;
00426 public:
00427 int x1,y1,x2,y2;
00428 int xp, yp;
00429 int centerx, centery;
00430 int units_heading_here;
00431
00432 int numberOfFields;
00433 AiThreat absUnitThreat;
00434 AiThreat avgUnitThreat;
00435 AiThreat absFieldThreat;
00436 AiThreat avgFieldThreat;
00437 float value[ aiValueTypeNum ];
00438
00439 int numberOfAccessibleFields ( const Vehicle* veh );
00440 void init ( int _x, int _y, int xsize, int ysize, int _xp, int _yp );
00441 void init ( AI* _ai, int _x, int _y, int xsize, int ysize, int _xp, int _yp );
00442 Section ( AI* _ai ) : ai ( _ai ) {};
00443 Section ( ) { ai = NULL; };
00444 };
00445 friend class Section;
00446
00447 class Sections {
00448 AI* ai;
00449 Section* section;
00450 public:
00451 int sizeX ;
00452 int sizeY ;
00453 int numX ;
00454 int numY ;
00455 void calculate ( void );
00456 Section& getForCoordinate ( int xc, int yc );
00457 Section& getForPos ( int xn, int yn );
00458
00459
00460 Section* getBest ( int pass, Vehicle* veh, MapCoordinate3D* dest = NULL, bool allowRefuellOrder = false, bool secondRun = false );
00461 Sections ( AI* _ai );
00462 void reset( void );
00463 } sections;
00464 friend class Sections;
00465
00466 void checkKeys ( void );
00467 void removeDisplay();
00468
00469 void diplomacy ();
00470
00471 void checkGameEvents();
00472
00473 public:
00474 AI ( GameMap* _map, int _player ) ;
00475
00476 void run ( ) { run ( false );};
00478 void run ( bool benchmark );
00479
00481 GameMap* getMap ( void ) { return activemap; };
00482
00484 int getPlayerNum ( void ) { return player; };
00485
00486 Player& getPlayer ( void ) { return getMap()->player[player]; };
00487 Player& getPlayer ( int player ) { return getMap()->player[player]; };
00488 Player& getPlayer ( PlayerID id ) { return getMap()->player[id.getID()]; };
00489 void showFieldInformation ( int x, int y );
00490 bool isRunning ( void );
00491
00497 VisibilityStates getVision ( void );
00498
00499 void read ( tnstream& stream );
00500 void write ( tnstream& stream ) const ;
00501 ~AI ( );
00502 };