1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
|
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------
#ifndef AAI_DEF_H
#define AAI_DEF_H
#include "System/float3.h"
#include "Sim/Misc/GlobalConstants.h"
#include <vector>
#include <string>
#define AAI_VERSION aiexport_getVersion()
#define MAP_CACHE_VERSION "MAP_DATA_0_92b"
#define MAP_LEARN_VERSION "MAP_LEARN_0_91"
#define MOD_LEARN_VERSION "MOD_LEARN_0_92"
#define CONTINENT_DATA_VERSION "MOVEMENT_MAPS_0_87"
#define AILOG_PATH "log/"
#define MAP_LEARN_PATH "learn/mod/"
#define MOD_LEARN_PATH "learn/mod/"
//! Constants used within AAI
class AAIConstants
{
public:
// The length/width of sectors (in map tiles)
static constexpr float sectorSize = 80.0f;
//! @todo Make this changeable via optinal mod config file
static constexpr float energyToMetalConversionFactor = 60.0f;
//! Minimum combat power value
static constexpr float minCombatPower = 0.01f;
//! Maximum combat power value
static constexpr float maxCombatPower = 20.0f;
//! Minimum initial combat power (if unit is allowed to target units of target category)
static constexpr float minInitialCombatPower = 1.0f;
//! Initial combat power if unit is not allowed to target units of target category
static constexpr float noValidTargetInitialCombarPower = 0.1f;
//! The maximum change from a single combat (attacker killes certain unit) - prevent odd statistical values from "lucky kills" (e.g. weak units gets last shot on stong one)
static constexpr float maxCombatPowerChangeAfterSingleCombat = 0.15f;
//! The factor applied to determine change of combat power for killer/destroyed unit type
static constexpr float combatPowerLearningFactor = 0.02f;
//! Minimum combat power for a unit to be considered effective against a certain target type
static constexpr float minAntiTargetTypeCombatPower = 0.15f;
//! Minimum combat power vs specific target type such that a group of only one unit may participate in attacks
static constexpr float minCombatPowerForSoloAttack = 2.5f;
//! Minimum weapons range difference to shorter ranged attacked before combat units try to keep their distance
static constexpr float minWeaponRangeDiffToKeepDistance = 50.0f;
//! Minimum averaged metal surplus before constrcution of non-resource generating units shall be assisted
static constexpr float minMetalSurplusForConstructionAssist = 0.5f;
//! Minimum averaged energy surplus before constrcution of non-resource generating units shall be assisted
static constexpr float minEnergySurplusForConstructionAssist = 40.0f;
//! Maximum power surplus until construction of further power plants shall be considered
static constexpr float powerSurplusToStopPowerPlantConstructionThreshold = 2000.0f;
//! Maximum distance to rally points for units to be considered to have reached it
static constexpr float maxSquaredDistToRallyPoint = static_cast<float>( (16*SQUARE_SIZE)*(16*SQUARE_SIZE) );
//! The factor applied to the combat power of the own units (when deciding whether to attack)
static constexpr float attackCombatPowerFactor = 2.0f;
//! If the local defence power against the target type of the attacker is below this threshold combat units shall be orderd to support.
static constexpr float localDefencePowerToRequestSupportThreshold = 2.0f;
//! The minimum number of frames between two updates of the units in current LOS (to avoid too heavy CPU load)
static constexpr int minFramesBetweenLOSUpdates = 10;
};
enum UnitTask {UNIT_IDLE, UNIT_ATTACKING, DEFENDING, GUARDING, MOVING, BUILDING, SCOUTING, ASSISTING, RECLAIMING, HEADING_TO_RALLYPOINT, UNIT_KILLED, ENEMY_UNIT, BOMB_TARGET};
//! @brief An id identifying a specific unit - used to prevent mixing ids referring to units and unit definitions
struct UnitId
{
public:
UnitId(int unitId) : id(unitId) { };
UnitId() : id(-1) { };
bool operator==(const UnitId& rhs) const { return (id == rhs.id); }
bool operator<(const UnitId& rhs) const { return (id < rhs.id); }
bool IsValid() const { return (id >= 0) ? true : false; };
void Invalidate() { id = -1; };
int id;
};
//! @brief An id identifying a unit type - used to prevent mixing ids referring to units and unit definitions
class UnitDefId
{
public:
UnitDefId(int unitDefId) : id(unitDefId) {}
UnitDefId() : UnitDefId(0) {}
bool operator==(const UnitDefId& rhs) const { return (id == rhs.id); }
bool IsValid() const { return (id > 0) ? true : false; }
void Invalidate() { id = 0; }
int id;
};
//! @brief An id identifying the corresponding buildqueues etc. for factories
class FactoryId
{
public:
FactoryId(int factoryId) : id(factoryId) {}
FactoryId() : FactoryId(-1) { }
bool IsValid() const { return (id >= 0) ? true : false; }
void Set(int factoryId) { id = factoryId; }
int id;
};
//! This class stores the information required for placing/upgrading metal extractors
class AAIMetalSpot
{
public:
AAIMetalSpot(const float3& _pos, float _amount):
pos(_pos),
occupied(false),
amount(_amount)
{}
AAIMetalSpot():
pos(ZeroVector),
occupied(false),
amount(0.0f)
{}
void SetUnoccupied()
{
occupied = false;
extractorUnitId.Invalidate();
extractorDefId.Invalidate();
}
//! @brief Returns whether spot belong to given map position
bool DoesSpotBelongToPosition(const float3& position) const
{
return (std::fabs(pos.x - position.x) < 16.0f) && (std::fabs(pos.z - position.z) < 16.0f);
}
//! The position of the metal spot in the map
float3 pos;
//! Flag whether the spot is currently occupied by any AAI player
bool occupied;
//! UnitId of the extractor occupying the spot
UnitId extractorUnitId;
//! UnitDefId of the extractor occupying the spot
UnitDefId extractorDefId;
//! The ammount of metal that can be extracted from the spot
float amount;
};
//! @brief This class encapsulates the determination of the current game phase (ranging from start to late game)
//! used to differentiate when making decisions/record learning data
class GamePhase
{
public:
GamePhase(int frame)
{
for(int i = 1; i < numberOfGamePhases; ++i) // starting with i=1 on purpose
{
if(frame < m_startFrameOfGamePhase[i])
{
m_gamePhase = i-1;
return;
}
}
m_gamePhase = 3;
}
bool operator>(const GamePhase& rhs) const { return (m_gamePhase > rhs.m_gamePhase); }
bool operator<(const GamePhase& rhs) const { return (m_gamePhase < rhs.m_gamePhase); }
bool operator<=(const GamePhase& rhs) const { return (m_gamePhase <= rhs.m_gamePhase); }
int GetArrayIndex() const { return m_gamePhase; };
const std::string& GetName() const { return m_gamePhaseNames[m_gamePhase]; }
bool IsStartingPhase() const {return (m_gamePhase == 0); }
bool IsEarlyPhase() const {return (m_gamePhase == 1); }
bool IsIntermediatePhase() const {return (m_gamePhase == 2); }
bool IsLatePhase() const {return (m_gamePhase == 3); }
void Next() { ++m_gamePhase; }
bool End() const { return (m_gamePhase >= numberOfGamePhases); }
static const int numberOfGamePhases = 4;
private:
int m_gamePhase;
//! Frame at which respective game phase starts: 0 -> 0 min, 1 -> 6min, 2 -> 15 min, 3 -> 40 min
const static std::vector<int> m_startFrameOfGamePhase;
const static std::vector<std::string> m_gamePhaseNames;
//const static inline std::vector<int> m_startFrameOfGamePhase = {0, 10800, 27000, 72000}; use when switching to Cpp17
//const static inline std::vector<int> m_gamePhaseNames = {"starting phase", "early phase", "mid phase", "late game"}; use when switching to Cpp17
};
class SmoothedData
{
public:
SmoothedData(int smoothingLength) : m_averageValue(0.0f), m_nextIndex(0) { m_values.resize(smoothingLength, 0.0f); }
float GetAverageValue() const { return m_averageValue; }
void AddValue(float value)
{
m_averageValue += (value - m_values[m_nextIndex]) / static_cast<float>(m_values.size());
m_values[m_nextIndex] = value;
++m_nextIndex;
if(m_nextIndex >= m_values.size())
m_nextIndex = 0;
}
private:
//! The values to be averaged
std::vector<float> m_values;
//! The current average value
float m_averageValue;
//! Index where next value will be added
int m_nextIndex;
};
class AAIGroup;
class AAIConstructor;
struct AAIUnit
{
int unit_id;
int def_id;
AAIGroup *group;
AAIConstructor *cons;
UnitTask status;
int last_order;
};
#endif
|