1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00
vcmi/AI/Nullkiller/Goals/AbstractGoal.h
Xilmi e374f24016 complete Building-costs as evaluation-context
Added building-cost including all resoruces as evaluation-context for more sophisticated building-selection and also as a countermeasure to softlocking a build-order by having no ways to obtain certain resources.
For example, if the AI would drop below 5 wood, while having no market-place and no wood-income it will avoid building any buildings that neither allow trading nor produce wood.
2024-07-19 15:25:24 +02:00

221 lines
4.6 KiB
C++

/*
* AbstractGoal.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../../../lib/VCMI_Lib.h"
#include "../../../lib/mapObjects/CGTownInstance.h"
#include "../../../lib/mapObjects/CGHeroInstance.h"
#include "../AIUtility.h"
namespace NKAI
{
struct HeroPtr;
class AIGateway;
class FuzzyHelper;
class Nullkiller;
namespace Goals
{
class AbstractGoal;
class ITask;
class RecruitHero;
class BuildThis;
class DigAtTile;
class CollectRes;
class BuyArmy;
class BuildBoat;
class Invalid;
class Trade;
class AdventureSpellCast;
enum EGoals
{
INVALID = -1,
WIN, CONQUER,
BUILD,
EXPLORE, GATHER_ARMY,
BOOST_HERO,
RECRUIT_HERO,
RECRUIT_HERO_BEHAVIOR,
BUILD_STRUCTURE, //if hero set, then in visited town
COLLECT_RES,
GATHER_TROOPS, // val of creatures with objid
CAPTURE_OBJECTS,
GET_ART_TYPE,
DEFENCE,
STARTUP,
DIG_AT_TILE,//elementar with hero on tile
BUY_ARMY, //at specific town
TRADE, //val resID at object objid
BUILD_BOAT,
COMPLETE_QUEST,
ADVENTURE_SPELL_CAST,
EXECUTE_HERO_CHAIN,
EXCHANGE_SWAP_TOWN_HEROES,
DISMISS_HERO,
COMPOSITION,
CLUSTER_BEHAVIOR,
UNLOCK_CLUSTER,
HERO_EXCHANGE,
ARMY_UPGRADE,
DEFEND_TOWN,
CAPTURE_OBJECT,
SAVE_RESOURCES,
STAY_AT_TOWN_BEHAVIOR,
STAY_AT_TOWN,
EXPLORATION_BEHAVIOR,
EXPLORATION_POINT,
EXPLORE_NEIGHBOUR_TILE
};
class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>
{
public:
bool operator==(const TSubgoal & rhs) const;
bool operator<(const TSubgoal & rhs) const;
};
using TTask = std::shared_ptr<ITask>;
using TTaskVec = std::vector<TTask>;
using TGoalVec = std::vector<TSubgoal>;
//method chaining + clone pattern
#define SETTER(type, field) AbstractGoal & set ## field(const type &rhs) {field = rhs; return *this;};
enum { LOW_PR = -1 };
DLL_EXPORT TSubgoal sptr(const AbstractGoal & tmp);
DLL_EXPORT TTask taskptr(const AbstractGoal & tmp);
class DLL_EXPORT AbstractGoal
{
public:
bool isAbstract; SETTER(bool, isAbstract)
int value; SETTER(int, value)
ui64 goldCost; SETTER(ui64, goldCost)
TResources buildingCost; SETTER(TResources, buildingCost)
int resID; SETTER(int, resID)
int objid; SETTER(int, objid)
int aid; SETTER(int, aid)
int3 tile; SETTER(int3, tile)
const CGHeroInstance * hero; SETTER(CGHeroInstance *, hero)
const CGTownInstance *town; SETTER(CGTownInstance *, town)
int bid; SETTER(int, bid)
AbstractGoal(EGoals goal = EGoals::INVALID): goalType(goal)
{
isAbstract = false;
value = 0;
aid = -1;
resID = -1;
objid = -1;
tile = int3(-1, -1, -1);
town = nullptr;
hero = nullptr;
bid = -1;
goldCost = 0;
}
virtual ~AbstractGoal() {}
//FIXME: abstract goal should be abstract, but serializer fails to instantiate subgoals in such case
virtual AbstractGoal * clone() const
{
return const_cast<AbstractGoal *>(this);
}
virtual TGoalVec decompose(const Nullkiller * ai) const
{
return TGoalVec();
}
EGoals goalType;
virtual std::string toString() const;
bool invalid() const;
virtual bool operator==(const AbstractGoal & g) const;
virtual bool isElementar() const { return false; }
virtual bool hasHash() const { return false; }
virtual uint64_t getHash() const { return 0; }
virtual ITask * asTask()
{
throw std::runtime_error("Abstract goal is not a task");
}
bool operator!=(const AbstractGoal & g) const
{
return !(*this == g);
}
};
class DLL_EXPORT ITask
{
public:
float priority;
ITask() : priority(0) {}
///Visitor pattern
//TODO: make accept work for std::shared_ptr... somehow
virtual void accept(AIGateway * ai) = 0; //unhandled goal will report standard error
virtual std::string toString() const = 0;
virtual const CGHeroInstance * getHero() const = 0;
virtual ~ITask() {}
virtual int getHeroExchangeCount() const = 0;
virtual bool isObjectAffected(ObjectInstanceID h) const = 0;
virtual std::vector<ObjectInstanceID> getAffectedObjects() const = 0;
};
}
class cannotFulfillGoalException : public std::exception
{
std::string msg;
public:
explicit cannotFulfillGoalException(const std::string & message)
: msg(message)
{
}
const char * what() const noexcept override
{
return msg.c_str();
}
};
class goalFulfilledException : public std::exception
{
std::string msg;
public:
Goals::TSubgoal goal;
explicit goalFulfilledException(Goals::TSubgoal Goal)
: goal(Goal)
{
msg = goal->toString();
}
const char * what() const noexcept override
{
return msg.c_str();
}
};
}