Goals.h 16 KB

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