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

View File

@@ -14,18 +14,22 @@ EMSCRIPTEN_KEEPALIVE
extern "C" void loop() extern "C" void loop()
{ {
Screeps::Context::update(); Screeps::Context::update();
EM_ASM({console.log('Starting loop: ')});
// Structures // Structures
for (auto& spawn_entry : Screeps::Game.spawns()) for (auto &spawn_entry : Screeps::Game.spawns())
{ {
auto spawn = DouwcoHivemind::Spawn(&spawn_entry.second); auto spawn = DouwcoHivemind::Spawn(&spawn_entry.second);
spawn.process(); spawn.process();
} }
JS::console.log(std::string("Processing tick:\t") + std::to_string(Screeps::Game.time()));
DouwcoHivemind::Engine engine; DouwcoHivemind::Engine engine;
engine.loop(); 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) EMSCRIPTEN_BINDINGS(loop)