Moved spawning to room, multiple miners working.
This commit is contained in:
@@ -1,17 +1,23 @@
|
||||
#ifndef DOUWCO_HIVEMIND_ROOM_HPP
|
||||
#define DOUWCO_HIVEMIND_ROOM_HPP
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace DouwcoHivemind {
|
||||
class Room {
|
||||
|
||||
protected:
|
||||
Screeps::Room room;
|
||||
public:
|
||||
Screeps::Room roomJs;
|
||||
JSON memory;
|
||||
std::vector<std::string> sources = {};
|
||||
std::vector<std::string> sourceContainers = {};
|
||||
|
||||
std::vector<std::string> sourceIds = {};
|
||||
std::vector<std::string> sourceContainerIds = {};
|
||||
std::vector<std::string> SpawnIds = {};
|
||||
std::vector<std::string> screepNames = {};
|
||||
|
||||
private:
|
||||
int minerIterator;
|
||||
|
||||
public:
|
||||
Room(Screeps::Room rm);
|
||||
@@ -20,6 +26,8 @@ public:
|
||||
void loop();
|
||||
|
||||
protected:
|
||||
void manageScreeps();
|
||||
void manageStructures();
|
||||
void placeContainers();
|
||||
};
|
||||
} // namespace DouwcoHivemind
|
||||
|
||||
@@ -9,15 +9,13 @@ namespace DouwcoHivemind
|
||||
{
|
||||
class Spawn : public StructureBase
|
||||
{
|
||||
private:
|
||||
Screeps::StructureSpawn spawn;
|
||||
public:
|
||||
Screeps::StructureSpawn spawnJs;
|
||||
|
||||
public:
|
||||
Spawn(Screeps::StructureSpawn spwn) : spawn(spwn),
|
||||
Spawn(Screeps::StructureSpawn spwn) : spawnJs(spwn),
|
||||
StructureBase() {}
|
||||
~Spawn() {}
|
||||
|
||||
void loop() override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -36,9 +36,7 @@ DouwcoHivemind::Worker::~Worker() { memory["harvesting"] = harvesting; }
|
||||
|
||||
void DouwcoHivemind::Worker::loop() {
|
||||
if (harvesting) {
|
||||
JS::console.log(std::string("worker: harvesting"));
|
||||
if (creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0) {
|
||||
JS::console.log(std::string("worker: harvesting full"));
|
||||
harvesting = false;
|
||||
targetId.clear();
|
||||
} else {
|
||||
@@ -55,20 +53,15 @@ void DouwcoHivemind::Worker::loop() {
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Worker::getEnergy() {
|
||||
JS::console.log(std::string("worker: get energy"));
|
||||
if (targetId.empty()) {
|
||||
JS::console.log(std::string("worker: No target search energy"));
|
||||
searchEnergySource();
|
||||
} else {
|
||||
JS::console.log(std::string("worker: has target with energy"));
|
||||
auto target = getRoomObjectTarget();
|
||||
if (!target)
|
||||
return;
|
||||
if (isNearTo(target->pos(), 1)) {
|
||||
JS::console.log(std::string("worker: collect energy"));
|
||||
extractEnergyFromTarget();
|
||||
} else {
|
||||
JS::console.log(std::string("worker: go to energy"));
|
||||
moveToTarget(1);
|
||||
}
|
||||
}
|
||||
@@ -95,6 +88,10 @@ void DouwcoHivemind::Worker::searchEnergySource() {
|
||||
.value_or(0);
|
||||
if (availableEnergy == 0)
|
||||
continue;
|
||||
if (container->pos().inRangeTo(creep.pos(), 3)) {
|
||||
targetId = container->id();
|
||||
return;
|
||||
}
|
||||
if (fullestContents < availableEnergy) {
|
||||
fullestContents = availableEnergy;
|
||||
containerID = container->id();
|
||||
@@ -103,6 +100,11 @@ void DouwcoHivemind::Worker::searchEnergySource() {
|
||||
}
|
||||
}
|
||||
|
||||
// If no storage go for the containers
|
||||
if (!containerID.empty()) {
|
||||
targetId = containerID;
|
||||
}
|
||||
|
||||
// Search for loose resources
|
||||
auto resourceObjects = creep.room().find(Screeps::FIND_DROPPED_RESOURCES);
|
||||
if (resourceObjects.size() > 0) {
|
||||
@@ -113,6 +115,10 @@ void DouwcoHivemind::Worker::searchEnergySource() {
|
||||
if (resource->resourceType() != Screeps::RESOURCE_ENERGY)
|
||||
continue;
|
||||
int amount = resource->amount();
|
||||
if (resource->pos().inRangeTo(creep.pos(), 3)) {
|
||||
targetId = resource->id();
|
||||
return;
|
||||
}
|
||||
if (amount < 100)
|
||||
continue;
|
||||
if (amount > highestAmount) {
|
||||
@@ -137,6 +143,10 @@ void DouwcoHivemind::Worker::searchEnergySource() {
|
||||
continue;
|
||||
int amount =
|
||||
ruin->store().getUsedCapacity(Screeps::RESOURCE_ENERGY).value_or(0);
|
||||
if (ruin->pos().inRangeTo(creep.pos(), 3) && amount > 0) {
|
||||
targetId = ruin->id();
|
||||
return;
|
||||
}
|
||||
if (amount > highestAmount) {
|
||||
highestAmount = amount;
|
||||
ruinID = ruin->id();
|
||||
@@ -160,6 +170,10 @@ void DouwcoHivemind::Worker::searchEnergySource() {
|
||||
int amount = tombstone->store()
|
||||
.getUsedCapacity(Screeps::RESOURCE_ENERGY)
|
||||
.value_or(0);
|
||||
if (tombstone->pos().inRangeTo(creep.pos(), 3) && amount > 0) {
|
||||
targetId = tombstone->id();
|
||||
return;
|
||||
}
|
||||
if (amount > highestAmount) {
|
||||
highestAmount = amount;
|
||||
TombstoneID = tombstone->id();
|
||||
@@ -171,13 +185,8 @@ void DouwcoHivemind::Worker::searchEnergySource() {
|
||||
}
|
||||
}
|
||||
|
||||
// If still nothing found take the earlier found container.
|
||||
if (!containerID.empty()) {
|
||||
targetId = containerID;
|
||||
}
|
||||
|
||||
// If still nothing found, there is no target and search should start again.
|
||||
targetId = std::string();
|
||||
targetId.clear();
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Worker::extractEnergyFromTarget() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Entity/Room.hpp"
|
||||
|
||||
#include "Engine.hpp"
|
||||
#include "Screeps/Constants.hpp"
|
||||
#include "Screeps/Game.hpp"
|
||||
#include "Screeps/Room.hpp"
|
||||
@@ -12,39 +13,158 @@
|
||||
#include "Screeps/StructureController.hpp"
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Screeps/StructureSpawn.hpp"
|
||||
#include "Structures/Spawn.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
DouwcoHivemind::Room::Room(Screeps::Room rm) : room(rm), memory(rm.memory()) {
|
||||
DouwcoHivemind::Room::Room(Screeps::Room rm) : roomJs(rm), memory(rm.memory()) {
|
||||
if (memory.contains("sources"))
|
||||
sources = static_cast<std::vector<std::string>>(memory["sources"]);
|
||||
sourceIds = static_cast<std::vector<std::string>>(memory["sources"]);
|
||||
if (memory.contains("sourceContainers"))
|
||||
sourceContainers =
|
||||
sourceContainerIds =
|
||||
static_cast<std::vector<std::string>>(memory["sourceContainers"]);
|
||||
minerIterator = memory.contains("minerIterator")
|
||||
? static_cast<int>(memory["minerIterator"])
|
||||
: 0;
|
||||
}
|
||||
|
||||
DouwcoHivemind::Room::~Room() {
|
||||
memory["sources"] = sources;
|
||||
memory["sourceContainers"] = sourceContainers;
|
||||
room.setMemory(memory);
|
||||
memory["sources"] = sourceIds;
|
||||
memory["sourceContainers"] = sourceContainerIds;
|
||||
memory["minerIterator"] = minerIterator;
|
||||
roomJs.setMemory(memory);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::loop() {
|
||||
if (sources.size() == 0) {
|
||||
auto sources_ = room.find(Screeps::FIND_SOURCES);
|
||||
for (auto &source : sources_) {
|
||||
sources.push_back(static_cast<Screeps::Source *>(source.get())->id());
|
||||
manageStructures();
|
||||
manageScreeps();
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::manageStructures() { placeContainers(); }
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
// Check if max energy used
|
||||
if (energyAvailable < energyCapacityAvailable && 0 < existing_suppliers)
|
||||
return;
|
||||
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
placeContainers();
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
screepNames.push_back(unique_name);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::placeContainers() {
|
||||
// If no sources stored yet
|
||||
if (sourceIds.size() == 0) {
|
||||
auto sources_ = roomJs.find(Screeps::FIND_SOURCES);
|
||||
for (auto &source : sources_) {
|
||||
sourceIds.push_back(static_cast<Screeps::Source *>(source.get())->id());
|
||||
}
|
||||
}
|
||||
// No containers planned or build, planning now
|
||||
if (sourceContainers.size() < sources.size()) {
|
||||
int controller_x = room.controller().value().pos().x();
|
||||
int controller_y = room.controller().value().pos().y();
|
||||
if (sourceContainerIds.size() < sourceIds.size()) {
|
||||
int controller_x = roomJs.controller().value().pos().x();
|
||||
int controller_y = roomJs.controller().value().pos().y();
|
||||
|
||||
for (auto sourceId : sources) {
|
||||
for (auto sourceId : sourceIds) {
|
||||
auto roomObj = Screeps::Game.getObjectById(sourceId);
|
||||
int source_x = roomObj->pos().x();
|
||||
int source_y = roomObj->pos().y();
|
||||
@@ -58,7 +178,7 @@ void DouwcoHivemind::Room::placeContainers() {
|
||||
continue;
|
||||
int x = source_x + dx;
|
||||
int y = source_y + dy;
|
||||
int terrainType = room.getTerrain().get(x, y);
|
||||
int terrainType = roomJs.getTerrain().get(x, y);
|
||||
if (terrainType != Screeps::TERRAIN_MASK_WALL) {
|
||||
int cost = std::abs(x - controller_x) + std::abs(y - controller_y);
|
||||
if (cost < lowest_cost) {
|
||||
@@ -69,30 +189,31 @@ void DouwcoHivemind::Room::placeContainers() {
|
||||
}
|
||||
}
|
||||
}
|
||||
room.createConstructionSite(best_x, best_y, Screeps::STRUCTURE_CONTAINER);
|
||||
sourceContainers.push_back("under_construction");
|
||||
roomJs.createConstructionSite(best_x, best_y,
|
||||
Screeps::STRUCTURE_CONTAINER);
|
||||
sourceContainerIds.push_back("under_construction");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Check if construction container is done.
|
||||
for (auto entry : sourceContainers) {
|
||||
for (auto entry : sourceContainerIds) {
|
||||
if (entry != "under_construction")
|
||||
continue;
|
||||
auto structures = room.find(Screeps::FIND_STRUCTURES);
|
||||
auto structures = roomJs.find(Screeps::FIND_STRUCTURES);
|
||||
int index = 0;
|
||||
for (auto &structure : structures) {
|
||||
auto str = dynamic_cast<Screeps::Structure *>(structure.get());
|
||||
if (str->structureType() == Screeps::STRUCTURE_CONTAINER) {
|
||||
sourceContainers[index] = str->id();
|
||||
sourceContainerIds[index] = str->id();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Check if containers still exist
|
||||
for (int i = 0; i < sourceContainers.size(); i++) {
|
||||
auto roomObj = Screeps::Game.getObjectById(sourceContainers[i]);
|
||||
for (int i = 0; i < sourceContainerIds.size(); i++) {
|
||||
auto roomObj = Screeps::Game.getObjectById(sourceContainerIds[i]);
|
||||
if (!roomObj)
|
||||
sourceContainers.erase(sourceContainers.begin() + i);
|
||||
sourceContainerIds.erase(sourceContainerIds.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +1 @@
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
|
||||
#include "Creeps/CreepBase.hpp"
|
||||
#include "Engine.hpp"
|
||||
#include "Structures/Spawn.hpp"
|
||||
|
||||
void DouwcoHivemind::Spawn::loop() {
|
||||
// Get energy data
|
||||
int energyAvailable = spawn.room().energyAvailable();
|
||||
int energyCapacityAvailable = spawn.room().energyCapacityAvailable();
|
||||
|
||||
// Calculate needed creep roles
|
||||
int required_upgraders = 1;
|
||||
int required_suppliers = 2;
|
||||
int required_maintainers = 1;
|
||||
int required_builders =
|
||||
spawn.room().find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() > 0 ? 1 : 0;
|
||||
int required_miners = 1; // spawn.room().memory()["sources"].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 : Screeps::Game.creeps()) {
|
||||
CreepRole role = creep.second.memory()["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++;
|
||||
}
|
||||
|
||||
// Check if max energy used
|
||||
if (energyAvailable < energyCapacityAvailable && 0 < existing_suppliers)
|
||||
return;
|
||||
|
||||
// Set creep properties
|
||||
std::string name;
|
||||
JSON opts;
|
||||
CreepRole role = CreepRole::UNEMPLOYED;
|
||||
if (required_miners > existing_miners) {
|
||||
role = CreepRole::MINER;
|
||||
opts["memory"]["sourceId"] =
|
||||
spawn.room().memory()["sources"][0]; // make logic for more
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
// Create creep
|
||||
spawn.spawnCreep(body, name + std::to_string(Screeps::Game.time()), opts);
|
||||
}
|
||||
Reference in New Issue
Block a user