Goals.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /*
  2. * Goals.h, 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. #pragma once
  11. #include "../../lib/VCMI_Lib.h"
  12. #include "../../lib/CBuildingHandler.h"
  13. #include "../../lib/CCreatureHandler.h"
  14. #include "../../lib/CTownHandler.h"
  15. #include "AIUtility.h"
  16. struct HeroPtr;
  17. class VCAI;
  18. class FuzzyHelper;
  19. namespace Goals
  20. {
  21. class AbstractGoal;
  22. class VisitTile;
  23. class DLL_EXPORT TSubgoal : public std::shared_ptr<Goals::AbstractGoal>
  24. {
  25. public:
  26. bool operator==(const TSubgoal & rhs) const;
  27. bool operator<(const TSubgoal & rhs) const;
  28. //TODO: serialize?
  29. };
  30. typedef std::vector<TSubgoal> TGoalVec;
  31. enum EGoals
  32. {
  33. INVALID = -1,
  34. WIN, DO_NOT_LOSE, CONQUER, BUILD, //build needs to get a real reasoning
  35. EXPLORE, GATHER_ARMY,
  36. BOOST_HERO,
  37. RECRUIT_HERO,
  38. BUILD_STRUCTURE, //if hero set, then in visited town
  39. COLLECT_RES,
  40. GATHER_TROOPS, // val of creatures with objid
  41. OBJECT_GOALS_BEGIN,
  42. VISIT_OBJ, //visit or defeat or collect the object
  43. FIND_OBJ, //find and visit any obj with objid + resid //TODO: consider universal subid for various types (aid, bid)
  44. VISIT_HERO, //heroes can move around - set goal abstract and track hero every turn
  45. GET_ART_TYPE,
  46. //BUILD_STRUCTURE,
  47. ISSUE_COMMAND,
  48. VISIT_TILE, //tile, in conjunction with hero elementar; assumes tile is reachable
  49. CLEAR_WAY_TO,
  50. DIG_AT_TILE,//elementar with hero on tile
  51. BUY_ARMY, //at specific town
  52. TRADE //val resID at object objid
  53. };
  54. //method chaining + clone pattern
  55. #define VSETTER(type, field) virtual AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
  56. #define OSETTER(type, field) CGoal<T> & set ## field(const type &rhs) override { field = rhs; return *this; };
  57. #if 0
  58. #define SETTER
  59. #endif // _DEBUG
  60. enum {LOW_PR = -1};
  61. DLL_EXPORT TSubgoal sptr(const AbstractGoal & tmp);
  62. class DLL_EXPORT AbstractGoal
  63. {
  64. public:
  65. bool isElementar; VSETTER(bool, isElementar)
  66. bool isAbstract; VSETTER(bool, isAbstract)
  67. float priority; VSETTER(float, priority)
  68. int value; VSETTER(int, value)
  69. int resID; VSETTER(int, resID)
  70. int objid; VSETTER(int, objid)
  71. int aid; VSETTER(int, aid)
  72. int3 tile; VSETTER(int3, tile)
  73. HeroPtr hero; VSETTER(HeroPtr, hero)
  74. const CGTownInstance *town; VSETTER(CGTownInstance *, town)
  75. int bid; VSETTER(int, bid)
  76. AbstractGoal(EGoals goal = INVALID)
  77. : goalType (goal)
  78. {
  79. priority = 0;
  80. isElementar = false;
  81. isAbstract = false;
  82. value = 0;
  83. aid = -1;
  84. resID = -1;
  85. objid = -1;
  86. tile = int3(-1, -1, -1);
  87. town = nullptr;
  88. bid = -1;
  89. }
  90. virtual ~AbstractGoal(){}
  91. //FIXME: abstract goal should be abstract, but serializer fails to instantiate subgoals in such case
  92. virtual AbstractGoal * clone() const
  93. {
  94. return const_cast<AbstractGoal *>(this);
  95. }
  96. virtual TGoalVec getAllPossibleSubgoals()
  97. {
  98. return TGoalVec();
  99. }
  100. virtual TSubgoal whatToDoToAchieve()
  101. {
  102. return sptr(AbstractGoal());
  103. }
  104. EGoals goalType;
  105. std::string name() const;
  106. virtual std::string completeMessage() const
  107. {
  108. return "This goal is unspecified!";
  109. }
  110. bool invalid() const;
  111. static TSubgoal goVisitOrLookFor(const CGObjectInstance * obj); //if obj is nullptr, then we'll explore
  112. static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
  113. static TSubgoal tryRecruitHero();
  114. ///Visitor pattern
  115. //TODO: make accept work for std::shared_ptr... somehow
  116. virtual void accept(VCAI * ai); //unhandled goal will report standard error
  117. virtual float accept(FuzzyHelper * f);
  118. virtual bool operator==(AbstractGoal & g);
  119. bool operator<(AbstractGoal & g); //final
  120. virtual bool fulfillsMe(Goals::TSubgoal goal) //TODO: multimethod instead of type check
  121. {
  122. return false; //use this method to check if goal is fulfilled by another (not equal) goal, operator == is handled spearately
  123. }
  124. template<typename Handler> void serialize(Handler & h, const int version)
  125. {
  126. h & goalType;
  127. h & isElementar;
  128. h & isAbstract;
  129. h & priority;
  130. h & value;
  131. h & resID;
  132. h & objid;
  133. h & aid;
  134. h & tile;
  135. h & hero;
  136. h & town;
  137. h & bid;
  138. }
  139. };
  140. template<typename T> class DLL_EXPORT CGoal : public AbstractGoal
  141. {
  142. public:
  143. CGoal<T>(EGoals goal = INVALID) : AbstractGoal(goal)
  144. {
  145. priority = 0;
  146. isElementar = false;
  147. isAbstract = false;
  148. value = 0;
  149. aid = -1;
  150. objid = -1;
  151. resID = -1;
  152. tile = int3(-1, -1, -1);
  153. town = nullptr;
  154. }
  155. OSETTER(bool, isElementar)
  156. OSETTER(bool, isAbstract)
  157. OSETTER(float, priority)
  158. OSETTER(int, value)
  159. OSETTER(int, resID)
  160. OSETTER(int, objid)
  161. OSETTER(int, aid)
  162. OSETTER(int3, tile)
  163. OSETTER(HeroPtr, hero)
  164. OSETTER(CGTownInstance *, town)
  165. OSETTER(int, bid)
  166. void accept(VCAI * ai) override;
  167. float accept(FuzzyHelper * f) override;
  168. CGoal<T> * clone() const override
  169. {
  170. return new T(static_cast<T const &>(*this)); //casting enforces template instantiation
  171. }
  172. TSubgoal iAmElementar()
  173. {
  174. setisElementar(true); //FIXME: it's not const-correct, maybe we shoudl only set returned clone?
  175. TSubgoal ptr;
  176. ptr.reset(clone());
  177. return ptr;
  178. }
  179. template<typename Handler> void serialize(Handler & h, const int version)
  180. {
  181. h & static_cast<AbstractGoal &>(*this);
  182. //h & goalType & isElementar & isAbstract & priority;
  183. //h & value & resID & objid & aid & tile & hero & town & bid;
  184. }
  185. };
  186. class DLL_EXPORT Invalid : public CGoal<Invalid>
  187. {
  188. public:
  189. Invalid()
  190. : CGoal(Goals::INVALID)
  191. {
  192. priority = -1e10;
  193. }
  194. TGoalVec getAllPossibleSubgoals() override
  195. {
  196. return TGoalVec();
  197. }
  198. TSubgoal whatToDoToAchieve() override;
  199. };
  200. class DLL_EXPORT Win : public CGoal<Win>
  201. {
  202. public:
  203. Win()
  204. : CGoal(Goals::WIN)
  205. {
  206. priority = 100;
  207. }
  208. TGoalVec getAllPossibleSubgoals() override
  209. {
  210. return TGoalVec();
  211. }
  212. TSubgoal whatToDoToAchieve() override;
  213. };
  214. class DLL_EXPORT NotLose : public CGoal<NotLose>
  215. {
  216. public:
  217. NotLose()
  218. : CGoal(Goals::DO_NOT_LOSE)
  219. {
  220. priority = 100;
  221. }
  222. TGoalVec getAllPossibleSubgoals() override
  223. {
  224. return TGoalVec();
  225. }
  226. //TSubgoal whatToDoToAchieve() override;
  227. };
  228. class DLL_EXPORT Conquer : public CGoal<Conquer>
  229. {
  230. public:
  231. Conquer()
  232. : CGoal(Goals::CONQUER)
  233. {
  234. priority = 10;
  235. }
  236. TGoalVec getAllPossibleSubgoals() override;
  237. TSubgoal whatToDoToAchieve() override;
  238. };
  239. class DLL_EXPORT Build : public CGoal<Build>
  240. {
  241. public:
  242. Build()
  243. : CGoal(Goals::BUILD)
  244. {
  245. priority = 1;
  246. }
  247. TGoalVec getAllPossibleSubgoals() override;
  248. TSubgoal whatToDoToAchieve() override;
  249. bool fulfillsMe(TSubgoal goal) override;
  250. };
  251. class DLL_EXPORT Explore : public CGoal<Explore>
  252. {
  253. public:
  254. Explore()
  255. : CGoal(Goals::EXPLORE)
  256. {
  257. priority = 1;
  258. }
  259. Explore(HeroPtr h)
  260. : CGoal(Goals::EXPLORE)
  261. {
  262. hero = h;
  263. priority = 1;
  264. }
  265. TGoalVec getAllPossibleSubgoals() override;
  266. TSubgoal whatToDoToAchieve() override;
  267. std::string completeMessage() const override;
  268. bool fulfillsMe(TSubgoal goal) override;
  269. };
  270. class DLL_EXPORT GatherArmy : public CGoal<GatherArmy>
  271. {
  272. public:
  273. GatherArmy()
  274. : CGoal(Goals::GATHER_ARMY)
  275. {
  276. }
  277. GatherArmy(int val)
  278. : CGoal(Goals::GATHER_ARMY)
  279. {
  280. value = val;
  281. priority = 2.5;
  282. }
  283. TGoalVec getAllPossibleSubgoals() override;
  284. TSubgoal whatToDoToAchieve() override;
  285. std::string completeMessage() const override;
  286. };
  287. class DLL_EXPORT BuyArmy : public CGoal<BuyArmy>
  288. {
  289. private:
  290. BuyArmy()
  291. : CGoal(Goals::BUY_ARMY)
  292. {}
  293. public:
  294. BuyArmy(const CGTownInstance * Town, int val)
  295. : CGoal(Goals::BUY_ARMY)
  296. {
  297. town = Town; //where to buy this army
  298. value = val; //expressed in AI unit strength
  299. priority = 3;//TODO: evaluate?
  300. }
  301. bool operator==(AbstractGoal & g) override;
  302. bool fulfillsMe(TSubgoal goal) override;
  303. TSubgoal whatToDoToAchieve() override;
  304. std::string completeMessage() const override;
  305. };
  306. class DLL_EXPORT BoostHero : public CGoal<BoostHero>
  307. {
  308. public:
  309. BoostHero()
  310. : CGoal(Goals::INVALID)
  311. {
  312. priority = -1e10; //TODO
  313. }
  314. TGoalVec getAllPossibleSubgoals() override
  315. {
  316. return TGoalVec();
  317. }
  318. //TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
  319. };
  320. class DLL_EXPORT RecruitHero : public CGoal<RecruitHero>
  321. {
  322. public:
  323. RecruitHero()
  324. : CGoal(Goals::RECRUIT_HERO)
  325. {
  326. priority = 1;
  327. }
  328. TGoalVec getAllPossibleSubgoals() override
  329. {
  330. return TGoalVec();
  331. }
  332. TSubgoal whatToDoToAchieve() override;
  333. bool operator==(AbstractGoal & g) override;
  334. };
  335. class DLL_EXPORT BuildThis : public CGoal<BuildThis>
  336. {
  337. public:
  338. BuildThis() //should be private, but unit test uses it
  339. : CGoal(Goals::BUILD_STRUCTURE)
  340. {}
  341. BuildThis(BuildingID Bid, const CGTownInstance * tid)
  342. : CGoal(Goals::BUILD_STRUCTURE)
  343. {
  344. bid = Bid;
  345. town = tid;
  346. priority = 1;
  347. }
  348. BuildThis(BuildingID Bid)
  349. : CGoal(Goals::BUILD_STRUCTURE)
  350. {
  351. bid = Bid;
  352. priority = 1;
  353. }
  354. TGoalVec getAllPossibleSubgoals() override
  355. {
  356. return TGoalVec();
  357. }
  358. TSubgoal whatToDoToAchieve() override;
  359. //bool fulfillsMe(TSubgoal goal) override;
  360. };
  361. class DLL_EXPORT CollectRes : public CGoal<CollectRes>
  362. {
  363. public:
  364. CollectRes()
  365. : CGoal(Goals::COLLECT_RES)
  366. {
  367. }
  368. CollectRes(int rid, int val)
  369. : CGoal(Goals::COLLECT_RES)
  370. {
  371. resID = rid;
  372. value = val;
  373. priority = 2;
  374. }
  375. TGoalVec getAllPossibleSubgoals() override;
  376. TSubgoal whatToDoToAchieve() override;
  377. TSubgoal whatToDoToTrade();
  378. bool fulfillsMe(TSubgoal goal) override; //TODO: Trade
  379. bool operator==(AbstractGoal & g) override;
  380. };
  381. class DLL_EXPORT Trade : public CGoal<Trade>
  382. {
  383. public:
  384. Trade()
  385. : CGoal(Goals::TRADE)
  386. {
  387. }
  388. Trade(int rid, int val, int Objid)
  389. : CGoal(Goals::TRADE)
  390. {
  391. resID = rid;
  392. value = val;
  393. objid = Objid;
  394. priority = 10; //do it immediately
  395. }
  396. TSubgoal whatToDoToAchieve() override;
  397. bool operator==(AbstractGoal & g) override;
  398. };
  399. class DLL_EXPORT GatherTroops : public CGoal<GatherTroops>
  400. {
  401. public:
  402. GatherTroops()
  403. : CGoal(Goals::GATHER_TROOPS)
  404. {
  405. priority = 2;
  406. }
  407. GatherTroops(int type, int val)
  408. : CGoal(Goals::GATHER_TROOPS)
  409. {
  410. objid = type;
  411. value = val;
  412. priority = 2;
  413. }
  414. TGoalVec getAllPossibleSubgoals() override
  415. {
  416. return TGoalVec();
  417. }
  418. TSubgoal whatToDoToAchieve() override;
  419. bool fulfillsMe(TSubgoal goal) override;
  420. };
  421. class DLL_EXPORT VisitObj : public CGoal<VisitObj> //this goal was previously known as GetObj
  422. {
  423. public:
  424. VisitObj() = delete; // empty constructor not allowed
  425. VisitObj(int Objid);
  426. TGoalVec getAllPossibleSubgoals() override;
  427. TSubgoal whatToDoToAchieve() override;
  428. bool operator==(AbstractGoal & g) override;
  429. bool fulfillsMe(TSubgoal goal) override;
  430. std::string completeMessage() const override;
  431. };
  432. class DLL_EXPORT FindObj : public CGoal<FindObj>
  433. {
  434. public:
  435. FindObj() {} // empty constructor not allowed
  436. FindObj(int ID)
  437. : CGoal(Goals::FIND_OBJ)
  438. {
  439. objid = ID;
  440. resID = -1; //subid unspecified
  441. priority = 1;
  442. }
  443. FindObj(int ID, int subID)
  444. : CGoal(Goals::FIND_OBJ)
  445. {
  446. objid = ID;
  447. resID = subID;
  448. priority = 1;
  449. }
  450. TGoalVec getAllPossibleSubgoals() override
  451. {
  452. return TGoalVec();
  453. }
  454. TSubgoal whatToDoToAchieve() override;
  455. bool fulfillsMe(TSubgoal goal) override;
  456. };
  457. class DLL_EXPORT VisitHero : public CGoal<VisitHero>
  458. {
  459. public:
  460. VisitHero()
  461. : CGoal(Goals::VISIT_HERO)
  462. {
  463. }
  464. VisitHero(int hid)
  465. : CGoal(Goals::VISIT_HERO)
  466. {
  467. objid = hid;
  468. priority = 4;
  469. }
  470. TGoalVec getAllPossibleSubgoals() override
  471. {
  472. return TGoalVec();
  473. }
  474. TSubgoal whatToDoToAchieve() override;
  475. bool operator==(AbstractGoal & g) override;
  476. bool fulfillsMe(TSubgoal goal) override;
  477. std::string completeMessage() const override;
  478. };
  479. class DLL_EXPORT GetArtOfType : public CGoal<GetArtOfType>
  480. {
  481. public:
  482. GetArtOfType()
  483. : CGoal(Goals::GET_ART_TYPE)
  484. {
  485. }
  486. GetArtOfType(int type)
  487. : CGoal(Goals::GET_ART_TYPE)
  488. {
  489. aid = type;
  490. priority = 2;
  491. }
  492. TGoalVec getAllPossibleSubgoals() override
  493. {
  494. return TGoalVec();
  495. }
  496. TSubgoal whatToDoToAchieve() override;
  497. };
  498. class DLL_EXPORT VisitTile : public CGoal<VisitTile>
  499. //tile, in conjunction with hero elementar; assumes tile is reachable
  500. {
  501. public:
  502. VisitTile() {} // empty constructor not allowed
  503. VisitTile(int3 Tile)
  504. : CGoal(Goals::VISIT_TILE)
  505. {
  506. tile = Tile;
  507. priority = 5;
  508. }
  509. TGoalVec getAllPossibleSubgoals() override;
  510. TSubgoal whatToDoToAchieve() override;
  511. bool operator==(AbstractGoal & g) override;
  512. std::string completeMessage() const override;
  513. };
  514. class DLL_EXPORT ClearWayTo : public CGoal<ClearWayTo>
  515. {
  516. public:
  517. ClearWayTo()
  518. : CGoal(Goals::CLEAR_WAY_TO)
  519. {
  520. }
  521. ClearWayTo(int3 Tile)
  522. : CGoal(Goals::CLEAR_WAY_TO)
  523. {
  524. tile = Tile;
  525. priority = 5;
  526. }
  527. ClearWayTo(int3 Tile, HeroPtr h)
  528. : CGoal(Goals::CLEAR_WAY_TO)
  529. {
  530. tile = Tile;
  531. hero = h;
  532. priority = 5;
  533. }
  534. TGoalVec getAllPossibleSubgoals() override;
  535. TSubgoal whatToDoToAchieve() override;
  536. bool operator==(AbstractGoal & g) override;
  537. bool fulfillsMe(TSubgoal goal) override;
  538. };
  539. class DLL_EXPORT DigAtTile : public CGoal<DigAtTile>
  540. //elementar with hero on tile
  541. {
  542. public:
  543. DigAtTile()
  544. : CGoal(Goals::DIG_AT_TILE)
  545. {
  546. }
  547. DigAtTile(int3 Tile)
  548. : CGoal(Goals::DIG_AT_TILE)
  549. {
  550. tile = Tile;
  551. priority = 20;
  552. }
  553. TGoalVec getAllPossibleSubgoals() override
  554. {
  555. return TGoalVec();
  556. }
  557. TSubgoal whatToDoToAchieve() override;
  558. bool operator==(AbstractGoal & g) override;
  559. };
  560. class DLL_EXPORT CIssueCommand : public CGoal<CIssueCommand>
  561. {
  562. std::function<bool()> command;
  563. public:
  564. CIssueCommand()
  565. : CGoal(ISSUE_COMMAND)
  566. {
  567. }
  568. CIssueCommand(std::function<bool()> _command)
  569. : CGoal(ISSUE_COMMAND), command(_command)
  570. {
  571. priority = 1e10;
  572. }
  573. TGoalVec getAllPossibleSubgoals() override
  574. {
  575. return TGoalVec();
  576. }
  577. //TSubgoal whatToDoToAchieve() override {return sptr(Invalid());}
  578. };
  579. }