diff --git a/douwco_hivemind/include/Constants.hpp b/douwco_hivemind/include/Constants.hpp new file mode 100644 index 0000000..d458238 --- /dev/null +++ b/douwco_hivemind/include/Constants.hpp @@ -0,0 +1,9 @@ +#ifndef DOUWCO_HIVEMIND_CONSTANTS_HPP +#define DOUWCO_HIVEMIND_CONSTANTS_HPP + +namespace DouwcoHivemind +{ + enum CreepRole { UNEMPLOYED, SUPPLIER, UPGRADER, BUILDER, MAINTAINER, MINER }; +} + +#endif // DOUWCO_HIVEMIND_CONSTANTS_HPP \ No newline at end of file diff --git a/douwco_hivemind/include/Creeps/CreepBase.hpp b/douwco_hivemind/include/Creeps/CreepBase.hpp index efd649a..237e13c 100644 --- a/douwco_hivemind/include/Creeps/CreepBase.hpp +++ b/douwco_hivemind/include/Creeps/CreepBase.hpp @@ -2,6 +2,7 @@ #define DOUWCO_HIVEMIND_CREEPBASE_HPP #include +#include "Constants.hpp" namespace Screeps { class RoomPosition; @@ -10,7 +11,6 @@ class PathStep; } // namespace Screeps namespace DouwcoHivemind { -enum CreepRole { UNEMPLOYED, SUPPLIER, UPGRADER, BUILDER, MAINTAINER, MINER }; class CreepBase { public: diff --git a/douwco_hivemind/include/Entity/Room.hpp b/douwco_hivemind/include/Entity/Room.hpp index c87412f..5704977 100644 --- a/douwco_hivemind/include/Entity/Room.hpp +++ b/douwco_hivemind/include/Entity/Room.hpp @@ -19,7 +19,7 @@ public: void loop(); protected: - bool placeContainers(); + void placeContainers(); }; } // namespace DouwcoHivemind diff --git a/douwco_hivemind/include/Structures/Tower.hpp b/douwco_hivemind/include/Structures/Tower.hpp new file mode 100644 index 0000000..408e74e --- /dev/null +++ b/douwco_hivemind/include/Structures/Tower.hpp @@ -0,0 +1,24 @@ +#ifndef DOUWCO_HIVEMIND_TOWER_HPP +#define DOUWCO_HIVEMIND_TOWER_HPP + +#include + +#include "Structures/StructureBase.hpp" + +namespace DouwcoHivemind +{ + class Tower : public StructureBase + { + private: + Screeps::StructureTower tower; + + public: + Tower(Screeps::StructureTower twr) : tower(twr), + StructureBase() {} + ~Tower() {} + + void loop() override; + }; +} + +#endif // DOUWCO_HIVEMIND_TOWER_HPP \ No newline at end of file diff --git a/douwco_hivemind/src/Creeps/Supplier.cpp b/douwco_hivemind/src/Creeps/Supplier.cpp index 40fbd9f..7f798da 100644 --- a/douwco_hivemind/src/Creeps/Supplier.cpp +++ b/douwco_hivemind/src/Creeps/Supplier.cpp @@ -1,120 +1,122 @@ -#include -#include #include +#include +#include +#include -#include #include -#include +#include #include -#include #include +#include +#include +#include #include #include -#include #include +#include +#include #include -#include #include "Creeps/Supplier.hpp" +#include "Screeps/Constants.hpp" -void DouwcoHivemind::Supplier::depositEnergy() -{ - auto structure = getEnergyStructureTarget(); - if (!structure) return; +void DouwcoHivemind::Supplier::depositEnergy() { + auto structure = getEnergyStructureTarget(); + if (!structure) + return; - if (isNearTo(structure->pos(), 1)) - { - int resp = creep.transfer(*structure, Screeps::RESOURCE_ENERGY); - } - else - { - moveToTarget(); - } + if (isNearTo(structure->pos(), 1)) { + int resp = creep.transfer(*structure, Screeps::RESOURCE_ENERGY); + } else { + moveToTarget(); + } } -std::unique_ptr DouwcoHivemind::Supplier::getEnergyStructureTarget() -{ - auto roomObj = getRoomObjectTarget(); - if (!roomObj) - { - searchEnergyStructure(); - return nullptr; - } +std::unique_ptr +DouwcoHivemind::Supplier::getEnergyStructureTarget() { + auto roomObj = getRoomObjectTarget(); + if (!roomObj) { + searchEnergyStructure(); + return nullptr; + } - auto structure = std::unique_ptr(dynamic_cast(roomObj.release())); + auto structure = std::unique_ptr( + dynamic_cast(roomObj.release())); + if (!structure) { + searchEnergyStructure(); + return nullptr; + } + + // Check if the structure can receive energy to harvest + int energyCapacity; + auto structureType = structure->structureType(); + if (structureType == Screeps::STRUCTURE_TOWER) { + auto tower = dynamic_cast(structure.get()); + energyCapacity = + tower->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } else if (structureType == Screeps::STRUCTURE_SPAWN) { + auto spawn = dynamic_cast(structure.get()); + energyCapacity = + spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } else if (structureType == Screeps::STRUCTURE_EXTENSION) { + auto extension = + dynamic_cast(structure.get()); + energyCapacity = + extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } else if (structureType == Screeps::STRUCTURE_STORAGE) { + auto storage = dynamic_cast(structure.get()); + energyCapacity = + storage->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } + + if (energyCapacity == 0) { + searchEnergyStructure(); + return nullptr; + } + + return std::move(structure); +} + +void DouwcoHivemind::Supplier::searchEnergyStructure() { + int mostEnergyNeeded = 0; + std::string selectedStructureId; + std::string storageStructureId; + auto structures = creep.room().find(Screeps::FIND_MY_STRUCTURES); + for (auto &structureObject : structures) { + auto structure = dynamic_cast(structureObject.get()); if (!structure) - { - searchEnergyStructure(); - return nullptr; - } + continue; + + int energyRequired = 0; - // Check if the structure can receive energy to harvest - int energyCapacity; auto structureType = structure->structureType(); - if (structureType == Screeps::STRUCTURE_SPAWN) - { - auto spawn = dynamic_cast(structure.get()); - energyCapacity = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); - } - else if (structureType == Screeps::STRUCTURE_EXTENSION) - { - auto extension = dynamic_cast(structure.get()); - energyCapacity = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); - } - else if (structureType == Screeps::STRUCTURE_TOWER) - { - auto extension = dynamic_cast(structure.get()); - energyCapacity = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + if (structureType == Screeps::STRUCTURE_TOWER) { + auto tower = dynamic_cast(structure); + energyRequired = + tower->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } else if (structureType == Screeps::STRUCTURE_SPAWN) { + auto spawn = dynamic_cast(structure); + energyRequired = + spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } else if (structureType == Screeps::STRUCTURE_EXTENSION) { + auto extension = dynamic_cast(structure); + energyRequired = + extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); + } else if (structureType == Screeps::STRUCTURE_STORAGE) { + storageStructureId = structure->id(); } - if (energyCapacity == 0) - { - searchEnergyStructure(); - return nullptr; + if (energyRequired > mostEnergyNeeded) { + mostEnergyNeeded = energyRequired; + selectedStructureId = structure->id(); } + } - return std::move(structure); -} - -void DouwcoHivemind::Supplier::searchEnergyStructure() -{ - int mostEnergyNeeded = 0; - Screeps::Structure *selectedStructure; - auto structures = creep.room().find(Screeps::FIND_MY_STRUCTURES); - for (auto &structureObject : structures) - { - auto structure = dynamic_cast(structureObject.get()); - if (!structure) - continue; - - int energyRequired; - - auto structureType = structure->structureType(); - if (structureType == Screeps::STRUCTURE_SPAWN) - { - auto spawn = dynamic_cast(structure); - energyRequired = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); - } - else if (structureType == Screeps::STRUCTURE_EXTENSION) - { - auto extension = dynamic_cast(structure); - energyRequired = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); - } - else if (structureType == Screeps::STRUCTURE_TOWER) - { - auto extension = dynamic_cast(structure); - energyRequired = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value(); - } - - if (energyRequired > mostEnergyNeeded) - { - mostEnergyNeeded = energyRequired; - selectedStructure = structure; - } - } - - if (selectedStructure) - target_id = selectedStructure->id(); - else - target_id.clear(); + if (mostEnergyNeeded == 0) + selectedStructureId = storageStructureId; + + if (selectedStructureId.empty()) + target_id.clear(); + else + target_id = selectedStructureId; } diff --git a/douwco_hivemind/src/Engine.cpp b/douwco_hivemind/src/Engine.cpp index b0a55f1..edf01c8 100644 --- a/douwco_hivemind/src/Engine.cpp +++ b/douwco_hivemind/src/Engine.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "Engine.hpp" @@ -11,7 +12,10 @@ #include "Creeps/Upgrader.hpp" #include "Creeps/Miner.hpp" +#include "Screeps/Constants.hpp" +#include "Screeps/StructureSpawn.hpp" #include "Structures/Spawn.hpp" +#include "Structures/Tower.hpp" DouwcoHivemind::Engine::Engine() { ReadOutRooms(); @@ -66,9 +70,15 @@ void DouwcoHivemind::Engine::ReadOutCreeps() { void DouwcoHivemind::Engine::ReadOutStructures() { JS::console.log(std::string("Reading out structures")); - auto spawns = Screeps::Game.spawns(); - for (auto &spawn : spawns) { - structures.push_back(std::make_unique(spawn.second)); + auto structures_src =Screeps::Game.structures(); + for (auto &structure : structures_src) { + std::string structureType = structure.second.structureType(); + if(structureType == Screeps::STRUCTURE_TOWER){ + structures.push_back(std::make_unique(static_cast(structure.second))); + } + else if(structureType == Screeps::STRUCTURE_SPAWN){ + structures.push_back(std::make_unique(static_cast(structure.second))); + } } } diff --git a/douwco_hivemind/src/Entity/Room.cpp b/douwco_hivemind/src/Entity/Room.cpp index 97718ba..f049525 100644 --- a/douwco_hivemind/src/Entity/Room.cpp +++ b/douwco_hivemind/src/Entity/Room.cpp @@ -9,13 +9,8 @@ #include "Screeps/Structure.hpp" #include "Screeps/StructureContainer.hpp" #include "Screeps/StructureController.hpp" -#include -#include -#include -#include -#include -#include -#include + +#include "Constants.hpp" DouwcoHivemind::Room::Room(Screeps::Room rm) : room(rm), memory(rm.memory()) { if (memory.contains("sourceContainers")) @@ -28,13 +23,13 @@ DouwcoHivemind::Room::~Room() { room.setMemory(memory); } -void DouwcoHivemind::Room::loop() { - if(Screeps::Game.time()%100!=0)return; - if (placeContainers()) - return; +void DouwcoHivemind::Room::loop() { + // Check on building setup + if(Screeps::Game.time()%1000!=0) return; + placeContainers(); } -bool DouwcoHivemind::Room::placeContainers() { +void DouwcoHivemind::Room::placeContainers() { auto sources = room.find(Screeps::FIND_SOURCES); // No containers planned or build, planning now @@ -69,7 +64,7 @@ bool DouwcoHivemind::Room::placeContainers() { room.createConstructionSite(best_x, best_y, Screeps::STRUCTURE_CONTAINER); sourceContainers.push_back("under_construction"); } - return true; + return; } // Check if construction container is done. for (auto entry : sourceContainers) { @@ -84,12 +79,11 @@ bool DouwcoHivemind::Room::placeContainers() { index++; } } - return true; + return; } // Check if containers still exist for(int i = 0; i < sourceContainers.size(); i++){ auto roomObj = Screeps::Game.getObjectById(sourceContainers[i]); if(!roomObj) sourceContainers.erase(sourceContainers.begin() + i); } - return false; -} \ No newline at end of file +} diff --git a/douwco_hivemind/src/Structures/Spawn.cpp b/douwco_hivemind/src/Structures/Spawn.cpp index 1d6af57..672bccc 100644 --- a/douwco_hivemind/src/Structures/Spawn.cpp +++ b/douwco_hivemind/src/Structures/Spawn.cpp @@ -6,68 +6,92 @@ void DouwcoHivemind::Spawn::loop() { // Only run every 500 ticks - if (Screeps::Game.time() % 250 != 0) + if (Screeps::Game.time() % 100 != 0) return; + // Get energy data int energyAvailable = spawn.room().energyAvailable(); int energyCapacityAvailable = spawn.room().energyCapacityAvailable(); + // Calculate needed creep roles int required_upgraders = 1; - int required_suppliers = 1; + int required_suppliers = 2; int required_maintainers = spawn.room().find(Screeps::FIND_STRUCTURES).size() <= 2 ? 0 : 1; ; int required_builders = spawn.room().find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() == 0 ? 0 : 1; - int required_miners = 1; //spawn.room().memory()["sourceContainers"].size(); + int required_miners = 1; // spawn.room().memory()["sourceContainers"].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) - required_suppliers--; + existing_suppliers++; else if (role == CreepRole::UPGRADER) - required_upgraders--; + existing_upgraders++; else if (role == CreepRole::MAINTAINER) - required_maintainers--; + existing_maintainers++; else if (role == CreepRole::BUILDER) - required_builders--; + existing_builders++; else if (role == CreepRole::MINER) - required_miners--; + existing_miners++; } - // if (energyAvailable < energyCapacityAvailable && 3 < - // Screeps::Game.creeps().size()) - // return; + // Check if max energy used + if (energyAvailable < energyCapacityAvailable && 0 < existing_suppliers) + return; + + // Set creep properties std::string name; JSON opts; - if (required_upgraders > 0) { - opts["memory"]["role"] = CreepRole::UPGRADER; - name = "Upgrader: "; - } else if (required_miners > 0) { - opts["memory"]["role"] = CreepRole::MINER; + CreepRole role = CreepRole::UNEMPLOYED; + if (required_miners > existing_miners) { + role = CreepRole::MINER; opts["memory"]["target_id"] = spawn.room().memory()["sourceContainers"][0]; // make logic for more name = "Miner: "; - } else if (required_suppliers > 0) { - opts["memory"]["role"] = CreepRole::SUPPLIER; + } else if (required_suppliers > existing_suppliers) { + role = CreepRole::SUPPLIER; name = "Supplier: "; - } else if (required_builders > 0) { - opts["memory"]["role"] = CreepRole::BUILDER; + } 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 > 0) { - opts["memory"]["role"] = CreepRole::MAINTAINER; + } else if (required_maintainers > existing_maintainers) { + role = CreepRole::MAINTAINER; name = "Maintainer: "; } else return; + opts["memory"]["role"] = role; + + // Build creep body std::vector body; - if (opts["memory"]["role"] == CreepRole::MINER) { + 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"); } + } else if (role == SUPPLIER) { + body.push_back("move"); + body.push_back("work"); + body.push_back("carry"); + for (int i = 0; i < (energyAvailable - 200) / 100 && i * 50 < energyCapacityAvailable; i++) { + body.push_back("move"); + body.push_back("carry"); + } } else { for (int i = 0; i < energyAvailable / 200; i++) { body.push_back("work"); @@ -76,5 +100,6 @@ void DouwcoHivemind::Spawn::loop() { } } + // Create creep spawn.spawnCreep(body, name + std::to_string(Screeps::Game.time()), opts); } \ No newline at end of file diff --git a/douwco_hivemind/src/Structures/Tower.cpp b/douwco_hivemind/src/Structures/Tower.cpp new file mode 100644 index 0000000..d9f261f --- /dev/null +++ b/douwco_hivemind/src/Structures/Tower.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +#include "Creeps/CreepBase.hpp" +#include "Screeps/Constants.hpp" +#include "Screeps/Creep.hpp" +#include "Structures/Tower.hpp" + +void DouwcoHivemind::Tower::loop() { + int minHits = INT16_MAX; + Screeps::Creep *target; + auto hostile_creeps = tower.room().find(Screeps::FIND_HOSTILE_CREEPS); + for (auto &creepRoomObj : hostile_creeps) { + Screeps::Creep* creep = static_cast(creepRoomObj.get()); + int health = creep->hits(); + if(health