TSubgoal FindObj::whatToDoToAchieve() { const CGObjectInstance * o = nullptr; if (resID > -1) //specified { for(const CGObjectInstance *obj : ai->visitableObjs) { if(obj->ID == objid && obj->subID == resID) { o = obj; break; //TODO: consider multiple objects and choose best } } } else { for(const CGObjectInstance *obj : ai->visitableObjs) { if(obj->ID == objid) { o = obj; break; //TODO: consider multiple objects and choose best } } } if (o && ai->isAccessible(o->pos)) //we don't use isAccessibleForHero as we don't know which hero it is return sptr (Goals::GetObj(o->id.getNum())); else return sptr (Goals::Explore()); }
TSubgoal CollectRes::whatToDoToAchieve() { std::vector<const IMarket*> markets; std::vector<const CGObjectInstance*> visObjs; ai->retreiveVisitableObjs(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) //TODO a moze po prostu test na pozwalanie handlu? 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 { return !(market->o->ID == Obj::TOWN && market->o->tempOwner == ai->playerID) && !ai->isAccessible(market->o->visitablePos()); }),markets.end()); if(!markets.size()) { for(const CGTownInstance *t : cb->getTownsInfo()) { if(cb->canBuildStructure(t, BuildingID::MARKETPLACE) == EBuildingState::ALLOWED) return sptr (Goals::BuildThis(BuildingID::MARKETPLACE, t)); } } 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 * (cb->getResourceAmount(i) / toGive); } if(howManyCanWeBuy + cb->getResourceAmount(static_cast<Res::ERes>(resID)) >= value) { auto backObj = cb->getTopObj(m->o->visitablePos()); //it'll be a hero if we have one there; otherwise marketplace assert(backObj); if (backObj->tempOwner != ai->playerID) { return sptr (Goals::GetObj(m->o->id.getNum())); } else { return sptr (Goals::GetObj(m->o->id.getNum()).setisElementar(true)); } } } return sptr (setisElementar(true)); //all the conditions for trade are met }
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 }