From 591fd97be097bd6aacbfb2e7373efd7e45e28cfa Mon Sep 17 00:00:00 2001 From: Douwe Ravers Date: Sun, 12 Jul 2026 02:53:46 +0200 Subject: [PATCH] Changed behaviour of maintainer and fixed screep cleanup. --- douwco_hivemind/include/Entity/Room.hpp | 4 +- douwco_hivemind/src/Creeps/CreepBase.cpp | 8 +- douwco_hivemind/src/Creeps/Maintainer.cpp | 134 +++++++++++----------- douwco_hivemind/src/Engine.cpp | 50 ++++---- douwco_hivemind/src/Entity/Room.cpp | 48 +++++--- douwco_hivemind/src/Loop.cpp | 3 - 6 files changed, 127 insertions(+), 120 deletions(-) diff --git a/douwco_hivemind/include/Entity/Room.hpp b/douwco_hivemind/include/Entity/Room.hpp index fd800d5..53e07eb 100644 --- a/douwco_hivemind/include/Entity/Room.hpp +++ b/douwco_hivemind/include/Entity/Room.hpp @@ -14,7 +14,7 @@ public: std::vector sourceIds = {}; std::vector sourceContainerIds = {}; std::vector SpawnIds = {}; - std::vector screepNames = {}; + std::vector creepNames = {}; private: int minerIterator; @@ -33,6 +33,8 @@ protected: void updateSpawnIds(); void updateContainerIds(); + void cleanupManagedCreeps(); + std::map calculateRequiredJobs(); std::map countCurrentJobs(); std::string getNewCreepName(CreepRole role); diff --git a/douwco_hivemind/src/Creeps/CreepBase.cpp b/douwco_hivemind/src/Creeps/CreepBase.cpp index 9dd6f5b..e9e4ad4 100644 --- a/douwco_hivemind/src/Creeps/CreepBase.cpp +++ b/douwco_hivemind/src/Creeps/CreepBase.cpp @@ -25,6 +25,8 @@ DouwcoHivemind::CreepBase::~CreepBase() { memory["role"] = role; memory["targetId"] = targetId; creep.setMemory(memory); + if (!creep.spawning() && creep.ticksToLive() == 1) + JS::getGlobal("eval")("delete Memory.creeps['" + creep.name() + "']"); } void DouwcoHivemind::CreepBase::moveToTarget(int dist) { @@ -65,12 +67,6 @@ void DouwcoHivemind::CreepBase::moveToTarget(int dist) { memory["path"] = vectorToJson(flattenPathSteps(path)); } - // JS::console.log(std::string("creep pos: [") + - // std::to_string(creep.pos().x()) + - // std::string(",") + - // std::to_string(creep.pos().y()) + - // std::string("]")); - // Get step from memory int pathStepData[5] = {0}; if (memory["path"].size() > 5) { diff --git a/douwco_hivemind/src/Creeps/Maintainer.cpp b/douwco_hivemind/src/Creeps/Maintainer.cpp index a9919da..b070a85 100644 --- a/douwco_hivemind/src/Creeps/Maintainer.cpp +++ b/douwco_hivemind/src/Creeps/Maintainer.cpp @@ -1,91 +1,85 @@ -#include -#include #include +#include +#include -#include #include -#include +#include #include -#include #include +#include +#include +#include #include #include -#include #include +#include #include -#include -#include "Creeps/Maintainer.hpp" #include "Creeps/CreepBase.hpp" +#include "Creeps/Maintainer.hpp" #include "Screeps/Constants.hpp" -void DouwcoHivemind::Maintainer::depositEnergy() -{ - auto structure = getDamagedStructureTarget(); - if (!structure) return; - if (isNearTo(structure->pos(), 1)) - { - int resp = creep.repair(*structure); - } - else - { - moveToTarget(); - } +void DouwcoHivemind::Maintainer::depositEnergy() { + auto structure = getDamagedStructureTarget(); + if (!structure) + return; + if (isNearTo(structure->pos(), 1)) { + int resp = creep.repair(*structure); + } else { + moveToTarget(); + } } -std::unique_ptr DouwcoHivemind::Maintainer::getDamagedStructureTarget() -{ - auto roomObj = getRoomObjectTarget(); - if (!roomObj) - { - searchDamagedStructure(); - return nullptr; - } +std::unique_ptr +DouwcoHivemind::Maintainer::getDamagedStructureTarget() { + auto roomObj = getRoomObjectTarget(); + if (!roomObj) { + searchDamagedStructure(); + return nullptr; + } - auto structure = std::unique_ptr(dynamic_cast(roomObj.release())); + auto structure = std::unique_ptr( + dynamic_cast(roomObj.release())); + if (!structure) { + searchDamagedStructure(); + return nullptr; + } + + // Check if the structure is still broken + int damage = structure->hitsMax() - structure->hits(); + if (damage == 0) { + searchDamagedStructure(); + return nullptr; + } + + return std::move(structure); +} + +void DouwcoHivemind::Maintainer::searchDamagedStructure() { + int highestDamage = 0; + Screeps::Structure *selectedStructure; + auto structures = creep.room().find(Screeps::FIND_STRUCTURES); + for (auto &structureObject : structures) { + auto structure = + dynamic_cast(structureObject.release()); if (!structure) - { - searchDamagedStructure(); - return nullptr; - } + continue; - // Check if the structure is still broken - int damage = structure->hitsMax() - structure->hits(); - if (damage == 0) - { - searchDamagedStructure(); - return nullptr; + auto structureType = structure->structureType(); + if (structureType == Screeps::STRUCTURE_CONTROLLER) + continue; + int damage = + 100 * (structure->hitsMax() - structure->hits()) / structure->hitsMax(); + if (structureType == Screeps::STRUCTURE_WALL) continue; + if (highestDamage < damage) { + highestDamage = damage; + selectedStructure = structure; } + } - return std::move(structure); -} - -void DouwcoHivemind::Maintainer::searchDamagedStructure() -{ - int highestDamage = 0; - Screeps::Structure *selectedStructure; - auto structures = creep.room().find(Screeps::FIND_STRUCTURES); - for (auto &structureObject : structures) - { - auto structure = dynamic_cast(structureObject.release()); - if (!structure) - continue; - - int damage = structure->hitsMax() - structure->hits(); - auto structureType = structure->structureType(); - if (structureType == Screeps::STRUCTURE_CONTROLLER) - continue; - if(structureType == Screeps::STRUCTURE_WALL || structureType == Screeps::STRUCTURE_RAMPART) - continue; // todo cover this situation as well. - if (highestDamage < damage) - { - highestDamage = damage; - selectedStructure = structure; - } - } - - if (selectedStructure && selectedStructure->hits() != selectedStructure->hitsMax()) - targetId = selectedStructure->id(); - else - targetId.clear(); + if (selectedStructure && + selectedStructure->hits() != selectedStructure->hitsMax()) + targetId = selectedStructure->id(); + else + targetId.clear(); } diff --git a/douwco_hivemind/src/Engine.cpp b/douwco_hivemind/src/Engine.cpp index d848635..219ec32 100644 --- a/douwco_hivemind/src/Engine.cpp +++ b/douwco_hivemind/src/Engine.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "Engine.hpp" @@ -13,36 +14,43 @@ #include "Creeps/Upgrader.hpp" #include "Screeps/Constants.hpp" +#include "Screeps/JS.hpp" #include "Screeps/StructureSpawn.hpp" #include "Structures/Spawn.hpp" #include "Structures/Tower.hpp" DouwcoHivemind::Engine::Engine() { instance = this; - JS::console.log(std::string("Reading out owned rooms")); + // JS::console.log(std::string("Reading out owned rooms")); ReadOutRooms(); - JS::console.log(std::string("Reading out creeps")); + // JS::console.log(std::string("Reading out creeps")); ReadOutCreeps(); - JS::console.log(std::string("Reading out structures")); + // JS::console.log(std::string("Reading out structures")); ReadOutStructures(); } void DouwcoHivemind::Engine::loop() { - JS::console.log(std::string("Iterating over rooms")); + int totalCost = Screeps::Game.cpuGetUsed(); for (auto &room : Rooms) room.second->loop(); + JS::console.log("Used CPU by rooms:\t" + + std::to_string(Screeps::Game.cpuGetUsed() - totalCost)); + totalCost = Screeps::Game.cpuGetUsed(); - JS::console.log(std::string("Iterating over creeps")); for (auto &creep : Creeps) creep.second->loop(); + JS::console.log("Used CPU by creeps:\t" + + std::to_string(Screeps::Game.cpuGetUsed() - totalCost)); + totalCost = Screeps::Game.cpuGetUsed(); - JS::console.log(std::string("Iterating over structures")); for (auto &structure : Structures) structure.second->loop(); + JS::console.log("Used CPU by structures:\t" + + std::to_string(Screeps::Game.cpuGetUsed() - totalCost)); + totalCost = Screeps::Game.cpuGetUsed(); - if (Screeps::Game.time() % 100 == 0) { + if (Screeps::Game.time() % 1000 == 0) clearDeadCreepMemory(); - } } void DouwcoHivemind::Engine::ReadOutRooms() { @@ -90,24 +98,16 @@ void DouwcoHivemind::Engine::ReadOutStructures() { } void DouwcoHivemind::Engine::clearDeadCreepMemory() { - auto creepMemory = Screeps::Memory["creeps"]; - auto creepsMap = Screeps::Game.creeps(); - int iterator = 0; - for (auto [name, creep] : creepMemory.items()) { - // avoid cpu overload - iterator++; - if (iterator == 100) - break; - bool containsname = false; - for (auto creepObject : creepsMap) { - if (creepObject.first == name) { - containsname = true; - break; - } + auto creepMemory = JS::getGlobal("Memory")["creeps"]; + auto creepNames = JS::gObject.call("keys", creepMemory); + int size = creepNames["length"].as(); + + for (int i = 0; i < size; i++) { + auto name = creepNames[i].as(); + if (Engine::getInstance()->Creeps.find(name) == + Engine::getInstance()->Creeps.end()) { + JS::getGlobal("eval")("delete Memory.creeps['" + name + "']"); } - if (!containsname) - creepMemory.erase(name); } - Screeps::Memory.set("creeps", creepMemory); } diff --git a/douwco_hivemind/src/Entity/Room.cpp b/douwco_hivemind/src/Entity/Room.cpp index 223b59e..7f75b53 100644 --- a/douwco_hivemind/src/Entity/Room.cpp +++ b/douwco_hivemind/src/Entity/Room.cpp @@ -16,21 +16,29 @@ #include "Screeps/StructureSpawn.hpp" #include "Structures/Spawn.hpp" #include +#include +#include DouwcoHivemind::Room::Room(Screeps::Room rm) : roomJs(rm), memory(rm.memory()) { - if (memory.contains("sources")) - sourceIds = static_cast>(memory["sources"]); - if (memory.contains("sourceContainers")) + if (memory.contains("sourceIds")) + sourceIds = static_cast>(memory["sourceIds"]); + if (memory.contains("sourceContainerIds")) sourceContainerIds = - static_cast>(memory["sourceContainers"]); + static_cast>(memory["sourceContainerIds"]); + if (memory.contains("SpawnIds")) + SpawnIds = static_cast>(memory["SpawnIds"]); + if (memory.contains("creepNames")) + creepNames = static_cast>(memory["creepNames"]); minerIterator = memory.contains("minerIterator") ? static_cast(memory["minerIterator"]) : 0; } DouwcoHivemind::Room::~Room() { - memory["sources"] = sourceIds; - memory["sourceContainers"] = sourceContainerIds; + memory["sourceIds"] = sourceIds; + memory["sourceContainerIds"] = sourceContainerIds; + memory["SpawnIds"] = SpawnIds; + memory["creepNames"] = creepNames; memory["minerIterator"] = minerIterator; roomJs.setMemory(memory); } @@ -47,15 +55,16 @@ void DouwcoHivemind::Room::manageStructures() { } void DouwcoHivemind::Room::manageScreeps() { - // Get energy data - int energyAvailable = roomJs.energyAvailable(); - int energyCapacityAvailable = roomJs.energyCapacityAvailable(); + // Clean dead creeps from managed creepNames list. + cleanupManagedCreeps(); // Get job status auto requiredJobs = calculateRequiredJobs(); auto currentJobs = countCurrentJobs(); // Check if max energy used + int energyAvailable = roomJs.energyAvailable(); + int energyCapacityAvailable = roomJs.energyCapacityAvailable(); if (energyAvailable < energyCapacityAvailable && 0 < currentJobs[SUPPLIER]) return; @@ -71,6 +80,8 @@ void DouwcoHivemind::Room::manageScreeps() { break; } } + if (role == UNEMPLOYED) + return; // Set creep properties std::string name = getNewCreepName(role); @@ -80,10 +91,18 @@ void DouwcoHivemind::Room::manageScreeps() { // Create creep auto spawn = static_cast( Engine::getInstance()->Structures[SpawnIds[0]].get()); - std::string unique_name = name + std::to_string(Screeps::Game.time()); - spawn->spawnJs.spawnCreep(body, unique_name, opts); + spawn->spawnJs.spawnCreep(body, name, opts); // Store creepname in managed list. - screepNames.push_back(unique_name); + creepNames.push_back(name); +} + +void DouwcoHivemind::Room::cleanupManagedCreeps() { + std::vector cleanedCreepNames; + for (std::string creepName : creepNames) { + if (Engine::getInstance()->Creeps.contains(creepName)) + cleanedCreepNames.push_back(creepName); + } + creepNames = cleanedCreepNames; } void DouwcoHivemind::Room::updateSourceIds() { @@ -188,12 +207,10 @@ DouwcoHivemind::Room::countCurrentJobs() { currentJobs.emplace(BUILDER, 0); currentJobs.emplace(MINER, 0); - for (std::string creepName : screepNames) { + for (std::string creepName : creepNames) { if (Engine::getInstance()->Creeps.contains(creepName)) { CreepRole role = Engine::getInstance()->Creeps[creepName]->role; currentJobs[role] += 1; - } else { - Engine::getInstance()->Creeps.erase(creepName); } } return currentJobs; @@ -261,6 +278,7 @@ JSON DouwcoHivemind::Room::getNewCreepOptions(CreepRole role) { switch (role) { case MINER: opts["memory"]["sourceId"] = sourceIds[minerIterator]; + minerIterator = (minerIterator + 1) % sourceIds.size(); break; default: break; diff --git a/douwco_hivemind/src/Loop.cpp b/douwco_hivemind/src/Loop.cpp index 0b6a44b..8344cfb 100644 --- a/douwco_hivemind/src/Loop.cpp +++ b/douwco_hivemind/src/Loop.cpp @@ -20,9 +20,6 @@ extern "C" void loop() { { DouwcoHivemind::Engine engine; engine.loop(); - - auto test = &(DouwcoHivemind::Engine::getInstance()->Structures); - JS::console.log(std::string("test: ") + std::to_string(test->size())); } JS::console.log("Used CPU:\t" + std::to_string(Screeps::Game.cpuGetUsed()));