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