improved the code of Room
This commit is contained in:
@@ -26,9 +26,19 @@ public:
|
||||
void loop();
|
||||
|
||||
protected:
|
||||
void manageScreeps();
|
||||
void manageStructures();
|
||||
void placeContainers();
|
||||
void manageScreeps();
|
||||
|
||||
void updateSourceIds();
|
||||
void updateSpawnIds();
|
||||
void updateContainerIds();
|
||||
|
||||
std::map<CreepRole, int> calculateRequiredJobs();
|
||||
std::map<CreepRole, int> countCurrentJobs();
|
||||
std::string getNewCreepName(CreepRole role);
|
||||
std::vector<std::string> getNewCreepBody(CreepRole role);
|
||||
JSON getNewCreepOptions(CreepRole role);
|
||||
|
||||
};
|
||||
} // namespace DouwcoHivemind
|
||||
|
||||
|
||||
@@ -79,5 +79,5 @@ void DouwcoHivemind::Builder::searchConstructionSite()
|
||||
if (selectedConstructionSite)
|
||||
targetId = selectedConstructionSite->id();
|
||||
else
|
||||
targetId.clear();
|
||||
creep.suicide();
|
||||
}
|
||||
|
||||
@@ -40,125 +40,73 @@ void DouwcoHivemind::Room::loop() {
|
||||
manageScreeps();
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::manageStructures() { placeContainers(); }
|
||||
void DouwcoHivemind::Room::manageStructures() {
|
||||
updateSourceIds();
|
||||
updateSpawnIds();
|
||||
updateContainerIds();
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::manageScreeps() {
|
||||
// Get energy data
|
||||
int energyAvailable = roomJs.energyAvailable();
|
||||
int energyCapacityAvailable = roomJs.energyCapacityAvailable();
|
||||
|
||||
// Calculate needed creep roles
|
||||
int required_upgraders = 1;
|
||||
int required_suppliers = 2;
|
||||
int required_maintainers = 1;
|
||||
int required_builders =
|
||||
roomJs.find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() > 0 ? 1 : 0;
|
||||
int required_miners = sourceIds.size();
|
||||
|
||||
// Count existing roles
|
||||
int existing_upgraders = 0;
|
||||
int existing_suppliers = 0;
|
||||
int existing_maintainers = 0;
|
||||
int existing_builders = 0;
|
||||
int existing_miners = 0;
|
||||
|
||||
for (auto &creep : Engine::getInstance()->Creeps) {
|
||||
CreepRole role = creep.second->role;
|
||||
|
||||
if (role == CreepRole::SUPPLIER)
|
||||
existing_suppliers++;
|
||||
else if (role == CreepRole::UPGRADER)
|
||||
existing_upgraders++;
|
||||
else if (role == CreepRole::MAINTAINER)
|
||||
existing_maintainers++;
|
||||
else if (role == CreepRole::BUILDER)
|
||||
existing_builders++;
|
||||
else if (role == CreepRole::MINER)
|
||||
existing_miners++;
|
||||
}
|
||||
// Get job status
|
||||
auto requiredJobs = calculateRequiredJobs();
|
||||
auto currentJobs = countCurrentJobs();
|
||||
|
||||
// Check if max energy used
|
||||
if (energyAvailable < energyCapacityAvailable && 0 < existing_suppliers)
|
||||
if (energyAvailable < energyCapacityAvailable && 0 < currentJobs[SUPPLIER])
|
||||
return;
|
||||
|
||||
// Select based on priority which role needs to be made first
|
||||
const std::vector<CreepRole> rolePriority = {
|
||||
CreepRole::MINER, CreepRole::SUPPLIER, CreepRole::UPGRADER,
|
||||
CreepRole::BUILDER, CreepRole::MAINTAINER};
|
||||
|
||||
CreepRole role = CreepRole::UNEMPLOYED;
|
||||
for (CreepRole roleType : rolePriority) {
|
||||
if (requiredJobs[roleType] > currentJobs[roleType]) {
|
||||
role = roleType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set creep properties
|
||||
std::string name;
|
||||
JSON opts;
|
||||
CreepRole role = CreepRole::UNEMPLOYED;
|
||||
if (required_miners > existing_miners) {
|
||||
role = CreepRole::MINER;
|
||||
opts["memory"]["sourceId"] = sourceIds[minerIterator];
|
||||
minerIterator = (minerIterator + 1) % sourceIds.size();
|
||||
name = "Miner: ";
|
||||
} else if (required_suppliers > existing_suppliers) {
|
||||
role = CreepRole::SUPPLIER;
|
||||
name = "Supplier: ";
|
||||
} else if (required_upgraders > existing_upgraders) {
|
||||
role = CreepRole::UPGRADER;
|
||||
name = "Upgrader: ";
|
||||
} else if (required_builders > existing_builders) {
|
||||
role = CreepRole::BUILDER;
|
||||
name = "Builder: ";
|
||||
} else if (required_maintainers > existing_maintainers) {
|
||||
role = CreepRole::MAINTAINER;
|
||||
name = "Maintainer: ";
|
||||
} else
|
||||
return;
|
||||
|
||||
opts["memory"]["role"] = role;
|
||||
|
||||
// Build creep body
|
||||
std::vector<std::string> body;
|
||||
// Miner body with up to 5 work (10 en/s) bits for 3000 source mining in 300
|
||||
// tick regen.
|
||||
if (role == CreepRole::MINER) {
|
||||
body.push_back("move");
|
||||
body.push_back("work");
|
||||
for (int i = 0; i < (energyAvailable - 150) / 100 && i < 5; i++) {
|
||||
body.push_back("work");
|
||||
}
|
||||
}
|
||||
// Supplier body with only move and carry to move energy around
|
||||
else if (role == SUPPLIER) {
|
||||
for (int i = 0; i < energyAvailable / 100; i++) {
|
||||
body.push_back("move");
|
||||
body.push_back("carry");
|
||||
}
|
||||
}
|
||||
// Worker body with balanced parts.
|
||||
else {
|
||||
for (int i = 0; i < energyAvailable / 200; i++) {
|
||||
body.push_back("work");
|
||||
body.push_back("carry");
|
||||
body.push_back("move");
|
||||
}
|
||||
}
|
||||
|
||||
// If no spawns stored yet
|
||||
if (SpawnIds.size() == 0) {
|
||||
auto spawnStructures = roomJs.find(Screeps::FIND_MY_SPAWNS);
|
||||
for (auto &spawnStructure : spawnStructures) {
|
||||
SpawnIds.push_back(
|
||||
static_cast<Screeps::StructureSpawn *>(spawnStructure.get())->id());
|
||||
}
|
||||
}
|
||||
std::string name = getNewCreepName(role);
|
||||
auto body = getNewCreepBody(role);
|
||||
JSON opts = getNewCreepOptions(role);
|
||||
|
||||
// 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);
|
||||
// Store creepname in managed list.
|
||||
screepNames.push_back(unique_name);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::placeContainers() {
|
||||
// If no sources stored yet
|
||||
void DouwcoHivemind::Room::updateSourceIds() {
|
||||
if (sourceIds.size() == 0) {
|
||||
auto sources_ = roomJs.find(Screeps::FIND_SOURCES);
|
||||
for (auto &source : sources_) {
|
||||
auto sources = roomJs.find(Screeps::FIND_SOURCES);
|
||||
for (auto &source : sources) {
|
||||
sourceIds.push_back(static_cast<Screeps::Source *>(source.get())->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::updateSpawnIds() {
|
||||
if (SpawnIds.size() == 0 || Screeps::Game.time() % 1000 == 0) {
|
||||
SpawnIds.clear();
|
||||
auto spawnStructures = roomJs.find(Screeps::FIND_MY_SPAWNS);
|
||||
for (auto &spawnStructure : spawnStructures) {
|
||||
SpawnIds.push_back(
|
||||
static_cast<Screeps::StructureSpawn *>(spawnStructure.get())->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::updateContainerIds() {
|
||||
// No containers planned or build, planning now
|
||||
if (sourceContainerIds.size() < sourceIds.size()) {
|
||||
int controller_x = roomJs.controller().value().pos().x();
|
||||
@@ -217,3 +165,105 @@ void DouwcoHivemind::Room::placeContainers() {
|
||||
sourceContainerIds.erase(sourceContainerIds.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<DouwcoHivemind::CreepRole, int>
|
||||
DouwcoHivemind::Room::calculateRequiredJobs() {
|
||||
std::map<DouwcoHivemind::CreepRole, int> requiredJobs;
|
||||
requiredJobs.emplace(UPGRADER, 1);
|
||||
requiredJobs.emplace(SUPPLIER, 2);
|
||||
requiredJobs.emplace(MAINTAINER, 1);
|
||||
requiredJobs.emplace(
|
||||
BUILDER,
|
||||
roomJs.find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() > 0 ? 1 : 0);
|
||||
requiredJobs.emplace(MINER, sourceIds.size());
|
||||
return requiredJobs;
|
||||
}
|
||||
|
||||
std::map<DouwcoHivemind::CreepRole, int>
|
||||
DouwcoHivemind::Room::countCurrentJobs() {
|
||||
std::map<DouwcoHivemind::CreepRole, int> currentJobs;
|
||||
currentJobs.emplace(UPGRADER, 0);
|
||||
currentJobs.emplace(SUPPLIER, 0);
|
||||
currentJobs.emplace(MAINTAINER, 0);
|
||||
currentJobs.emplace(BUILDER, 0);
|
||||
currentJobs.emplace(MINER, 0);
|
||||
|
||||
for (std::string creepName : screepNames) {
|
||||
if (Engine::getInstance()->Creeps.contains(creepName)) {
|
||||
CreepRole role = Engine::getInstance()->Creeps[creepName]->role;
|
||||
currentJobs[role] += 1;
|
||||
} else {
|
||||
Engine::getInstance()->Creeps.erase(creepName);
|
||||
}
|
||||
}
|
||||
return currentJobs;
|
||||
}
|
||||
|
||||
std::string DouwcoHivemind::Room::getNewCreepName(CreepRole role) {
|
||||
std::string name;
|
||||
switch (role) {
|
||||
case UPGRADER:
|
||||
name = "Upgrader";
|
||||
break;
|
||||
case SUPPLIER:
|
||||
name = "Supplier";
|
||||
break;
|
||||
case MAINTAINER:
|
||||
name = "Maintainer";
|
||||
break;
|
||||
case BUILDER:
|
||||
name = "Builder";
|
||||
break;
|
||||
case MINER:
|
||||
name = "Miner";
|
||||
break;
|
||||
default:
|
||||
name = "creep";
|
||||
break;
|
||||
}
|
||||
return name + " - " + std::to_string(Screeps::Game.time());
|
||||
}
|
||||
|
||||
std::vector<std::string> DouwcoHivemind::Room::getNewCreepBody(CreepRole role) {
|
||||
int energyAvailable = roomJs.energyAvailable();
|
||||
|
||||
std::vector<std::string> body;
|
||||
switch (role) {
|
||||
case MINER:
|
||||
body.push_back("move");
|
||||
body.push_back("work");
|
||||
for (int i = 0; i < (energyAvailable - 150) / 100 && i < 5; i++) {
|
||||
body.push_back("work");
|
||||
}
|
||||
break;
|
||||
case SUPPLIER:
|
||||
for (int i = 0; i < energyAvailable / 100; i++) {
|
||||
body.push_back("move");
|
||||
body.push_back("carry");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < energyAvailable / 200; i++) {
|
||||
body.push_back("work");
|
||||
body.push_back("carry");
|
||||
body.push_back("move");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
JSON DouwcoHivemind::Room::getNewCreepOptions(CreepRole role) {
|
||||
JSON opts;
|
||||
opts["memory"]["role"] = role;
|
||||
|
||||
switch (role) {
|
||||
case MINER:
|
||||
opts["memory"]["sourceId"] = sourceIds[minerIterator];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
Reference in New Issue
Block a user