Goals.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  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. //TODO: serialize?
  28. };
  29. typedef std::vector<TSubgoal> TGoalVec;
  30. enum EGoals
  31. {
  32. INVALID = -1,
  33. WIN, DO_NOT_LOSE, CONQUER, BUILD, //build needs to get a real reasoning
  34. EXPLORE, GATHER_ARMY,
  35. BOOST_HERO,
  36. RECRUIT_HERO,
  37. BUILD_STRUCTURE, //if hero set, then in visited town
  38. COLLECT_RES,
  39. GATHER_TROOPS, // val of creatures with objid
  40. OBJECT_GOALS_BEGIN,
  41. GET_OBJ, //visit or defeat or collect the object
  42. FIND_OBJ, //find and visit any obj with objid + resid //TODO: consider universal subid for various types (aid, bid)
  43. VISIT_HERO, //heroes can move around - set goal abstract and track hero every turn
  44. GET_ART_TYPE,
  45. //BUILD_STRUCTURE,
  46. ISSUE_COMMAND,
  47. VISIT_TILE, //tile, in conjunction with hero elementar; assumes tile is reachable
  48. CLEAR_WAY_TO,
  49. DIG_AT_TILE,//elementar with hero on tile
  50. BUY_ARMY //at specific town
  51. };
  52. //method chaining + clone pattern
  53. #define VSETTER(type, field) virtual AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
  54. #define OSETTER(type, field) CGoal<T> & set ## field(const type &rhs) override { field = rhs; return *this; };
  55. #if 0
  56. #define SETTER
  57. #endif // _DEBUG
  58. enum {LOW_PR = -1};
  59. DLL_EXPORT TSubgoal sptr(const AbstractGoal & tmp);
  60. class DLL_EXPORT AbstractGoal
  61. {
  62. public:
  63. bool isElementar; VSETTER(bool, isElementar)
  64. bool isAbstract; VSETTER(bool, isAbstract)
  65. float priority; VSETTER(float, priority)
  66. int value; VSETTER(int, value)
  67. int resID; VSETTER(int, resID)
  68. int objid; VSETTER(int, objid)
  69. int aid; VSETTER(int, aid)
  70. int3 tile; VSETTER(int3, tile)
  71. HeroPtr hero; VSETTER(HeroPtr, hero)
  72. const CGTownInstance *town; VSETTER(CGTownInstance *, town)
  73. int bid; VSETTER(int, bid)
  74. AbstractGoal(EGoals goal = INVALID)
  75. : goalType (goal)
  76. {
  77. priority = 0;
  78. isElementar = false;
  79. isAbstract = false;
  80. value = 0;
  81. aid = -1;
  82. resID = -1;
  83. objid = -1;
  84. tile = int3(-1, -1, -1);
  85. town = nullptr;
  86. bid = -1;
  87. }
  88. virtual ~AbstractGoal(){}
  89. //FIXME: abstract goal should be abstract, but serializer fails to instantiate subgoals in such case
  90. virtual AbstractGoal * clone() const
  91. {
  92. return const_cast<AbstractGoal *>(this);
  93. }
  94. virtual TGoalVec getAllPossibleSubgoals()
  95. {
  96. return TGoalVec();
  97. }
  98. virtual TSubgoal whatToDoToAchieve()
  99. {
  100. return sptr(AbstractGoal());
  101. }
  102. EGoals goalType;
  103. std::string name() const;
  104. virtual std::string completeMessage() const
  105. {
  106. return "This goal is unspecified!";
  107. }
  108. bool invalid() const;
  109. static TSubgoal goVisitOrLookFor(const CGObjectInstance * obj); //if obj is nullptr, then we'll explore
  110. static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
  111. static TSubgoal tryRecruitHero();
  112. ///Visitor pattern
  113. //TODO: make accept work for std::shared_ptr... somehow
  114. virtual void accept(VCAI * ai); //unhandled goal will report standard error
  115. virtual float accept(FuzzyHelper * f);
  116. virtual bool operator==(AbstractGoal & g);
  117. virtual bool fulfillsMe(Goals::TSubgoal goal) //TODO: multimethod instead of type check
  118. {
  119. return false; //use this method to check if goal is fulfilled by another (not equal) goal, operator == is handled spearately
  120. }
  121. template<typename Handler> void serialize(Handler & h, const int version)
  122. {
  123. h & goalType;
  124. h & isElementar;
  125. h & isAbstract;
  126. h & priority;
  127. h & value;
  128. h & resID;
  129. h & objid;
  130. h & aid;
  131. h & tile;
  132. h & hero;
  133. h & town;
  134. h & bid;
  135. }
  136. };
  137. template<typename T> class DLL_EXPORT CGoal : public AbstractGoal
  138. {
  139. public:
  140. CGoal<T>(EGoals goal = INVALID) : AbstractGoal(goal)
  141. {
  142. priority = 0;
  143. isElementar = false;
  144. isAbstract = false;
  145. value = 0;
  146. aid = -1;
  147. objid = -1;
  148. resID = -1;
  149. tile = int3(-1, -1, -1);
  150. town = nullptr;
  151. }
  152. OSETTER(bool, isElementar)
  153. OSETTER(bool, isAbstract)
  154. OSETTER(float, priority)
  155. OSETTER(int, value)
  156. OSETTER(int, resID)
  157. OSETTER(int, objid)
  158. OSETTER(int, aid)
  159. OSETTER(int3, tile)
  160. OSETTER(HeroPtr, hero)
  161. OSETTER(CGTownInstance *, town)
  162. OSETTER(int, bid)
  163. void accept(VCAI * ai) override;
  164. float accept(FuzzyHelper * f) override;
  165. CGoal<T> * clone() const override
  166. {
  167. return new T(static_cast<T const &>(*this)); //casting enforces template instantiation
  168. }
  169. TSubgoal iAmElementar()
  170. {
  171. setisElementar(true); //FIXME: it's not const-correct, maybe we shoudl only set returned clone?
  172. TSubgoal ptr;
  173. ptr.reset(clone());
  174. return ptr;
  175. }
  176. template<typename Handler> void serialize(Handler & h, const int version)
  177. {
  178. h & static_cast<AbstractGoal &>(*this);
  179. //h & goalType & isElementar & isAbstract & priority;
  180. //h & value & resID & objid & aid & tile & hero & town & bid;
  181. }
  182. };
  183. class DLL_EXPORT Invalid : public CGoal<Invalid>
  184. {
  185. public:
  186. Invalid()
  187. : CGoal(Goals::INVALID)
  188. {
  189. priority = -1e10;
  190. }
  191. TGoalVec getAllPossibleSubgoals() override
  192. {
  193. return TGoalVec();
  194. }
  195. TSubgoal whatToDoToAchieve() override;
  196. };
  197. class DLL_EXPORT Win : public CGoal<Win>
  198. {
  199. public:
  200. Win()
  201. : CGoal(Goals::WIN)
  202. {
  203. priority = 100;
  204. }
  205. TGoalVec getAllPossibleSubgoals() override
  206. {
  207. return TGoalVec();
  208. }
  209. TSubgoal whatToDoToAchieve() override;
  210. };
  211. class DLL_EXPORT NotLose : public CGoal<NotLose>
  212. {
  213. public:
  214. NotLose()
  215. : CGoal(Goals::DO_NOT_LOSE)
  216. {
  217. priority = 100;
  218. }
  219. TGoalVec getAllPossibleSubgoals() override
  220. {
  221. return TGoalVec();
  222. }
  223. //TSubgoal whatToDoToAchieve() override;
  224. };
  225. class DLL_EXPORT Conquer : public CGoal<Conquer>
  226. {
  227. public:
  228. Conquer()
  229. : CGoal(Goals::CONQUER)
  230. {
  231. priority = 10;
  232. }
  233. TGoalVec getAllPossibleSubgoals() override;
  234. TSubgoal whatToDoToAchieve() override;
  235. };
  236. class DLL_EXPORT Build : public CGoal<Build>
  237. {
  238. public:
  239. Build()
  240. : CGoal(Goals::BUILD)
  241. {
  242. priority = 1;
  243. }
  244. TGoalVec getAllPossibleSubgoals() override
  245. {
  246. return TGoalVec();
  247. }
  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 = 2;//TODO: evaluate?
  300. }
  301. bool operator==(BuyArmy & g);
  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==(RecruitHero & g);
  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;
  379. bool operator==(CollectRes & g);
  380. };
  381. class DLL_EXPORT GatherTroops : public CGoal<GatherTroops>
  382. {
  383. public:
  384. GatherTroops()
  385. : CGoal(Goals::GATHER_TROOPS)
  386. {
  387. priority = 2;
  388. }
  389. GatherTroops(int type, int val)
  390. : CGoal(Goals::GATHER_TROOPS)
  391. {
  392. objid = type;
  393. value = val;
  394. priority = 2;
  395. }
  396. TGoalVec getAllPossibleSubgoals() override
  397. {
  398. return TGoalVec();
  399. }
  400. TSubgoal whatToDoToAchieve() override;
  401. bool fulfillsMe(TSubgoal goal) override;
  402. };
  403. class DLL_EXPORT GetObj : public CGoal<GetObj>
  404. {
  405. public:
  406. GetObj() {} // empty constructor not allowed
  407. GetObj(int Objid)
  408. : CGoal(Goals::GET_OBJ)
  409. {
  410. objid = Objid;
  411. priority = 3;
  412. }
  413. TGoalVec getAllPossibleSubgoals() override
  414. {
  415. return TGoalVec();
  416. }
  417. TSubgoal whatToDoToAchieve() override;
  418. bool operator==(GetObj & g)
  419. {
  420. return g.objid == objid;
  421. }
  422. bool fulfillsMe(TSubgoal goal) override;
  423. std::string completeMessage() const override;
  424. };
  425. class DLL_EXPORT FindObj : public CGoal<FindObj>
  426. {
  427. public:
  428. FindObj() {} // empty constructor not allowed
  429. FindObj(int ID)
  430. : CGoal(Goals::FIND_OBJ)
  431. {
  432. objid = ID;
  433. resID = -1; //subid unspecified
  434. priority = 1;
  435. }
  436. FindObj(int ID, int subID)
  437. : CGoal(Goals::FIND_OBJ)
  438. {
  439. objid = ID;
  440. resID = subID;
  441. priority = 1;
  442. }
  443. TGoalVec getAllPossibleSubgoals() override
  444. {
  445. return TGoalVec();
  446. }
  447. TSubgoal whatToDoToAchieve() override;
  448. bool fulfillsMe(TSubgoal goal) override;
  449. };
  450. class DLL_EXPORT VisitHero : public CGoal<VisitHero>
  451. {
  452. public:
  453. VisitHero()
  454. : CGoal(Goals::VISIT_HERO)
  455. {
  456. }
  457. VisitHero(int hid)
  458. : CGoal(Goals::VISIT_HERO)
  459. {
  460. objid = hid;
  461. priority = 4;
  462. }
  463. TGoalVec getAllPossibleSubgoals() override
  464. {
  465. return TGoalVec();
  466. }
  467. TSubgoal whatToDoToAchieve() override;
  468. bool operator==(VisitHero & g)
  469. {
  470. return g.goalType == goalType && g.objid == objid;
  471. }
  472. bool fulfillsMe(TSubgoal goal) override;
  473. std::string completeMessage() const override;
  474. };
  475. class DLL_EXPORT GetArtOfType : public CGoal<GetArtOfType>
  476. {
  477. public:
  478. GetArtOfType()
  479. : CGoal(Goals::GET_ART_TYPE)
  480. {
  481. }
  482. GetArtOfType(int type)
  483. : CGoal(Goals::GET_ART_TYPE)
  484. {
  485. aid = type;
  486. priority = 2;
  487. }
  488. TGoalVec getAllPossibleSubgoals() override
  489. {
  490. return TGoalVec();
  491. }
  492. TSubgoal whatToDoToAchieve() override;
  493. };
  494. class DLL_EXPORT VisitTile : public CGoal<VisitTile>
  495. //tile, in conjunction with hero elementar; assumes tile is reachable
  496. {
  497. public:
  498. VisitTile() {} // empty constructor not allowed
  499. VisitTile(int3 Tile)
  500. : CGoal(Goals::VISIT_TILE)
  501. {
  502. tile = Tile;
  503. priority = 5;
  504. }
  505. TGoalVec getAllPossibleSubgoals() override;
  506. TSubgoal whatToDoToAchieve() override;
  507. bool operator==(VisitTile & g)
  508. {
  509. return g.goalType == goalType && g.tile == tile;
  510. }
  511. std::string completeMessage() const override;
  512. };
  513. class DLL_EXPORT ClearWayTo : public CGoal<ClearWayTo>
  514. {
  515. public:
  516. ClearWayTo()
  517. : CGoal(Goals::CLEAR_WAY_TO)
  518. {
  519. }
  520. ClearWayTo(int3 Tile)
  521. : CGoal(Goals::CLEAR_WAY_TO)
  522. {
  523. tile = Tile;
  524. priority = 5;
  525. }
  526. ClearWayTo(int3 Tile, HeroPtr h)
  527. : CGoal(Goals::CLEAR_WAY_TO)
  528. {
  529. tile = Tile;
  530. hero = h;
  531. priority = 5;
  532. }
  533. TGoalVec getAllPossibleSubgoals() override;
  534. TSubgoal whatToDoToAchieve() override;
  535. bool operator==(ClearWayTo & g)
  536. {
  537. return g.goalType == goalType && g.tile == tile;
  538. }
  539. bool fulfillsMe(TSubgoal goal) override;
  540. };
  541. class DLL_EXPORT DigAtTile : public CGoal<DigAtTile>
  542. //elementar with hero on tile
  543. {
  544. public:
  545. DigAtTile()
  546. : CGoal(Goals::DIG_AT_TILE)
  547. {
  548. }
  549. DigAtTile(int3 Tile)
  550. : CGoal(Goals::DIG_AT_TILE)
  551. {
  552. tile = Tile;
  553. priority = 20;
  554. }
  555. TGoalVec getAllPossibleSubgoals() override
  556. {
  557. return TGoalVec();
  558. }
  559. TSubgoal whatToDoToAchieve() override;
  560. bool operator==(DigAtTile & g)
  561. {
  562. return g.goalType == goalType && g.tile == tile;
  563. }
  564. };
  565. class DLL_EXPORT CIssueCommand : public CGoal<CIssueCommand>
  566. {
  567. std::function<bool()> command;
  568. public:
  569. CIssueCommand()
  570. : CGoal(ISSUE_COMMAND)
  571. {
  572. }
  573. CIssueCommand(std::function<bool()> _command)
  574. : CGoal(ISSUE_COMMAND), command(_command)
  575. {
  576. priority = 1e10;
  577. }
  578. TGoalVec getAllPossibleSubgoals() override
  579. {
  580. return TGoalVec();
  581. }
  582. //TSubgoal whatToDoToAchieve() override {return sptr(Invalid());}
  583. };
  584. }