1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-16 10:19:47 +02:00
vcmi/AI/Nullkiller/Goals/CollectRes.cpp

195 lines
5.1 KiB
C++

/*
* CollectRes.cpp, 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
*
*/
#include "StdInc.h"
#include "Goals.h"
#include "../VCAI.h"
#include "../AIUtility.h"
#include "../AIhelper.h"
#include "../FuzzyHelper.h"
#include "../../../lib/mapping/CMap.h" //for victory conditions
#include "../../../lib/CPathfinder.h"
#include "../../../lib/StringConstants.h"
extern boost::thread_specific_ptr<CCallback> cb;
extern boost::thread_specific_ptr<VCAI> ai;
extern FuzzyHelper * fh;
using namespace Goals;
bool CollectRes::operator==(const CollectRes & other) const
{
return resID == other.resID;
}
//TGoalVec CollectRes::getAllPossibleSubgoals()
//{
// TGoalVec ret;
//
//auto givesResource = [this](const CGObjectInstance * obj) -> bool
//{
// //TODO: move this logic to object side
// //TODO: remember mithril exists
// //TODO: water objects
// //TODO: Creature banks
// //return false first from once-visitable, before checking if they were even visited
// switch (obj->ID.num)
// {
// case Obj::TREASURE_CHEST:
// return resID == Res::GOLD;
// break;
// case Obj::RESOURCE:
// return obj->subID == resID;
// break;
// case Obj::MINE:
// return (obj->subID == resID &&
// (cb->getPlayerRelations(obj->tempOwner, ai->playerID) == PlayerRelations::ENEMIES)); //don't capture our mines
// break;
// case Obj::CAMPFIRE:
// return true; //contains all resources
// break;
// case Obj::WINDMILL:
// switch (resID)
// {
// case Res::GOLD:
// case Res::WOOD:
// return false;
// }
// break;
// case Obj::WATER_WHEEL:
// if (resID != Res::GOLD)
// return false;
// break;
// case Obj::MYSTICAL_GARDEN:
// if ((resID != Res::GOLD) && (resID != Res::GEMS))
// return false;
// break;
// case Obj::LEAN_TO:
// case Obj::WAGON:
// if (resID != Res::GOLD)
// return false;
// break;
// default:
// return false;
// break;
// }
// return !vstd::contains(ai->alreadyVisited, obj); //for weekly / once visitable
//};
//std::vector<const CGObjectInstance *> objs;
//for (auto obj : ai->visitableObjs)
//{
// if (givesResource(obj))
// objs.push_back(obj);
//}
//for (auto h : cb->getHeroesInfo())
//{
// std::vector<const CGObjectInstance *> ourObjs(objs); //copy common objects
// for (auto obj : ai->reservedHeroesMap[h]) //add objects reserved by this hero
// {
// if (givesResource(obj))
// ourObjs.push_back(obj);
// }
// for (auto obj : ourObjs)
// {
// auto waysToGo = ai->ah->howToVisitObj(h, ObjectIdRef(obj));
// vstd::concatenate(ret, waysToGo);
// }
//}
// return ret;
//}
//TSubgoal CollectRes::whatToDoToAchieve()
//{
// auto goals = getAllPossibleSubgoals();
// auto trade = whatToDoToTrade();
// if (!trade->invalid())
// goals.push_back(trade);
//
// return sptr(Invalid()); //we can always do that
//}
TSubgoal CollectRes::whatToDoToTrade()
{
//std::vector<const IMarket *> markets;
//std::vector<const CGObjectInstance *> visObjs;
//ai->retrieveVisitableObjs(visObjs, true);
//for (const CGObjectInstance * obj : visObjs)
//{
// if (const IMarket * m = IMarket::castFrom(obj, false))
// {
// if (obj->ID == Obj::TOWN && obj->tempOwner == ai->playerID && m->allowsTrade(EMarketMode::RESOURCE_RESOURCE))
// markets.push_back(m);
// else if (obj->ID == Obj::TRADING_POST)
// markets.push_back(m);
// }
//}
//boost::sort(markets, [](const IMarket * m1, const IMarket * m2) -> bool
//{
// return m1->getMarketEfficiency() < m2->getMarketEfficiency();
//});
//markets.erase(boost::remove_if(markets, [](const IMarket * market) -> bool
//{
// if (!(market->o->ID == Obj::TOWN && market->o->tempOwner == ai->playerID))
// {
// if (!ai->isAccessible(market->o->visitablePos()))
// return true;
// }
// return false;
//}), markets.end());
//if (!markets.size())
//{
// for (const CGTownInstance * t : cb->getTownsInfo())
// {
// if (cb->canBuildStructure(t, BuildingID::MARKETPLACE) == EBuildingState::ALLOWED)
// return sptr(BuildThis(BuildingID::MARKETPLACE, t).setpriority(2));
// }
//}
//else
//{
// const IMarket * m = markets.back();
// //attempt trade at back (best prices)
// int howManyCanWeBuy = 0;
// for (Res::ERes i = Res::WOOD; i <= Res::GOLD; vstd::advance(i, 1))
// {
// if (i == resID)
// continue;
// int toGive = -1, toReceive = -1;
// m->getOffer(i, resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE);
// assert(toGive > 0 && toReceive > 0);
// howManyCanWeBuy += toReceive * (ai->ah->freeResources()[i] / toGive);
// }
// if (howManyCanWeBuy >= value)
// {
// auto backObj = cb->getTopObj(m->o->visitablePos()); //it'll be a hero if we have one there; otherwise marketplace
// assert(backObj);
// auto objid = m->o->id.getNum();
// if (backObj->tempOwner != ai->playerID) //top object not owned
// {
// return sptr(VisitObj(objid)); //just go there
// }
// else //either it's our town, or we have hero there
// {
// return sptr(Trade(resID, value, objid).setisElementar(true)); //we can do this immediately
// }
// }
//}
return sptr(Invalid()); //cannot trade
}