Finished revision harvester behaviour. Added Some metrics for every loop.

This commit is contained in:
douwe
2025-08-21 23:35:00 +02:00
parent 1ede4cce47
commit 0c8da1d472
5 changed files with 126 additions and 99 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -10,18 +10,21 @@ namespace DouwcoHivemind
class HarvesterRole : public Creep
{
public:
HarvesterRole(Screeps::Creep crp) : Creep(crp){}
~HarvesterRole(){}
HarvesterRole(Screeps::Creep crp) : Creep(crp) {}
~HarvesterRole() {}
void loop() override;
private:
void harvestSource();
std::unique_ptr<Screeps::Source> getSourceTarget();
void searchTarget();
void searchEnergyDeposit();
void searchSource();
void depositEnergy();
std::unique_ptr<Screeps::Structure> getDepositTarget();
void searchDeposit();
std::unique_ptr<Screeps::RoomObject> getRoomObjectTarget();
};
}

View File

@@ -26,9 +26,23 @@ void DouwcoHivemind::HarvesterRole::loop()
memory["harvesting"] = false;
if (memory["harvesting"])
{
if (creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0)
{
memory["harvesting"] = false;
memory["target"].clear();
}
harvestSource();
}
else
{
if (creep.store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0)
{
memory["harvesting"] = true;
memory["target"].clear();
}
depositEnergy();
}
}
void DouwcoHivemind::HarvesterRole::harvestSource()
@@ -39,42 +53,22 @@ void DouwcoHivemind::HarvesterRole::harvestSource()
if (isNearTo(creep.pos(), source->pos()))
{
int resp = creep.harvest(*source);
// switch (resp)
// {
// case Screeps::ERR_NOT_IN_RANGE:
// /* code */
// break;
// default:
// break;
// }
}
else
creep.moveTo(*source);
}
std::unique_ptr<Screeps::Source> DouwcoHivemind::HarvesterRole::getSourceTarget()
{
// Check if target is still valid
if (!memory.contains("target") || memory["target"].empty())
auto roomObj = getRoomObjectTarget();
if (!roomObj)
{
searchSource();
return nullptr;
}
// Check if game can find target
auto sourceObj = Screeps::Game.getObjectById(memory["target"]);
if (!sourceObj)
{
JS::console.log(creep.name() + ": Game can\'t find target id");
// EM_ASM({console.log($0 + ': Game can\'t find target id')}, creep.name().c_str());
searchSource();
return nullptr;
}
// Check if found roomobject is an actual source
auto source = std::unique_ptr<Screeps::Source>(dynamic_cast<Screeps::Source *>(sourceObj.release()));
auto source = std::unique_ptr<Screeps::Source>(dynamic_cast<Screeps::Source *>(roomObj.release()));
if (!source)
{
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')}, creep.name().c_str());
@@ -126,98 +120,124 @@ void DouwcoHivemind::HarvesterRole::searchSource()
void DouwcoHivemind::HarvesterRole::depositEnergy()
{
if (!memory.contains("target") || memory["target"].empty())
{
searchEnergyDeposit();
if (!memory.contains("target") || memory["target"].empty())
return;
}
auto structure = getDepositTarget();
if (!structure)
return;
auto structureObj = Screeps::Game.getObjectById(memory["target"]);
if (structureObj)
if (isNearTo(creep.pos(), structure->pos()))
{
auto structure = dynamic_cast<Screeps::Structure *>(structureObj.get());
bool searchAgain = !structure;
if (!searchAgain)
int resp;
if (structure->structureType() == Screeps::STRUCTURE_CONTROLLER)
{
if (isNearTo(creep.pos(), structure->pos()))
{
if (structure->structureType() == Screeps::STRUCTURE_CONTROLLER)
{
Screeps::StructureController *controller = dynamic_cast<Screeps::StructureController *>(structure);
if (!controller)
return;
int resp = creep.upgradeController(*controller);
if (resp != Screeps::OK)
searchAgain = true;
}
else if (structure->structureType() == Screeps::STRUCTURE_SPAWN ||
structure->structureType() == Screeps::STRUCTURE_EXTENSION ||
structure->structureType() == Screeps::STRUCTURE_TOWER)
{
int resp = creep.transfer(*structure, Screeps::RESOURCE_ENERGY);
if (resp != Screeps::OK)
searchAgain = true;
}
}
else
creep.moveTo(*structure);
}
if (searchAgain)
{
searchEnergyDeposit();
auto controller = dynamic_cast<Screeps::StructureController *>(structure.get());
if (!controller)
return;
resp = creep.upgradeController(*controller);
}
else
resp = creep.transfer(*structure, Screeps::RESOURCE_ENERGY);
}
else
creep.moveTo(*structure);
}
void DouwcoHivemind::HarvesterRole::searchTarget()
std::unique_ptr<Screeps::Structure> DouwcoHivemind::HarvesterRole::getDepositTarget()
{
if (memory["harvesting"] && creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0)
auto roomObj = getRoomObjectTarget();
if (!roomObj)
{
memory["harvesting"] = false;
searchEnergyDeposit();
searchDeposit();
return nullptr;
}
else if (!memory["harvesting"] && creep.store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0)
// Check if found roomobject is an actual structure
auto structure = std::unique_ptr<Screeps::Structure>(dynamic_cast<Screeps::Structure *>(roomObj.release()));
if (!structure)
{
memory["harvesting"] = true;
searchSource();
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')}, creep.name().c_str());
searchDeposit();
return nullptr;
}
// Check if the structure can receive energy to harvest
int energyCapacity;
auto structureType = structure->structureType();
if (structureType == Screeps::STRUCTURE_SPAWN)
{
auto spawn = dynamic_cast<Screeps::StructureSpawn *>(structure.get());
energyCapacity = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
}
else if (structureType == Screeps::STRUCTURE_EXTENSION)
{
auto extension = dynamic_cast<Screeps::StructureExtension *>(structure.get());
energyCapacity = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
}
if (energyCapacity == 0)
{
searchDeposit();
return nullptr;
}
return std::move(structure);
}
void DouwcoHivemind::HarvesterRole::searchEnergyDeposit()
void DouwcoHivemind::HarvesterRole::searchDeposit()
{
int highestEnergyNeed = 0;
Screeps::Structure *selectedStructure;
auto structures = creep.room().find(Screeps::FIND_MY_STRUCTURES);
std::vector<std::unique_ptr<Screeps::RoomObject>> filtered;
for (auto &structureObject : structures)
{
auto structure = dynamic_cast<Screeps::Structure *>(structureObject.get());
if (!structure)
continue;
if (structure->structureType() == Screeps::STRUCTURE_SPAWN &&
dynamic_cast<Screeps::StructureSpawn *>(structure)->store().getFreeCapacity(Screeps::RESOURCE_ENERGY) > 0)
filtered.emplace_back(std::move(structureObject));
else if (structure->structureType() == Screeps::STRUCTURE_EXTENSION &&
dynamic_cast<Screeps::StructureSpawn *>(structure)->store().getFreeCapacity(Screeps::RESOURCE_ENERGY) > 0)
filtered.emplace_back(std::move(structureObject));
else if (structure->structureType() == Screeps::STRUCTURE_TOWER &&
dynamic_cast<Screeps::StructureSpawn *>(structure)->store().getFreeCapacity(Screeps::RESOURCE_ENERGY) > 0)
filtered.emplace_back(std::move(structureObject));
else if (structure->structureType() == Screeps::STRUCTURE_CONTROLLER)
filtered.emplace_back(std::move(structureObject));
}
int energyNeed;
auto closestObj = creep.pos().findClosestByPath(filtered);
if (closestObj)
{
auto closest = dynamic_cast<Screeps::Structure *>(closestObj.get());
if (closest)
auto structureType = structure->structureType();
if (structureType == Screeps::STRUCTURE_SPAWN)
{
memory["target"] = closest->id();
return;
auto spawn = dynamic_cast<Screeps::StructureSpawn *>(structure);
energyNeed = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
}
else if (structureType == Screeps::STRUCTURE_EXTENSION)
{
auto extension = dynamic_cast<Screeps::StructureExtension *>(structure);
energyNeed = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
}
else if (structureType == Screeps::STRUCTURE_CONTROLLER)
{
energyNeed = 1;
}
if (energyNeed > highestEnergyNeed)
{
highestEnergyNeed = energyNeed;
selectedStructure = structure;
}
}
memory["target"].clear();
if(selectedStructure)
memory["target"] = selectedStructure->id();
else
memory["target"].clear();
}
std::unique_ptr<Screeps::RoomObject> DouwcoHivemind::HarvesterRole::getRoomObjectTarget()
{
// Check if target is still valid
if (!memory.contains("target") || memory["target"].empty())
return nullptr;
// Check if game can find target
auto roomObj = Screeps::Game.getObjectById(memory["target"]);
if (!roomObj)
{
JS::console.log(creep.name() + ": Game can\'t find target id");
return nullptr;
}
return std::move(roomObj);
}
bool isNearTo(const Screeps::RoomPosition &pos1, const Screeps::RoomPosition &pos2)

View File

@@ -14,18 +14,22 @@ EMSCRIPTEN_KEEPALIVE
extern "C" void loop()
{
Screeps::Context::update();
EM_ASM({console.log('Starting loop: ')});
// Structures
for (auto& spawn_entry : Screeps::Game.spawns())
{
for (auto &spawn_entry : Screeps::Game.spawns())
{
auto spawn = DouwcoHivemind::Spawn(&spawn_entry.second);
spawn.process();
}
JS::console.log(std::string("Processing tick:\t") + std::to_string(Screeps::Game.time()));
DouwcoHivemind::Engine engine;
engine.loop();
EM_ASM({console.log('\n\n\n')});
JS::console.log("Used CPU:\t" + std::to_string(Screeps::Game.cpuGetUsed()));
JS::console.log("Bucket:\t" + std::to_string(static_cast<int>(Screeps::Game.cpu()["bucket"])));
JS::console.log(std::string("\n\n\n"));
}
EMSCRIPTEN_BINDINGS(loop)