Updated the supplier behavior to also use storage and implemented tower.
This commit is contained in:
9
douwco_hivemind/include/Constants.hpp
Normal file
9
douwco_hivemind/include/Constants.hpp
Normal file
@@ -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
|
||||
@@ -2,6 +2,7 @@
|
||||
#define DOUWCO_HIVEMIND_CREEPBASE_HPP
|
||||
|
||||
#include <Screeps/Creep.hpp>
|
||||
#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:
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
void loop();
|
||||
|
||||
protected:
|
||||
bool placeContainers();
|
||||
void placeContainers();
|
||||
};
|
||||
} // namespace DouwcoHivemind
|
||||
|
||||
|
||||
24
douwco_hivemind/include/Structures/Tower.hpp
Normal file
24
douwco_hivemind/include/Structures/Tower.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef DOUWCO_HIVEMIND_TOWER_HPP
|
||||
#define DOUWCO_HIVEMIND_TOWER_HPP
|
||||
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
|
||||
#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
|
||||
@@ -1,120 +1,122 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#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/StructureStorage.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#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<Screeps::Structure> DouwcoHivemind::Supplier::getEnergyStructureTarget()
|
||||
{
|
||||
auto roomObj = getRoomObjectTarget();
|
||||
if (!roomObj)
|
||||
{
|
||||
searchEnergyStructure();
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<Screeps::Structure>
|
||||
DouwcoHivemind::Supplier::getEnergyStructureTarget() {
|
||||
auto roomObj = getRoomObjectTarget();
|
||||
if (!roomObj) {
|
||||
searchEnergyStructure();
|
||||
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) {
|
||||
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<Screeps::StructureTower *>(structure.get());
|
||||
energyCapacity =
|
||||
tower->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
} else if (structureType == Screeps::STRUCTURE_SPAWN) {
|
||||
auto spawn = dynamic_cast<Screeps::StructureSpawn *>(structure.get());
|
||||
energyCapacity =
|
||||
spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
} else if (structureType == Screeps::STRUCTURE_EXTENSION) {
|
||||
auto extension =
|
||||
dynamic_cast<Screeps::StructureExtension *>(structure.get());
|
||||
energyCapacity =
|
||||
extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
} else if (structureType == Screeps::STRUCTURE_STORAGE) {
|
||||
auto storage = dynamic_cast<Screeps::StructureStorage *>(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<Screeps::Structure *>(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<Screeps::StructureSpawn *>(structure.get());
|
||||
energyCapacity = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
}
|
||||
else if (structureType == Screeps::STRUCTURE_EXTENSION)
|
||||
{
|
||||
auto extension = dynamic_cast<Screeps::StructureExtension *>(structure.get());
|
||||
energyCapacity = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
}
|
||||
else if (structureType == Screeps::STRUCTURE_TOWER)
|
||||
{
|
||||
auto extension = dynamic_cast<Screeps::StructureTower *>(structure.get());
|
||||
energyCapacity = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
if (structureType == Screeps::STRUCTURE_TOWER) {
|
||||
auto tower = dynamic_cast<Screeps::StructureTower *>(structure);
|
||||
energyRequired =
|
||||
tower->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
} else if (structureType == Screeps::STRUCTURE_SPAWN) {
|
||||
auto spawn = dynamic_cast<Screeps::StructureSpawn *>(structure);
|
||||
energyRequired =
|
||||
spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
} else if (structureType == Screeps::STRUCTURE_EXTENSION) {
|
||||
auto extension = dynamic_cast<Screeps::StructureExtension *>(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<Screeps::Structure *>(structureObject.get());
|
||||
if (!structure)
|
||||
continue;
|
||||
|
||||
int energyRequired;
|
||||
|
||||
auto structureType = structure->structureType();
|
||||
if (structureType == Screeps::STRUCTURE_SPAWN)
|
||||
{
|
||||
auto spawn = dynamic_cast<Screeps::StructureSpawn *>(structure);
|
||||
energyRequired = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
}
|
||||
else if (structureType == Screeps::STRUCTURE_EXTENSION)
|
||||
{
|
||||
auto extension = dynamic_cast<Screeps::StructureExtension *>(structure);
|
||||
energyRequired = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
}
|
||||
else if (structureType == Screeps::STRUCTURE_TOWER)
|
||||
{
|
||||
auto extension = dynamic_cast<Screeps::StructureTower *>(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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Memory.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <memory>
|
||||
|
||||
#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>(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<Tower>(static_cast<Screeps::StructureTower>(structure.second)));
|
||||
}
|
||||
else if(structureType == Screeps::STRUCTURE_SPAWN){
|
||||
structures.push_back(std::make_unique<Spawn>(static_cast<Screeps::StructureSpawn>(structure.second)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,8 @@
|
||||
#include "Screeps/Structure.hpp"
|
||||
#include "Screeps/StructureContainer.hpp"
|
||||
#include "Screeps/StructureController.hpp"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Constants.hpp"
|
||||
|
||||
DouwcoHivemind::Room::Room(Screeps::Room rm) : room(rm), memory(rm.memory()) {
|
||||
if (memory.contains("sourceContainers"))
|
||||
@@ -29,12 +24,12 @@ DouwcoHivemind::Room::~Room() {
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Room::loop() {
|
||||
if(Screeps::Game.time()%100!=0)return;
|
||||
if (placeContainers())
|
||||
return;
|
||||
// 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;
|
||||
}
|
||||
@@ -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<std::string> 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);
|
||||
}
|
||||
23
douwco_hivemind/src/Structures/Tower.cpp
Normal file
23
douwco_hivemind/src/Structures/Tower.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
#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<Screeps::Creep*>(creepRoomObj.get());
|
||||
int health = creep->hits();
|
||||
if(health<minHits){
|
||||
minHits=health;
|
||||
target = creep;
|
||||
}
|
||||
}
|
||||
tower.attack(*target);
|
||||
}
|
||||
Reference in New Issue
Block a user