Goals.h 12 KB

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