Changed behaviour of maintainer and fixed screep cleanup.

This commit is contained in:
2026-07-12 02:53:46 +02:00
parent 88deef5109
commit 591fd97be0
6 changed files with 127 additions and 120 deletions

View File

@@ -14,7 +14,7 @@ public:
std::vector<std::string> sourceIds = {};
std::vector<std::string> sourceContainerIds = {};
std::vector<std::string> SpawnIds = {};
std::vector<std::string> screepNames = {};
std::vector<std::string> creepNames = {};
private:
int minerIterator;
@@ -33,6 +33,8 @@ protected:
void updateSpawnIds();
void updateContainerIds();
void cleanupManagedCreeps();
std::map<CreepRole, int> calculateRequiredJobs();
std::map<CreepRole, int> countCurrentJobs();
std::string getNewCreepName(CreepRole role);

View File

@@ -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) {

View File

@@ -1,91 +1,85 @@
#include <vector>
#include <optional>
#include <emscripten.h>
#include <optional>
#include <vector>
#include <Screeps/Game.hpp>
#include <Screeps/Creep.hpp>
#include <Screeps/Source.hpp>
#include <Screeps/Game.hpp>
#include <Screeps/Room.hpp>
#include <Screeps/RoomPosition.hpp>
#include <Screeps/RoomObject.hpp>
#include <Screeps/RoomPosition.hpp>
#include <Screeps/Source.hpp>
#include <Screeps/Store.hpp>
#include <Screeps/Structure.hpp>
#include <Screeps/StructureController.hpp>
#include <Screeps/StructureSpawn.hpp>
#include <Screeps/StructureExtension.hpp>
#include <Screeps/StructureSpawn.hpp>
#include <Screeps/StructureTower.hpp>
#include <Screeps/Store.hpp>
#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<Screeps::Structure> DouwcoHivemind::Maintainer::getDamagedStructureTarget()
{
auto roomObj = getRoomObjectTarget();
if (!roomObj)
{
searchDamagedStructure();
return nullptr;
}
std::unique_ptr<Screeps::Structure>
DouwcoHivemind::Maintainer::getDamagedStructureTarget() {
auto roomObj = getRoomObjectTarget();
if (!roomObj) {
searchDamagedStructure();
return nullptr;
}
auto structure = std::unique_ptr<Screeps::Structure>(dynamic_cast<Screeps::Structure *>(roomObj.release()));
auto structure = std::unique_ptr<Screeps::Structure>(
dynamic_cast<Screeps::Structure *>(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<Screeps::Structure *>(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<Screeps::Structure *>(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();
}

View File

@@ -3,6 +3,7 @@
#include <Screeps/StructureController.hpp>
#include <algorithm>
#include <memory>
#include <string>
#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<JS::Value>("keys", creepMemory);
int size = creepNames["length"].as<int>();
for (int i = 0; i < size; i++) {
auto name = creepNames[i].as<std::string>();
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);
}

View File

@@ -16,21 +16,29 @@
#include "Screeps/StructureSpawn.hpp"
#include "Structures/Spawn.hpp"
#include <cstdint>
#include <string>
#include <vector>
DouwcoHivemind::Room::Room(Screeps::Room rm) : roomJs(rm), memory(rm.memory()) {
if (memory.contains("sources"))
sourceIds = static_cast<std::vector<std::string>>(memory["sources"]);
if (memory.contains("sourceContainers"))
if (memory.contains("sourceIds"))
sourceIds = static_cast<std::vector<std::string>>(memory["sourceIds"]);
if (memory.contains("sourceContainerIds"))
sourceContainerIds =
static_cast<std::vector<std::string>>(memory["sourceContainers"]);
static_cast<std::vector<std::string>>(memory["sourceContainerIds"]);
if (memory.contains("SpawnIds"))
SpawnIds = static_cast<std::vector<std::string>>(memory["SpawnIds"]);
if (memory.contains("creepNames"))
creepNames = static_cast<std::vector<std::string>>(memory["creepNames"]);
minerIterator = memory.contains("minerIterator")
? static_cast<int>(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<Spawn *>(
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<std::string> 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;

View File

@@ -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()));