Skip to content

Commit

Permalink
more heavy ai work
Browse files Browse the repository at this point in the history
  • Loading branch information
Robosturm committed Oct 14, 2023
1 parent 05d77ba commit 03ff67e
Show file tree
Hide file tree
Showing 16 changed files with 475 additions and 265 deletions.
14 changes: 12 additions & 2 deletions ai/heavyai/heavyAiSharedData.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
#include <QtTypes>

class Unit;
class UnitTargetedPathFindingSystem;
using spUnitTargetedPathFindingSystem = std::shared_ptr<UnitTargetedPathFindingSystem>;

namespace HeavyAiSharedData
{

static constexpr qint32 UNIT_COUNT = 40;
static constexpr qint32 SEARCH_RANGE = 30;

enum SituationFeatures
{
HP,
Expand All @@ -19,6 +24,7 @@ enum SituationFeatures
RepairsOnPosition,
CapturePoints,
BuildingImportance,
Stealthed,
MaxFeatures,
};

Expand All @@ -27,16 +33,20 @@ enum AiCache
UnitMovementPoints,
MinFirerange,
MaxFirerange,
TerrainDefense,
CanMoveAndFire,
MaxAiCache,
};


struct UnitInfo
{
Unit* pUnit{nullptr};
qint32 multiplier{0};
bool reachable{false};
std::array<bool, UNIT_COUNT> reachable{false};
std::vector<bool> stealthed;
spUnitTargetedPathFindingSystem pUnitTargetedPathFindingSystem;
};

using spUnitInfo = std::shared_ptr<UnitInfo>;

}
1 change: 1 addition & 0 deletions ai/heavyai/heavyai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ void HeavyAi::updateUnitCache(spQmlVectorUnit & pUnits)
cache[HeavyAiSharedData::AiCache::UnitMovementPoints] = pUnit->getMovementpoints(pos);
cache[HeavyAiSharedData::AiCache::MinFirerange] = pUnit->getMinRange(pos);
cache[HeavyAiSharedData::AiCache::MaxFirerange] = pUnit->getMaxRange(pos);
cache[HeavyAiSharedData::TerrainDefense] = pUnit->getTerrainDefense();
cache[HeavyAiSharedData::AiCache::CanMoveAndFire] = static_cast<qint32>(pUnit->canMoveAndFire(pos));
}
}
Expand Down
253 changes: 214 additions & 39 deletions ai/heavyai/situationevaluator.cpp
Original file line number Diff line number Diff line change
@@ -1,64 +1,217 @@
#include "ai/heavyai/situationevaluator.h"
#include "ai/heavyai/unittargetedpathfindingsystem.h"

#include "coreengine/globalutils.h"
#include "game/gamemap.h"



SituationEvaluator::SituationEvaluator(Player* pOwner)
: m_inputVector(1, UNIT_COUNT * UNIT_COUNT * HeavyAiSharedData::SituationFeatures::MaxFeatures),
m_searchRange(GlobalUtils::getSpCircle(0, SEARCH_RANGE)),
: m_inputVector(1, HeavyAiSharedData::UNIT_COUNT * HeavyAiSharedData::UNIT_COUNT * HeavyAiSharedData::SituationFeatures::MaxFeatures),
m_searchRange(GlobalUtils::getSpCircle(0, HeavyAiSharedData::SEARCH_RANGE)),
m_pOwner(pOwner)
{
for (qint32 i = 0; i < HeavyAiSharedData::UNIT_COUNT; ++i)
{
m_unitsInfo[i] = MemoryManagement::create<HeavyAiSharedData::UnitInfo>();
m_unitsInfo[i]->stealthed.resize(pOwner->getMap()->getPlayerCount());
}
}

void SituationEvaluator::updateInputVector(GameMap* pMap, const QPoint & searchPoint)
void SituationEvaluator::updateInputVector(GameMap* pMap, const QPoint & searchPoint, bool updateUnitData)
{
getUnitsInRange(pMap, searchPoint);
for (qint32 i = 0; i < UNIT_COUNT; ++i)
if (updateUnitData)
{
getUnitsInRange(pMap, searchPoint);
createPathFindingSystems(pMap);
}

for (qint32 i = 0; i < HeavyAiSharedData::UNIT_COUNT; ++i)
{
Unit* pUnit = m_unitsInfo[i].pUnit;
Unit* pUnit = m_unitsInfo[i]->pUnit;
if (pUnit == nullptr)
{
for (qint32 feature = 0; feature < HeavyAiSharedData::SituationFeatures::MaxFeatures; ++feature)
{
qint32 basePosition = UNIT_COUNT * UNIT_COUNT * feature + i * UNIT_COUNT;
for (qint32 enemyUnit = 0; enemyUnit < UNIT_COUNT; ++enemyUnit)
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
clearUnitInput(i);
}
else
{
for (qint32 feature = 0; feature < HeavyAiSharedData::SituationFeatures::MaxFeatures; ++feature)
{
qint32 basePosition = UNIT_COUNT * UNIT_COUNT * feature + i * UNIT_COUNT;
fillUnitInput(i);
}
}
}

}
void SituationEvaluator::clearUnitInput(qint32 index)
{
for (qint32 feature = 0; feature < HeavyAiSharedData::SituationFeatures::MaxFeatures; ++feature)
{
qint32 basePosition = HeavyAiSharedData::UNIT_COUNT * HeavyAiSharedData::UNIT_COUNT * feature + index * HeavyAiSharedData::UNIT_COUNT;
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

void SituationEvaluator::fillUnitInput(qint32 index)
{
for (qint32 feature = 0; feature < HeavyAiSharedData::SituationFeatures::MaxFeatures; ++feature)
{
qint32 basePosition = HeavyAiSharedData::UNIT_COUNT * HeavyAiSharedData::UNIT_COUNT * feature + index * HeavyAiSharedData::UNIT_COUNT;
using updateFeature = void (SituationEvaluator::*)(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo);
constexpr std::array<updateFeature, HeavyAiSharedData::SituationFeatures::MaxFeatures> featureCb{
&SituationEvaluator::updateHp,
&SituationEvaluator::updateHpDamage,
&SituationEvaluator::updateFundsDamage,
&SituationEvaluator::updateMovementPoints,
&SituationEvaluator::updateDistance,
&SituationEvaluator::updateHasMoved,
&SituationEvaluator::updateDefense,
&SituationEvaluator::updateRepairsOnPosition,
&SituationEvaluator::updateCapturePoints,
&SituationEvaluator::updateBuildingImportance,
&SituationEvaluator::updateStealthed,
};
(this->*featureCb[feature])(basePosition, m_unitsInfo[index]);
}
}

void SituationEvaluator::updateHp(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (shouldFillInfo(unitInfo, enemyUnit))
{
m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->pUnit->getHpRounded();
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

//void SituationEvaluator::updateHp(qint32 basePosition, const UnitInfo & unitInfo)
//{
// for (qint32 enemyUnit = 0; enemyUnit < UNIT_COUNT; ++enemyUnit)
// {
// if (unitInfo.multiplier != m_unitsInfo[enemyUnit].multiplier)
// {
// m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit].pUnit->getHpRounded();
// }
// else
// {
// m_inputVector(0, basePosition + enemyUnit) = 0;
// }
// }
//}
void SituationEvaluator::updateHpDamage(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{

}

void SituationEvaluator::updateFundsDamage(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{

}

void SituationEvaluator::updateMovementPoints(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (shouldFillInfo(unitInfo, enemyUnit))
{
m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->pUnit->getAiCache()[HeavyAiSharedData::AiCache::UnitMovementPoints];
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

void SituationEvaluator::updateDistance(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (m_unitsInfo[enemyUnit]->pUnit != nullptr)
{
m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->multiplier * GlobalUtils::getDistance(unitInfo->pUnit->getX(), unitInfo->pUnit->getY(),
m_unitsInfo[enemyUnit]->pUnit->getX(), m_unitsInfo[enemyUnit]->pUnit->getY());
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

void SituationEvaluator::updateHasMoved(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (unitInfo->reachable[enemyUnit])
{
m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->pUnit->getHasMoved();
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

void SituationEvaluator::updateDefense(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (shouldFillInfo(unitInfo, enemyUnit))
{
m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->pUnit->getAiCache()[HeavyAiSharedData::AiCache::TerrainDefense];
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

void SituationEvaluator::updateRepairsOnPosition(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{

}

void SituationEvaluator::updateCapturePoints(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (shouldFillInfo(unitInfo, enemyUnit))
{
m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->pUnit->getCapturePoints();
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

void SituationEvaluator::updateBuildingImportance(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{

}

void SituationEvaluator::updateStealthed(qint32 basePosition, const HeavyAiSharedData::spUnitInfo & unitInfo)
{
for (qint32 enemyUnit = 0; enemyUnit < HeavyAiSharedData::UNIT_COUNT; ++enemyUnit)
{
if (shouldFillInfo(unitInfo, enemyUnit))
{

m_inputVector(0, basePosition + enemyUnit) = m_unitsInfo[enemyUnit]->stealthed[unitInfo->pUnit->getOwner()->getPlayerID()];
}
else
{
m_inputVector(0, basePosition + enemyUnit) = 0;
}
}
}

bool SituationEvaluator::shouldFillInfo(const HeavyAiSharedData::spUnitInfo & unitInfo, qint32 enemyUnit)
{
return unitInfo->multiplier != m_unitsInfo[enemyUnit]->multiplier &&
unitInfo->reachable[enemyUnit];
}

void SituationEvaluator::getUnitsInRange(GameMap* pMap, const QPoint & searchPoint)
{
qint32 alliedPosition = 0;
qint32 enemyPosition = UNIT_COUNT - 1;
qint32 enemyPosition = HeavyAiSharedData::UNIT_COUNT - 1;
for (const auto & point : m_searchRange->getVector())
{
QPoint mapPoint = point + searchPoint;
Expand All @@ -70,14 +223,16 @@ void SituationEvaluator::getUnitsInRange(GameMap* pMap, const QPoint & searchPoi
{
if (m_pOwner->isEnemyUnit(pUnit))
{
m_unitsInfo[enemyPosition].pUnit = pUnit;
m_unitsInfo[enemyPosition].multiplier = -1;
m_unitsInfo[enemyPosition]->pUnit = pUnit;
m_unitsInfo[enemyPosition]->multiplier = -1;
updateStealthInfo(pMap, enemyPosition);
--enemyPosition;
}
else
{
m_unitsInfo[alliedPosition].pUnit = pUnit;
m_unitsInfo[alliedPosition].multiplier = 1;
m_unitsInfo[alliedPosition]->pUnit = pUnit;
m_unitsInfo[alliedPosition]->multiplier = 1;
updateStealthInfo(pMap, alliedPosition);
++alliedPosition;
}
if (alliedPosition > enemyPosition)
Expand All @@ -89,7 +244,27 @@ void SituationEvaluator::getUnitsInRange(GameMap* pMap, const QPoint & searchPoi
}
for (qint32 i = alliedPosition; i <= enemyPosition; ++i)
{
m_unitsInfo[enemyPosition].pUnit = nullptr;
m_unitsInfo[enemyPosition].multiplier = 1;
m_unitsInfo[enemyPosition]->pUnit = nullptr;
m_unitsInfo[enemyPosition]->pUnitTargetedPathFindingSystem.reset();
m_unitsInfo[enemyPosition]->multiplier = 1;
}
}

void SituationEvaluator::updateStealthInfo(GameMap* pMap, qint32 unitPosition)
{
for (qint32 i = 0; i < pMap->getPlayerCount(); ++i)
{
m_unitsInfo[unitPosition]->stealthed[i] = m_unitsInfo[unitPosition]->pUnit->isStealthed(pMap->getPlayer(i));
}
}

void SituationEvaluator::createPathFindingSystems(GameMap* pMap)
{
for (qint32 i = 0; i < HeavyAiSharedData::UNIT_COUNT; ++i)
{
if (m_unitsInfo[i]->pUnit != nullptr)
{
m_unitsInfo[i]->pUnitTargetedPathFindingSystem = MemoryManagement::create<UnitTargetedPathFindingSystem>(pMap, i, m_unitsInfo);
}
}
}
Loading

0 comments on commit 03ff67e

Please sign in to comment.