CGeniusAI.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #ifndef __CGENIUSAI_H__
  2. #define __CGENIUSAI_H__
  3. #define VCMI_DLL
  4. #pragma warning (disable: 4100 4251 4245 4018 4081)
  5. #include "../../global.h"
  6. #include "../../AI_Base.h"
  7. #include "../../CCallback.h"
  8. #include "../../hch/CCreatureHandler.h"
  9. #include "../../hch/CObjectHandler.h"
  10. #pragma warning (default: 4100 4251 4245 4018 4081)
  11. #pragma warning (disable: 4100)
  12. #ifdef __GNUC__
  13. #define strcpy_s(a, b, c) strncpy(a, c, b)
  14. #endif
  15. using namespace std;
  16. namespace GeniusAI {
  17. class CBattleHelper
  18. {
  19. public:
  20. CBattleHelper();
  21. ~CBattleHelper();
  22. int GetBattleFieldPosition(int x, int y);
  23. int DecodeXPosition(int battleFieldPosition);
  24. int DecodeYPosition(int battleFieldPosition);
  25. int GetShortestDistance(int pointA, int pointB);
  26. int GetDistanceWithObstacles(int pointA, int pointB);
  27. int GetVoteForMaxDamage() const { return m_voteForMaxDamage; }
  28. int GetVoteForMinDamage() const { return m_voteForMinDamage; }
  29. int GetVoteForMaxSpeed() const { return m_voteForMaxSpeed; }
  30. int GetVoteForDistance() const { return m_voteForDistance; }
  31. int GetVoteForDistanceFromShooters() const { return m_voteForDistanceFromShooters; }
  32. int GetVoteForHitPoints() const { return m_voteForHitPoints; }
  33. const int InfiniteDistance;
  34. const int BattlefieldWidth;
  35. const int BattlefieldHeight;
  36. private:
  37. int m_voteForMaxDamage;
  38. int m_voteForMinDamage;
  39. int m_voteForMaxSpeed;
  40. int m_voteForDistance;
  41. int m_voteForDistanceFromShooters;
  42. int m_voteForHitPoints;
  43. CBattleHelper(const CBattleHelper &);
  44. CBattleHelper &operator=(const CBattleHelper &);
  45. };
  46. /**
  47. * Maybe it is a additional proxy, but i've separated the game IA for transparent.
  48. */
  49. class CBattleLogic
  50. {
  51. private:
  52. enum EMainStrategyType
  53. {
  54. strategy_super_aggresive,
  55. strategy_aggresive,
  56. strategy_neutral,
  57. strategy_defensive,
  58. strategy_super_defensive,
  59. strategy_berserk_attack /** cause max damage, usually when creatures fight against overwhelming army*/
  60. };
  61. enum ECreatureRoleInBattle
  62. {
  63. creature_role_shooter,
  64. creature_role_defenser,
  65. creature_role_fast_attacker,
  66. creature_role_attacker
  67. };
  68. enum EActionType
  69. {
  70. action_cancel = 0, // Cancel BattleAction
  71. action_cast_spell = 1, // Hero cast a spell
  72. action_walk = 2, // Walk
  73. action_defend = 3, // Defend
  74. action_retreat = 4, // Retreat from the battle
  75. action_surrender = 5, // Surrender
  76. action_walk_and_attack = 6, // Walk and Attack
  77. action_shoot = 7, // Shoot
  78. action_wait = 8, // Wait
  79. action_catapult = 9, // Catapult
  80. action_monster_casts_spell = 10 // Monster casts a spell (i.e. Faerie Dragons)
  81. };
  82. struct SCreatureCasualties
  83. {
  84. int amount_max; // amount of creatures that will be dead
  85. int amount_min;
  86. int damage_max; // number of hit points that creature will lost
  87. int damage_min;
  88. int leftHitPoints_for_max; // number of hit points that will remain (for last unity)
  89. int leftHitPoint_for_min; // scenario
  90. };
  91. public:
  92. CBattleLogic(ICallback *cb, CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side);
  93. ~CBattleLogic();
  94. void SetCurrentTurn(int turn);
  95. /**
  96. * Get the final decision.
  97. */
  98. BattleAction MakeDecision(int stackID);
  99. private:
  100. CBattleHelper m_battleHelper;
  101. //BattleInfo m_battleInfo;
  102. int m_iCurrentTurn;
  103. bool m_bIsAttacker;
  104. ICallback *m_cb;
  105. CCreatureSet *m_army1;
  106. CCreatureSet *m_army2;
  107. int3 m_tile;
  108. CGHeroInstance *m_hero1;
  109. CGHeroInstance *m_hero2;
  110. bool m_side;
  111. // statistics
  112. typedef std::vector<std::pair<int, int> > creature_stat; // first - creature id, second - value
  113. creature_stat m_statMaxDamage;
  114. creature_stat m_statMinDamage;
  115. //
  116. creature_stat m_statMaxSpeed;
  117. creature_stat m_statDistance;
  118. creature_stat m_statDistanceFromShooters;
  119. creature_stat m_statHitPoints;
  120. typedef std::vector<std::pair<int, SCreatureCasualties> > creature_stat_casualties;
  121. creature_stat_casualties m_statCasualties;
  122. bool m_bEnemyDominates;
  123. /**
  124. * Before decision we have to make some calculation and simulation.
  125. */
  126. void MakeStatistics(int currentCreatureId);
  127. /**
  128. * Helper function. It's used for performing an attack action.
  129. */
  130. std::vector<int> GetAvailableHexesForAttacker(CStack *defender, CStack *attacker = NULL);
  131. /**
  132. * Just make defend action.
  133. */
  134. BattleAction MakeDefend(int stackID);
  135. /**
  136. * Just make wait action.
  137. */
  138. BattleAction MakeWait(int stackID);
  139. /**
  140. * Make an attack action if it's possible.
  141. * If it's not possible then function returns defend action.
  142. */
  143. BattleAction MakeAttack(int attackerID, int destinationID);
  144. /**
  145. * Berserk mode - do maximum casualties.
  146. * Return vector wiht IDs of creatures to attack,
  147. * additional info: -2 means wait, -1 - defend, 0 - make attack
  148. */
  149. list<int> PerformBerserkAttack(int stackID, int &additionalInfo);
  150. /**
  151. * Normal mode - equilibrium between casualties and yields.
  152. * Return vector wiht IDs of creatures to attack,
  153. * additional info: -2 means wait, -1 - defend, 0 - make attack
  154. */
  155. list<int> PerformDefaultAction(int stackID, int &additionalInfo);
  156. /**
  157. * Only for debug purpose.
  158. */
  159. void PrintBattleAction(const BattleAction &action);
  160. };
  161. class CGeniusAI : public CGlobalAI
  162. {
  163. private:
  164. ICallback *m_cb;
  165. CBattleLogic *m_battleLogic;
  166. public:
  167. virtual void init(ICallback * CB);
  168. virtual void yourTurn();
  169. virtual void heroKilled(const CGHeroInstance *);
  170. virtual void heroCreated(const CGHeroInstance *);
  171. virtual void heroMoved(const HeroMoveDetails &);
  172. virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
  173. virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
  174. virtual void tileRevealed(int3 pos){};
  175. virtual void tileHidden(int3 pos){};
  176. virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
  177. // battle
  178. virtual void actionFinished(const BattleAction *action);//occurs AFTER every action taken by any stack or by the hero
  179. virtual void actionStarted(const BattleAction *action);//occurs BEFORE every action taken by any stack or by the hero
  180. virtual void battleAttack(BattleAttack *ba); //called when stack is performing attack
  181. virtual void battleStacksAttacked(std::set<BattleStackAttacked> & bsa); //called when stack receives damage (after battleAttack())
  182. virtual void battleEnd(BattleResult *br);
  183. virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
  184. virtual void battleStackMoved(int ID, int dest);
  185. virtual void battleSpellCasted(SpellCasted *sc);
  186. virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
  187. virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
  188. //
  189. virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving);
  190. virtual void battleStackAttacking(int ID, int dest);
  191. virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting);
  192. virtual BattleAction activeStack(int stackID);
  193. };
  194. }
  195. #endif // __CGENIUSAI_H__