-
Notifications
You must be signed in to change notification settings - Fork 1
/
AAISector.h
332 lines (230 loc) · 13.8 KB
/
AAISector.h
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// -------------------------------------------------------------------------
// AAI
//
// A skirmish AI for the Spring engine.
// Copyright Alexander Seizinger
//
// Released under GPL license: see LICENSE.html for more information.
// -------------------------------------------------------------------------
#ifndef AAI_SECTOR_H
#define AAI_SECTOR_H
#include "System/float3.h"
#include "aidef.h"
#include "AAITypes.h"
#include "AAIUnitTypes.h"
#include "AAIBuildTree.h"
#include <list>
#include <vector>
class AAI;
class AAIUnitTable;
class AAIMap;
class AAIThreatMap;
class BuildMapTileType;
class AAIMetalSpot;
namespace springLegacyAI {
struct UnitDef;
}
using namespace springLegacyAI;
enum Direction {WEST, EAST, SOUTH, NORTH, CENTER, NO_DIRECTION};
struct DefenceCoverage
{
Direction direction;
float defence;
};
struct SectorIndex
{
SectorIndex(int x, int y) : x(x), y(y) {};
bool operator==(const SectorIndex& rhs) const { return (x == rhs.x) && (y == rhs.y); }
int x = 0;
int y = 0;
};
class AAISector
{
public:
friend AAIMap;
AAISector();
~AAISector(void);
//! @brief Adds a metal spot to the list of metal spots in the sector
void AddMetalSpot(AAIMetalSpot *spot);
//! @brief Associates an extractor with a metal spot in that sector
void AddExtractor(UnitId unitId, UnitDefId unitDefId, float3 position);
//! @brief Looks for metal spot that corresponds to given position and marks it as free
void FreeMetalSpot(float3 position, UnitDefId extractorDefId);
void Init(AAI *ai, int x, int y);
//! @brief Loads sector data from given file
void LoadDataFromFile(FILE* file);
//! @brief Saves sector data to given file
void SaveDataToFile(FILE* file);
//! @brief Updates learning data for sector
void UpdateLearnedData();
//! @brief Adds/removes the sector from base sectors; returns true if succesful
bool AddToBase(bool addToBase);
//! @brief Returns the corresponding index of the sector
const SectorIndex GetSectorIndex() const { return m_sectorIndex; }
//! @brief Returns the distance (in sectors) to the base
int GetDistanceToBase() const { return m_distanceToBase; }
//! @brief Returns the number of metal spots in this sector
int GetNumberOfMetalSpots() const { return metalSpots.size(); }
//! @brief Returns the number of buildings of the given category in this sector
int GetNumberOfBuildings(const AAIUnitCategory& category) const { return m_ownBuildingsOfCategory[category.GetArrayIndex()]; }
//! @brief Returns the number of buildings belonging to allied players
int GetNumberOfAlliedBuildings() const { return m_alliedBuildings; }
//! @brief Returns the number of buildings belonging to hostile players
int GetNumberOfEnemyBuildings() const { return m_enemyBuildings; }
//! @brief Resets the own combat power / number of allied buildings
void ResetLocalCombatPower();
//! @brief Resets the number / combat power of spotted enemy units
void ResetScoutedEnemiesData();
//! @brief Updates enemy combat power and counters
void AddScoutedEnemyUnit(UnitDefId enemyDefId, int framesSinceLastUpdate);
//! @brief Return the total number of enemy combat units
float GetTotalEnemyCombatUnits() const { return m_enemyCombatUnits.CalcuateSum(); };
//! @brief Returns whether sector is supsected to be occupied by enemy units (according to scouting or sensor)
bool IsOccupiedByEnemies() const{ return (GetTotalEnemyCombatUnits() > 0.1f) || (m_enemyBuildings > 0) || (m_enemyUnitsDetectedBySensor > 0); }
//! @brief Returns number of enemy units of given target type spotted in this sector (float as number decreases over time if sector is not scouted)
float GetNumberOfEnemyCombatUnits(const AAITargetType& targetType) const { return m_enemyCombatUnits.GetValue(targetType); };
const TargetTypeValues& GetNumberOfEnemyCombatUnits() const { return m_enemyCombatUnits; };
//! @brief Decreases number of lost units by a factor < 1 such that AAI "forgets" about lost unit over time
void DecreaseLostUnits();
//! @brief Returns whether sector can be considered for expansion of base
bool IsSectorSuitableForBaseExpansion() const;
//! @brief Returns true if sector shall be considered for selection of construction of further metal extractor
bool ShallBeConsideredForExtractorConstruction() const;
//! @brief Returns true if free metal spot available in sector
bool AreFreeMetalSpotsAvailable() const;
//! @brief Returns a buildsite that has been chosen randomly (the given number of trials) - ZeroVector if none found
BuildSite DetermineRandomBuildsite(UnitDefId buildingDefId, int trials) const;
//! @brief Searches for a buildsite that is preferably elevated with respect to its surroundings and not close to the map edges
BuildSite DetermineElevatedBuildsite(UnitDefId buildingDefId, float range) const;
//! @brief Returns position of known enemy buildings (or center if no buidlings in sector)
float3 DetermineAttackPosition() const;
//! @brief Adds building of category to sector
void AddBuilding(const AAIUnitCategory& category) { m_ownBuildingsOfCategory[category.GetArrayIndex()] += 1; };
//! @brief Removes building from sector
void RemoveBuilding(const AAIUnitCategory& category) { m_ownBuildingsOfCategory[category.GetArrayIndex()] -= 1; };
//! @brief Returns true if local combat power does not suffice to defend vs attack by given target type
bool IsSupportNeededToDefenceVs(const AAITargetType& targetType) const;
//! @brief Returns how often units in sector have been attacked by given mobile target type
float GetLocalAttacksBy(const AAITargetType& targetType, float previousGames, float currentGame) const;
//! @brief Get total (mobile + static) defence power of enemy vs given target type (according to spotted units)
float GetEnemyCombatPowerVsUnits(const MobileTargetTypeValues& unitsOfTargetType) const;
//! @brief Get total (mobile + static) defence power vs given target type
float GetEnemyCombatPower(const AAITargetType& targetType) const { return m_enemyStaticCombatPower.GetValueOfTargetType(targetType) + m_enemyMobileCombatPower.GetValueOfTargetType(targetType); }
//! @brief Returns combat power of own/allied static defences against given target type
float GetFriendlyStaticDefencePower(const AAITargetType& targetType) const { return m_friendlyStaticCombatPower.GetValueOfTargetType(targetType); }
//! @brief Returns cmbat power of own/allied static defences against given target type
float GetFriendlyCombatPower(const AAITargetType& targetType) const { return m_friendlyStaticCombatPower.GetValueOfTargetType(targetType) + m_friendlyMobileCombatPower.GetValueOfTargetType(targetType); }
//! @brief Adds given values to friendly combat power in this sector
void AddFriendlyCombatPower(const TargetTypeValues& combatPower) { m_friendlyMobileCombatPower.AddCombatPower(combatPower); }
//! @brief Updates threat map storing where own buildings/units got killed
void UpdateThreatValues(UnitDefId destroyedDefId, UnitDefId attackerDefId);
//! @brief Returns lost units in that sector
float GetLostUnits(const AAITargetType& targetType) const { return m_lostUnits.GetValueOfTargetType(targetType); }
//! @brief Returns the total number (i.e. of all target types) of lost units in this sector
float GetTotalLostUnits() const { return m_lostUnits.CalculateSum(); }
//! @brief Returns number of attacks by the main combat categories (ground, hover, air)
float GetTotalAttacksInThisGame() const
{
return m_attacksByTargetTypeInCurrentGame.CalculateSum();
}
//! @brief Returns number of attacks by the main combat categories (ground, hover, air)
float GetTotalAttacksInPreviousGames() const
{
return m_attacksByTargetTypeInPreviousGames.CalculateSum();
}
//! @brief Returns center position of the sector
float3 GetCenter() const;
//! @brief Returns the continent ID of the center of the sector
int GetContinentID() const { return m_continentId; }
//! @brief Returns the ratio of flat terrain tiles in this sector
float GetFlatTilesRatio() const { return m_flatTilesRatio; }
//! @brief Returns the ratio of water tiles in this sector
float GetWaterTilesRatio() const { return m_waterTilesRatio; }
//! @brief Increments corresponding counter (used to avoid trying to build static defences in a sector with no suitable buildsites)
void FailedToConstructStaticDefence() { ++m_failedAttemptsToConstructStaticDefence; }
//! @brief Returns the importance of a static defence against the target type with highest priority
float GetImportanceForStaticDefenceVs(AAITargetType& targetType, const GamePhase& gamePhase, float previousGames, float currentGame);
//! @brief Returns the rating of this sector as destination to attack (0.0f if no suitable target)
float GetAttackRating(const AAISector* currentSector, bool landSectorSelectable, bool waterSectorSelectable, const MobileTargetTypeValues& targetTypeOfUnits) const;
//! @brief Returns the rating of this sector as destination to attack (0.0f if no suitable target)
float GetAttackRating(const std::vector<float>& globalCombatPower, const std::vector< std::vector<float> >& continentCombatPower, const MobileTargetTypeValues& assaultGroupsOfType, float maxLostUnits) const;
//! @brief Returns rating as next destination for scout of given movement type
float GetRatingAsNextScoutDestination(const AAIMovementType& scoutMoveType, const AAITargetType& scoutTargetType, const float3& currentPositionOfScout);
//! @brief Returns the rating to be selected for a rally point for units of given movement type
float GetRatingForRallyPoint(const AAIMovementType& moveType, int continentId) const;
//! @brief Returns the rating as starting sector (if a new one has to be selected as the current is already occupied by other AAI player)
float GetRatingAsStartSector() const;
//! @brief Returns rating as sector to build a power plant
float GetRatingForPowerPlant(float weightPreviousGames, float weightCurrentGame) const;
//! @brief Shall be called when scout is sent to this sector (resets counter how often this sector has been skipped)
void SelectedAsScoutDestination() { m_skippedAsScoutDestination = 0; }
//! @brief Searches for a free position in sector on specified continent (use -1 if continent does not matter).
//! Returns position or ZeroVector if none found.
float3 DetermineUnitMovePos(AAIMovementType moveType, int continentId) const;
//! @brief Returns true if pos lies within this sector
bool PosInSector(const float3& pos) const;
//! @brief Determines ratio of water cells of this sector
float DetermineWaterRatio() const;
//! @brief Determines ratio of flat cells of this sector
float DetermineFlatRatio() const;
//! @brief Returns true if sector is connected with a big ocean (and not only a small pond)
bool ConnectedToOcean() const;
//! @brief Returns minimum distance to one of the map edges (in sector sizes)
int GetEdgeDistance() const { return m_minSectorDistanceToMapEdge; }
//! @brief Determines rectangle for possible buildsite
void DetermineBuildsiteRectangle(int *xStart, int *xEnd, int *yStart, int *yEnd) const;
// list of all metal spots in the sector
std::list<AAIMetalSpot*> metalSpots;
// importance of the sector
float importance_this_game;
float importance_learned;
private:
//! @brief Helper function to determine position to move units to
bool IsValidMovePos(const float3& pos, BuildMapTileType forbiddenMapTileTypes, int continentId) const;
//! @brief Returns true if further static defences may be built in this sector
bool AreFurtherStaticDefencesAllowed() const;
AAI *ai;
//! The corresponding index of the sector
SectorIndex m_sectorIndex;
//! Id of the continent of the center of the sector
int m_continentId;
//! Ratio of flat terrain tiles
float m_flatTilesRatio;
//! Ratio of water tiles
float m_waterTilesRatio;
//! Distance (in sectors) to own base, i.e 0 = belongs to base, 1 = neighbour to base, ...
int m_distanceToBase;
//! Bitmask storing movement types that may maneuver in this sector
uint32_t m_suitableMovementTypes;
//! Minimum distance to one of the map edges (in sector sizes)
int m_minSectorDistanceToMapEdge;
//! How many units have recently been lost in that sector (float as the number decays over time)
MobileTargetTypeValues m_lostUnits;
//! Number of own buildings of each category in the sector
std::vector<int> m_ownBuildingsOfCategory;
//! Number of spotted enemy combat units (float values as number decays over time)
TargetTypeValues m_enemyCombatUnits; // 0 surface, 1 air, 3 ship, 4 submarine, 5 static defences
//! Number of buildings enemy players have constructed in this sector
int m_enemyBuildings;
//! Number of buildings allied players have constructed in this sector
int m_alliedBuildings;
//! Number of enemy units detected by sensor (radar/sonar)
int m_enemyUnitsDetectedBySensor;
//! The combat power against mobile targets of all hostile static defences in this sector
MobileTargetTypeValues m_enemyStaticCombatPower;
//! The combat power against mobile targets of all hostile combat units in this sector
MobileTargetTypeValues m_enemyMobileCombatPower;
//! The combat power against mobile targets of all friendly static defences in this sector
MobileTargetTypeValues m_friendlyStaticCombatPower;
//! The combat power against mobile targets of all friendly combat units in this sector
MobileTargetTypeValues m_friendlyMobileCombatPower;
//! Stores how often buildings in this sector have been attacked(=destroyed) by a certain target type in previous games
MobileTargetTypeValues m_attacksByTargetTypeInPreviousGames;
//! Stores how often buildings in this sector have been attacked(=destroyed) by a certain target type in the current game
MobileTargetTypeValues m_attacksByTargetTypeInCurrentGame;
//! indicates how many times scouts have been sent to another sector
int m_skippedAsScoutDestination;
//! How many times AAI tried to build defences in this sector but failed (because of unavailable buildsite)
int m_failedAttemptsToConstructStaticDefence;
};
#endif