PotentialTargets.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * PotentialTargets.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "PotentialTargets.h"
  12. PotentialTargets::PotentialTargets(const CStack *attacker, const HypotheticChangesToBattleState &state /*= HypotheticChangesToBattleState()*/)
  13. {
  14. auto dists = getCbc()->battleGetDistances(attacker);
  15. auto avHexes = getCbc()->battleGetAvailableHexes(attacker, false);
  16. for(const CStack *enemy : getCbc()->battleGetStacks())
  17. {
  18. //Consider only stacks of different owner
  19. if(enemy->attackerOwned == attacker->attackerOwned)
  20. continue;
  21. auto GenerateAttackInfo = [&](bool shooting, BattleHex hex) -> AttackPossibility
  22. {
  23. auto bai = BattleAttackInfo(attacker, enemy, shooting);
  24. bai.attackerBonuses = getValOr(state.bonusesOfStacks, bai.attacker, bai.attacker);
  25. bai.defenderBonuses = getValOr(state.bonusesOfStacks, bai.defender, bai.defender);
  26. if(hex.isValid())
  27. {
  28. assert(dists[hex] <= attacker->Speed());
  29. bai.chargedFields = dists[hex];
  30. }
  31. return AttackPossibility::evaluate(bai, state, hex);
  32. };
  33. if(getCbc()->battleCanShoot(attacker, enemy->position))
  34. {
  35. possibleAttacks.push_back(GenerateAttackInfo(true, BattleHex::INVALID));
  36. }
  37. else
  38. {
  39. for(BattleHex hex : avHexes)
  40. if(CStack::isMeleeAttackPossible(attacker, enemy, hex))
  41. possibleAttacks.push_back(GenerateAttackInfo(false, hex));
  42. if(!vstd::contains_if(possibleAttacks, [=](const AttackPossibility &pa) { return pa.enemy == enemy; }))
  43. unreachableEnemies.push_back(enemy);
  44. }
  45. }
  46. }
  47. int PotentialTargets::bestActionValue() const
  48. {
  49. if(possibleAttacks.empty())
  50. return 0;
  51. return bestAction().attackValue();
  52. }
  53. AttackPossibility PotentialTargets::bestAction() const
  54. {
  55. if(possibleAttacks.empty())
  56. throw std::runtime_error("No best action, since we don't have any actions");
  57. return *vstd::maxElementByFun(possibleAttacks, [](const AttackPossibility &ap) { return ap.attackValue(); } );
  58. }