Goals.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #pragma once
  2. #include "../../lib/VCMI_Lib.h"
  3. #include "../../lib/CObjectHandler.h"
  4. #include "../../lib/CBuildingHandler.h"
  5. #include "../../lib/CCreatureHandler.h"
  6. #include "../../lib/CTownHandler.h"
  7. #include "AIUtility.h"
  8. /*
  9. * Goals.h, part of VCMI engine
  10. *
  11. * Authors: listed in file AUTHORS in main folder
  12. *
  13. * License: GNU General Public License v2.0 or later
  14. * Full text of license available in license.txt file, in main folder
  15. *
  16. */
  17. struct HeroPtr;
  18. class VCAI;
  19. class FuzzyHelper;
  20. namespace Goals
  21. {
  22. struct AbstractGoal;
  23. class VisitTile;
  24. typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
  25. typedef std::vector<TSubgoal> TGoalVec;
  26. enum EGoals
  27. {
  28. INVALID = -1,
  29. WIN, DO_NOT_LOSE, CONQUER, BUILD, //build needs to get a real reasoning
  30. EXPLORE, GATHER_ARMY, BOOST_HERO,
  31. RECRUIT_HERO,
  32. BUILD_STRUCTURE, //if hero set, then in visited town
  33. COLLECT_RES,
  34. GATHER_TROOPS, // val of creatures with objid
  35. OBJECT_GOALS_BEGIN,
  36. GET_OBJ, //visit or defeat or collect the object
  37. FIND_OBJ, //find and visit any obj with objid + resid //TODO: consider universal subid for various types (aid, bid)
  38. VISIT_HERO, //heroes can move around - set goal abstract and track hero every turn
  39. GET_ART_TYPE,
  40. //BUILD_STRUCTURE,
  41. ISSUE_COMMAND,
  42. VISIT_TILE, //tile, in conjunction with hero elementar; assumes tile is reachable
  43. CLEAR_WAY_TO,
  44. DIG_AT_TILE //elementar with hero on tile
  45. };
  46. //method chaining + clone pattern
  47. #define VSETTER(type, field) virtual AbstractGoal & set ## field(const type &rhs) = 0;
  48. #define OSETTER(type, field) CGoal<T> & set ## field(const type &rhs) override { field = rhs; return *this; };
  49. #if 0
  50. #define SETTER
  51. #endif // _DEBUG
  52. enum {LOW_PR = -1};
  53. class AbstractGoal
  54. {
  55. public:
  56. bool isElementar; VSETTER(bool, isElementar)
  57. bool isAbstract; VSETTER(bool, isAbstract)
  58. float priority; VSETTER(float, priority)
  59. int value; VSETTER(int, value)
  60. int resID; VSETTER(int, resID)
  61. int objid; VSETTER(int, objid)
  62. int aid; VSETTER(int, aid)
  63. int3 tile; VSETTER(int3, tile)
  64. HeroPtr hero; VSETTER(HeroPtr, hero)
  65. const CGTownInstance *town; VSETTER(CGTownInstance *, town)
  66. int bid; VSETTER(int, bid)
  67. AbstractGoal (EGoals goal = INVALID) : goalType (goal)
  68. {
  69. priority = 0;
  70. isElementar = false;
  71. isAbstract = false;
  72. value = 0;
  73. aid = -1;
  74. resID = -1;
  75. tile = int3(-1, -1, -1);
  76. town = nullptr;
  77. }
  78. virtual ~AbstractGoal(){};
  79. virtual AbstractGoal * clone() const = 0;
  80. EGoals goalType;
  81. std::string name() const;
  82. virtual std::string completeMessage() const {return "This goal is unspecified!";};
  83. bool invalid() const;
  84. static TSubgoal goVisitOrLookFor(const CGObjectInstance *obj); //if obj is nullptr, then we'll explore
  85. static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
  86. static TSubgoal tryRecruitHero();
  87. virtual TGoalVec getAllPossibleSubgoals() = 0;
  88. virtual TSubgoal whatToDoToAchieve() = 0;
  89. ///Visitor pattern
  90. //TODO: make accept work for shared_ptr... somehow
  91. virtual void accept (VCAI * ai); //unhandled goal will report standard error
  92. virtual float accept (FuzzyHelper * f);
  93. virtual bool operator== (AbstractGoal &g)
  94. {
  95. return false;
  96. }
  97. virtual bool fulfillsMe (Goals::TSubgoal goal) //TODO: multimethod instead of type check
  98. {
  99. return false;
  100. }
  101. //template <typename Handler> void serialize(Handler &h, const int version)
  102. //{
  103. // h & goalType & isElementar & isAbstract & priority;
  104. // h & value & resID & objid & aid & tile & hero & town & bid;
  105. //}
  106. };
  107. template <typename T> class CGoal : public AbstractGoal
  108. {
  109. public:
  110. CGoal<T> (EGoals goal = INVALID) : AbstractGoal (goal)
  111. {
  112. priority = 0;
  113. isElementar = false;
  114. isAbstract = false;
  115. value = 0;
  116. aid = -1;
  117. resID = -1;
  118. tile = int3(-1, -1, -1);
  119. town = nullptr;
  120. }
  121. //virtual TSubgoal whatToDoToAchieve() override; //can't have virtual and template class at once
  122. OSETTER(bool, isElementar)
  123. OSETTER(bool, isAbstract)
  124. OSETTER(float, priority)
  125. OSETTER(int, value)
  126. OSETTER(int, resID)
  127. OSETTER(int, objid)
  128. OSETTER(int, aid)
  129. OSETTER(int3, tile)
  130. OSETTER(HeroPtr, hero)
  131. OSETTER(CGTownInstance *, town)
  132. OSETTER(int, bid)
  133. void accept (VCAI * ai) override;
  134. float accept (FuzzyHelper * f) override;
  135. //float importanceWhenLocked() const override;
  136. CGoal<T> * clone() const override
  137. {
  138. return new T(static_cast<T const&>(*this)); //casting enforces template instantiation
  139. }
  140. TSubgoal iAmElementar()
  141. {
  142. setisElementar(true);
  143. shared_ptr<AbstractGoal> ptr;
  144. ptr.reset(clone());
  145. return ptr;
  146. }
  147. template <typename Handler> void serialize(Handler &h, const int version)
  148. {
  149. h & goalType & isElementar & isAbstract & priority;
  150. h & value & resID & objid & aid & tile & hero & town & bid;
  151. }
  152. };
  153. TSubgoal sptr(const AbstractGoal & tmp);
  154. class Invalid : public CGoal<Invalid>
  155. {
  156. public:
  157. Invalid() : CGoal (Goals::INVALID) {priority = -1e10;};
  158. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  159. TSubgoal whatToDoToAchieve() override;
  160. };
  161. class Win : public CGoal<Win>
  162. {
  163. public:
  164. Win() : CGoal (Goals::WIN) {priority = 100;};
  165. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  166. TSubgoal whatToDoToAchieve() override;
  167. };
  168. class NotLose : public CGoal<NotLose>
  169. {
  170. public:
  171. NotLose() : CGoal (Goals::DO_NOT_LOSE) {priority = 100;};
  172. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  173. TSubgoal whatToDoToAchieve() override;
  174. };
  175. class Conquer : public CGoal<Conquer>
  176. {
  177. public:
  178. Conquer() : CGoal (Goals::CONQUER) {priority = 10;};
  179. TGoalVec getAllPossibleSubgoals() override;
  180. TSubgoal whatToDoToAchieve() override;
  181. };
  182. class Build : public CGoal<Build>
  183. {
  184. public:
  185. Build() : CGoal (Goals::BUILD) {priority = 1;};
  186. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  187. TSubgoal whatToDoToAchieve() override;
  188. };
  189. class Explore : public CGoal<Explore>
  190. {
  191. public:
  192. Explore() : CGoal (Goals::EXPLORE){priority = 1;};
  193. Explore(HeroPtr h) : CGoal (Goals::EXPLORE){hero = h;};
  194. TGoalVec getAllPossibleSubgoals() override;
  195. TSubgoal whatToDoToAchieve() override;
  196. std::string completeMessage() const override;
  197. bool fulfillsMe (TSubgoal goal) override;
  198. };
  199. class GatherArmy : public CGoal<GatherArmy>
  200. {
  201. private:
  202. GatherArmy() : CGoal (Goals::GATHER_ARMY){};
  203. public:
  204. GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val; priority = 2.5;};
  205. TGoalVec getAllPossibleSubgoals() override;
  206. TSubgoal whatToDoToAchieve() override;
  207. std::string completeMessage() const override;
  208. };
  209. class BoostHero : public CGoal<BoostHero>
  210. {
  211. public:
  212. BoostHero() : CGoal (Goals::INVALID){priority = -1e10;}; //TODO
  213. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  214. TSubgoal whatToDoToAchieve() override;
  215. };
  216. class RecruitHero : public CGoal<RecruitHero>
  217. {
  218. public:
  219. RecruitHero() : CGoal (Goals::RECRUIT_HERO){priority = 1;};
  220. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  221. TSubgoal whatToDoToAchieve() override;
  222. };
  223. class BuildThis : public CGoal<BuildThis>
  224. {
  225. private:
  226. BuildThis() : CGoal (Goals::BUILD_STRUCTURE){};
  227. public:
  228. BuildThis(BuildingID Bid, const CGTownInstance *tid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; town = tid; priority = 5;};
  229. BuildThis(BuildingID Bid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; priority = 5;};
  230. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  231. TSubgoal whatToDoToAchieve() override;
  232. };
  233. class CollectRes : public CGoal<CollectRes>
  234. {
  235. private:
  236. CollectRes() : CGoal (Goals::COLLECT_RES){};
  237. public:
  238. CollectRes(int rid, int val) : CGoal (Goals::COLLECT_RES) {resID = rid; value = val; priority = 2;};
  239. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  240. TSubgoal whatToDoToAchieve() override;
  241. };
  242. class GatherTroops : public CGoal<GatherTroops>
  243. {
  244. private:
  245. GatherTroops() : CGoal (Goals::GATHER_TROOPS){priority = 2;};
  246. public:
  247. GatherTroops(int type, int val) : CGoal (Goals::GATHER_TROOPS){objid = type; value = val; priority = 2;};
  248. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  249. TSubgoal whatToDoToAchieve() override;
  250. };
  251. class GetObj : public CGoal<GetObj>
  252. {
  253. private:
  254. GetObj() {}; // empty constructor not allowed
  255. public:
  256. GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid; priority = 3;};
  257. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  258. TSubgoal whatToDoToAchieve() override;
  259. bool operator== (GetObj &g) {return g.objid == objid;}
  260. bool fulfillsMe (TSubgoal goal) override;
  261. std::string completeMessage() const override;
  262. };
  263. class FindObj : public CGoal<FindObj>
  264. {
  265. private:
  266. FindObj() {}; // empty constructor not allowed
  267. public:
  268. FindObj(int ID) : CGoal(Goals::FIND_OBJ) {objid = ID; priority = 1;};
  269. FindObj(int ID, int subID) : CGoal(Goals::FIND_OBJ) {objid = ID; resID = subID; priority = 1;};
  270. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  271. TSubgoal whatToDoToAchieve() override;
  272. };
  273. class VisitHero : public CGoal<VisitHero>
  274. {
  275. private:
  276. VisitHero() : CGoal (Goals::VISIT_HERO){};
  277. public:
  278. VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid; priority = 4;};
  279. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  280. TSubgoal whatToDoToAchieve() override;
  281. bool operator== (VisitHero &g) {return g.objid == objid;}
  282. bool fulfillsMe (TSubgoal goal) override;
  283. std::string completeMessage() const override;
  284. };
  285. class GetArtOfType : public CGoal<GetArtOfType>
  286. {
  287. private:
  288. GetArtOfType() : CGoal (Goals::GET_ART_TYPE){};
  289. public:
  290. GetArtOfType(int type) : CGoal (Goals::GET_ART_TYPE){aid = type; priority = 2;};
  291. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  292. TSubgoal whatToDoToAchieve() override;
  293. };
  294. class VisitTile : public CGoal<VisitTile>
  295. //tile, in conjunction with hero elementar; assumes tile is reachable
  296. {
  297. private:
  298. VisitTile() {}; // empty constructor not allowed
  299. public:
  300. VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile; priority = 5;};
  301. TGoalVec getAllPossibleSubgoals() override;
  302. TSubgoal whatToDoToAchieve() override;
  303. bool operator== (VisitTile &g) {return g.tile == tile;}
  304. std::string completeMessage() const override;
  305. };
  306. class ClearWayTo : public CGoal<ClearWayTo>
  307. {
  308. public:
  309. ClearWayTo(int3 Tile) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile; priority = 5;};
  310. TGoalVec getAllPossibleSubgoals() override;
  311. TSubgoal whatToDoToAchieve() override;
  312. bool operator== (ClearWayTo &g) {return g.tile == tile;}
  313. };
  314. class DigAtTile : public CGoal<DigAtTile>
  315. //elementar with hero on tile
  316. {
  317. private:
  318. DigAtTile() : CGoal (Goals::DIG_AT_TILE){};
  319. public:
  320. DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile; priority = 20;};
  321. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  322. TSubgoal whatToDoToAchieve() override;
  323. bool operator== (DigAtTile &g) {return g.tile == tile;}
  324. };
  325. class CIssueCommand : public CGoal<CIssueCommand>
  326. {
  327. std::function<bool()> command;
  328. public:
  329. CIssueCommand(std::function<bool()> _command): CGoal(ISSUE_COMMAND), command(_command) {priority = 1e10;};
  330. TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
  331. TSubgoal whatToDoToAchieve() override;
  332. };
  333. }