mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-17 20:58:07 +02:00
NKAI: stability fixes and regression
This commit is contained in:
parent
ed76d8a652
commit
3939c4b9d3
@ -1111,7 +1111,24 @@ void AIGateway::recruitCreatures(const CGDwelling * d, const CArmedInstance * re
|
||||
|
||||
if(!recruiter->getSlotFor(creID).validSlot())
|
||||
{
|
||||
continue;
|
||||
for(auto stack : recruiter->Slots())
|
||||
{
|
||||
if(!stack.second->type)
|
||||
continue;
|
||||
|
||||
auto duplicatingSlot = recruiter->getSlotFor(stack.second->type);
|
||||
|
||||
if(duplicatingSlot != stack.first)
|
||||
{
|
||||
cb->mergeStacks(recruiter, recruiter, stack.first, duplicatingSlot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!recruiter->getSlotFor(creID).validSlot())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
vstd::amin(count, cb->getResourceAmount() / creID.toCreature()->getFullRecruitCost());
|
||||
|
@ -91,7 +91,7 @@ bool HeroPtr::operator<(const HeroPtr & rhs) const
|
||||
|
||||
const CGHeroInstance * HeroPtr::get(bool doWeExpectNull) const
|
||||
{
|
||||
return get(cb);
|
||||
return get(cb, doWeExpectNull);
|
||||
}
|
||||
|
||||
const CGHeroInstance * HeroPtr::get(const CPlayerSpecificInfoCallback * cb, bool doWeExpectNull) const
|
||||
@ -300,6 +300,19 @@ uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock>
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
|
||||
}
|
||||
|
||||
int getDuplicatingSlots(const CArmedInstance * army)
|
||||
{
|
||||
int duplicatingSlots = 0;
|
||||
|
||||
for(auto stack : army->Slots())
|
||||
{
|
||||
if(stack.second->type && army->getSlotFor(stack.second->type) != stack.first)
|
||||
duplicatingSlots++;
|
||||
}
|
||||
|
||||
return duplicatingSlots;
|
||||
}
|
||||
|
||||
// todo: move to obj manager
|
||||
bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObjectInstance * obj)
|
||||
{
|
||||
@ -347,13 +360,14 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
|
||||
return false;
|
||||
|
||||
const CGDwelling * d = dynamic_cast<const CGDwelling *>(obj);
|
||||
auto duplicatingSlotsCount = getDuplicatingSlots(h);
|
||||
|
||||
for(auto level : d->creatures)
|
||||
{
|
||||
for(auto c : level.second)
|
||||
{
|
||||
if(level.first
|
||||
&& h->getSlotFor(CreatureID(c)) != SlotID()
|
||||
&& (h->getSlotFor(CreatureID(c)) != SlotID() || duplicatingSlotsCount > 0)
|
||||
&& ai->cb->getResourceAmount().canAfford(c.toCreature()->getFullRecruitCost()))
|
||||
{
|
||||
return true;
|
||||
|
@ -242,6 +242,7 @@ uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock>
|
||||
|
||||
// todo: move to obj manager
|
||||
bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObjectInstance * obj);
|
||||
int getDuplicatingSlots(const CArmedInstance * army);
|
||||
|
||||
template <class T>
|
||||
class SharedPool
|
||||
|
@ -318,7 +318,7 @@ void Nullkiller::makeTurn()
|
||||
|
||||
Goals::TGoalVec bestTasks;
|
||||
|
||||
for(int i = 1; i <= settings->getMaxPass(); i++)
|
||||
for(int i = 1; i <= settings->getMaxPass() && cb->getPlayerStatus(playerID) == EPlayerStatus::INGAME; i++)
|
||||
{
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
updateAiState(i);
|
||||
@ -372,6 +372,9 @@ void Nullkiller::makeTurn()
|
||||
|
||||
for(auto bestTask : selectedTasks)
|
||||
{
|
||||
if(cb->getPlayerStatus(playerID) != EPlayerStatus::INGAME)
|
||||
return;
|
||||
|
||||
std::string taskDescription = bestTask->toString();
|
||||
HeroPtr hero = bestTask->getHero();
|
||||
HeroRole heroRole = HeroRole::MAIN;
|
||||
|
@ -158,6 +158,8 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
|
||||
|
||||
const auto& slots = hero->Slots();
|
||||
ui64 weakestStackPower = 0;
|
||||
int duplicatingSlots = getDuplicatingSlots(hero);
|
||||
|
||||
if (slots.size() >= GameConstants::ARMY_SIZE)
|
||||
{
|
||||
//No free slot, we might discard our weakest stack
|
||||
@ -172,7 +174,7 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero
|
||||
{
|
||||
//Only if hero has slot for this creature in the army
|
||||
auto ccre = dynamic_cast<const CCreature*>(c.data.type);
|
||||
if (hero->getSlotFor(ccre).validSlot())
|
||||
if (hero->getSlotFor(ccre).validSlot() || duplicatingSlots > 0)
|
||||
{
|
||||
result += (c.data.type->getAIValue() * c.data.count) * c.chance;
|
||||
}
|
||||
@ -1125,7 +1127,7 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task)
|
||||
}
|
||||
|
||||
#if NKAI_TRACE_LEVEL >= 2
|
||||
logAi->trace("Evaluated %s, loss: %f, turn: %d, turns main: %f, scout: %f, gold: %f, cost: %d, army gain: %d, danger: %d, role: %s, strategical value: %f, cwr: %f, fear: %f, result %f",
|
||||
logAi->trace("Evaluated %s, loss: %f, turn: %d, turns main: %f, scout: %f, gold: %f, cost: %d, army gain: %f, danger: %d, role: %s, strategical value: %f, cwr: %f, fear: %f, result %f",
|
||||
task->toString(),
|
||||
evaluationContext.armyLossPersentage,
|
||||
(int)evaluationContext.turn,
|
||||
|
@ -104,6 +104,13 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
||||
const CGHeroInstance * hero = node->targetHero;
|
||||
HeroPtr heroPtr = hero;
|
||||
|
||||
if(!heroPtr.validAndSet())
|
||||
{
|
||||
logAi->error("Hero %s was lost. Exit hero chain.", heroPtr.name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(node->parentIndex >= i)
|
||||
{
|
||||
logAi->error("Invalid parentIndex while executing node " + node->coord.toString());
|
||||
|
@ -375,6 +375,8 @@ int main(int argc, char * argv[])
|
||||
while(!headlessQuit)
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
|
||||
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
|
||||
|
||||
quitApplication();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user