mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
BattleAI: better retaliation calculation
This commit is contained in:
parent
ff33fbd3a0
commit
b3fc6743d9
@ -42,7 +42,7 @@ float BattleExchangeVariant::trackAttack(
|
||||
for(auto affectedUnit : affectedUnits)
|
||||
{
|
||||
auto unitToUpdate = hb->getForUpdate(affectedUnit->unitId());
|
||||
auto damageDealt = unitToUpdate->getTotalHealth() - affectedUnit->getTotalHealth();
|
||||
auto damageDealt = unitToUpdate->getAvailableHealth() - affectedUnit->getAvailableHealth();
|
||||
|
||||
if(damageDealt > 0)
|
||||
{
|
||||
@ -58,7 +58,7 @@ float BattleExchangeVariant::trackAttack(
|
||||
#if BATTLE_TRACE_LEVEL>=1
|
||||
logAi->trace(
|
||||
"%s -> %s, ap retaliation, %s, dps: %lld",
|
||||
ap.attack.defender->getDescription(),
|
||||
hb->getForUpdate(ap.attack.defender->unitId())->getDescription(),
|
||||
ap.attack.attacker->getDescription(),
|
||||
ap.attack.shooting ? "shot" : "mellee",
|
||||
damageDealt);
|
||||
@ -456,14 +456,14 @@ ReachabilityData BattleExchangeEvaluator::getExchangeUnits(
|
||||
for(auto unit : turnOrder[turn])
|
||||
{
|
||||
if(vstd::contains(allReachableUnits, unit))
|
||||
result.units.push_back(unit);
|
||||
}
|
||||
result.units[turn].push_back(unit);
|
||||
}
|
||||
|
||||
vstd::erase_if(result.units, [&](const battle::Unit * u) -> bool
|
||||
vstd::erase_if(result.units[turn], [&](const battle::Unit * u) -> bool
|
||||
{
|
||||
return !hb->battleGetUnitByID(u->unitId())->alive();
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -523,7 +523,9 @@ BattleScore BattleExchangeEvaluator::calculateExchange(
|
||||
auto exchangeBattle = std::make_shared<HypotheticBattle>(env.get(), hb);
|
||||
BattleExchangeVariant v;
|
||||
|
||||
for(auto unit : exchangeUnits.units)
|
||||
for(int turn = 0; turn < exchangeUnits.units.size(); turn++)
|
||||
{
|
||||
for(auto unit : exchangeUnits.units.at(turn))
|
||||
{
|
||||
if(unit->isTurret())
|
||||
continue;
|
||||
@ -541,6 +543,7 @@ BattleScore BattleExchangeEvaluator::calculateExchange(
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto melleeAttackers = ourStacks;
|
||||
|
||||
@ -552,7 +555,9 @@ BattleScore BattleExchangeEvaluator::calculateExchange(
|
||||
|
||||
bool canUseAp = true;
|
||||
|
||||
for(auto activeUnit : exchangeUnits.units)
|
||||
for(int turn = 0; turn < exchangeUnits.units.size(); turn++)
|
||||
{
|
||||
for(auto activeUnit : exchangeUnits.units.at(turn))
|
||||
{
|
||||
bool isOur = exchangeBattle->battleMatchOwner(ap.attack.attacker, activeUnit, true);
|
||||
battle::Units & attackerQueue = isOur ? ourStacks : enemyStacks;
|
||||
@ -563,7 +568,7 @@ BattleScore BattleExchangeEvaluator::calculateExchange(
|
||||
if(!attacker->alive())
|
||||
{
|
||||
#if BATTLE_TRACE_LEVEL>=1
|
||||
logAi->trace( "Attacker is dead");
|
||||
logAi->trace("Attacker is dead");
|
||||
#endif
|
||||
|
||||
continue;
|
||||
@ -613,7 +618,7 @@ BattleScore BattleExchangeEvaluator::calculateExchange(
|
||||
if(!exchangeBattle->getForUpdate(u->unitId())->alive())
|
||||
return false;
|
||||
|
||||
if (!u->getPosition().isValid())
|
||||
if(!u->getPosition().isValid())
|
||||
return false; // e.g. tower shooters
|
||||
|
||||
return vstd::contains_if(reachabilityMap.at(u->getPosition()), [&attacker](const battle::Unit * other) -> bool
|
||||
@ -670,6 +675,9 @@ BattleScore BattleExchangeEvaluator::calculateExchange(
|
||||
});
|
||||
}
|
||||
|
||||
exchangeBattle->nextRound();
|
||||
}
|
||||
|
||||
// avoid blocking path for stronger stack by weaker stack
|
||||
// the method checks if all stacks can be placed around enemy
|
||||
std::map<BattleHex, battle::Units> reachabilityMap;
|
||||
|
@ -113,7 +113,7 @@ private:
|
||||
|
||||
struct ReachabilityData
|
||||
{
|
||||
std::vector<const battle::Unit *> units;
|
||||
std::map<int, std::vector<const battle::Unit *>> units;
|
||||
|
||||
// shooters which are within mellee attack and mellee units
|
||||
std::vector<const battle::Unit *> melleeAccessible;
|
||||
|
Loading…
Reference in New Issue
Block a user