Compare commits
10 Commits
6ee67eac47
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 38082e3fc4 | |||
| e484919546 | |||
| e9134357a7 | |||
|
|
1859662e94 | ||
|
|
eea9e7d69f | ||
|
|
0c693354e6 | ||
|
|
40ab8b289a | ||
|
|
67f0afae4c | ||
|
|
cc0de10471 | ||
|
|
98b123ee0d |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
build
|
||||
# Build files
|
||||
build/*
|
||||
dist/*
|
||||
|
||||
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -3,4 +3,4 @@
|
||||
url = git@github.com:emscripten-core/emsdk.git
|
||||
[submodule "screepsxx"]
|
||||
path = screepsxx
|
||||
url = git@github.com:UltraCoderRU/screepsxx.git
|
||||
url = git@github.com:DouweRavers/screepsxx.git
|
||||
113
.vscode/settings.json
vendored
113
.vscode/settings.json
vendored
@@ -1,113 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"__hash_table": "cpp",
|
||||
"__string": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"locale": "cpp",
|
||||
"utility": "cpp",
|
||||
"mutex": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"cassert": "cpp",
|
||||
"vector": "cpp",
|
||||
"optional": "cpp",
|
||||
"*.inc": "cpp",
|
||||
"thread": "cpp",
|
||||
"atomic": "cpp",
|
||||
"__config": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"__tree": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"exception": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stack": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string_view": "cpp",
|
||||
"strstream": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"cerrno": "cpp",
|
||||
"cfloat": "cpp",
|
||||
"climits": "cpp",
|
||||
"concepts": "cpp",
|
||||
"format": "cpp",
|
||||
"numbers": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__locale": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"__sso_allocator": "cpp",
|
||||
"__std_stream": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"csignal": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"source_location": "cpp",
|
||||
"stdfloat": "cpp",
|
||||
"typeindex": "cpp"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(example CXX)
|
||||
project(douwco_hivemind CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
@@ -16,9 +16,9 @@ add_subdirectory(screepsxx)
|
||||
# If you change TARGET_NAME, please, make corresponding changes in main.js.
|
||||
set(TARGET_NAME douwco_hivemind)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/douwco_hivemind/include)
|
||||
|
||||
file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/src/*.cpp)
|
||||
file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/douwco_hivemind/src/*.cpp)
|
||||
add_executable(${TARGET_NAME} ${SRC_FILES})
|
||||
target_link_libraries(${TARGET_NAME} screepsxx)
|
||||
target_link_options(${TARGET_NAME} PUBLIC -sMODULARIZE=1 --no-entry --bind -sEXPORT_ES6=0)
|
||||
|
||||
36
README.md
36
README.md
@@ -1,5 +1,33 @@
|
||||
# screeps
|
||||
My source code for the MMO-programming game: Screeps.
|
||||
# Douwco Hivemind
|
||||
This is the sourcecode of my hivemind implementation for the MMO-programming game Screeps. This is mainly designed to learn programming with C++. This is possible throught the work done in the screepxx project, which I will and try to expand as well.
|
||||
|
||||
# Status
|
||||
As a way to learn c++ programming I used the screepsxx repo for controlling the screeps with c++.
|
||||
# Running the project
|
||||
All commands are run starting from the root directory.
|
||||
|
||||
## Emsdk setup
|
||||
Screeps only supports ES5 js syntax which can only be guaranteed by using emsdk 2.0.0.
|
||||
|
||||
```
|
||||
cd emsdk && \
|
||||
./emsdk install 2.0.0 && \
|
||||
./emsdk activate 2.0.0 && \
|
||||
source ./emsdk_env.sh && \
|
||||
cd ..
|
||||
```
|
||||
|
||||
## Cmake setup
|
||||
Create the makefiles using cmake. For more info look at the readme in screepsxx.
|
||||
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake ..
|
||||
```
|
||||
|
||||
# Build
|
||||
To build the project run the following. In the dist folder the "screeps ready" project is copied.
|
||||
|
||||
```
|
||||
cd build
|
||||
cmake --build .
|
||||
```
|
||||
22
dist/douwco_hivemind_loader.js
vendored
22
dist/douwco_hivemind_loader.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/douwco_hivemind_module.wasm
vendored
BIN
dist/douwco_hivemind_module.wasm
vendored
Binary file not shown.
14
dist/main.js
vendored
14
dist/main.js
vendored
@@ -1,14 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const wasm_loader = require('wasm_loader')
|
||||
|
||||
var mod;
|
||||
wasm_loader('douwco_hivemind_loader', 'douwco_hivemind_module').then((instance) => {
|
||||
console.log("WASM module loaded.");
|
||||
mod = instance;
|
||||
});
|
||||
|
||||
module.exports.loop = function () {
|
||||
if (mod !== undefined)
|
||||
mod.loop();
|
||||
}
|
||||
24
dist/wasm_loader.js
vendored
24
dist/wasm_loader.js
vendored
@@ -1,24 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = ((mod_js, mod_wasm, opts) => {
|
||||
|
||||
const mod_file = require(mod_js);
|
||||
const bin_file = require(mod_wasm);
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
opts.wasmBinary = bin_file;
|
||||
opts.print = opts.print || ((text) => console.log(text));
|
||||
opts.printErr = opts.printErr || ((text) => console.log(`error: ${text}`));
|
||||
opts.onAbort = opts.onAbort || (() => console.log('WASM aborted!!!'));
|
||||
|
||||
// == don't call main()
|
||||
if (typeof opts.noInitialRun === "undefined")
|
||||
opts.noInitialRun = true;
|
||||
|
||||
// == don't terminate after returning from main()
|
||||
if (typeof opts.noExitRuntime === "undefined")
|
||||
opts.noExitRuntime = true;
|
||||
|
||||
return mod_file(opts);
|
||||
});
|
||||
22
douwco_hivemind/include/Creeps/Builder.hpp
Normal file
22
douwco_hivemind/include/Creeps/Builder.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef DOUWCO_HIVEMIND_BUILDER_HPP
|
||||
#define DOUWCO_HIVEMIND_BUILDER_HPP
|
||||
|
||||
#include "Creeps/Worker.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Builder : public Worker
|
||||
{
|
||||
public:
|
||||
Builder(Screeps::Creep creep) : Worker(creep) {}
|
||||
|
||||
protected:
|
||||
void depositEnergy() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Screeps::ConstructionSite> getConstructionSiteTarget();
|
||||
void searchConstructionSite();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_BUILDER_HPP
|
||||
49
douwco_hivemind/include/Creeps/CreepBase.hpp
Normal file
49
douwco_hivemind/include/Creeps/CreepBase.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef DOUWCO_HIVEMIND_CREEPBASE_HPP
|
||||
#define DOUWCO_HIVEMIND_CREEPBASE_HPP
|
||||
|
||||
#include <Screeps/Creep.hpp>
|
||||
|
||||
namespace Screeps{
|
||||
class RoomPosition;
|
||||
class RoomObject;
|
||||
class PathStep;
|
||||
}
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
enum CreepRole
|
||||
{
|
||||
UNEMPLOYED,
|
||||
SUPPLIER,
|
||||
UPGRADER,
|
||||
BUILDER,
|
||||
MAINTAINER
|
||||
};
|
||||
|
||||
class CreepBase
|
||||
{
|
||||
public:
|
||||
CreepRole role;
|
||||
std::string target_id;
|
||||
|
||||
protected:
|
||||
Screeps::Creep creep;
|
||||
JSON memory;
|
||||
|
||||
public:
|
||||
CreepBase(Screeps::Creep crp);
|
||||
virtual ~CreepBase();
|
||||
virtual void loop() {}
|
||||
|
||||
|
||||
|
||||
bool isNearTo(const Screeps::RoomPosition &pos, int dist);
|
||||
|
||||
|
||||
protected:
|
||||
void moveToTarget(int dist = 1);
|
||||
std::unique_ptr<Screeps::RoomObject> getRoomObjectTarget();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_CREEPBASE_HPP
|
||||
22
douwco_hivemind/include/Creeps/Maintainer.hpp
Normal file
22
douwco_hivemind/include/Creeps/Maintainer.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef DOUWCO_HIVEMIND_MAINTAINER_HPP
|
||||
#define DOUWCO_HIVEMIND_MAINTAINER_HPP
|
||||
|
||||
#include "Creeps/Worker.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Maintainer : public Worker
|
||||
{
|
||||
public:
|
||||
Maintainer(Screeps::Creep creep) : Worker(creep) {}
|
||||
|
||||
protected:
|
||||
void depositEnergy() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Screeps::Structure> getDamagedStructureTarget();
|
||||
void searchDamagedStructure();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_MAINTAINER_HPP
|
||||
22
douwco_hivemind/include/Creeps/Supplier.hpp
Normal file
22
douwco_hivemind/include/Creeps/Supplier.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef DOUWCO_HIVEMIND_SUPPLIER_HPP
|
||||
#define DOUWCO_HIVEMIND_SUPPLIER_HPP
|
||||
|
||||
#include "Creeps/Worker.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Supplier : public Worker
|
||||
{
|
||||
public:
|
||||
Supplier(Screeps::Creep creep) : Worker(creep) {}
|
||||
|
||||
protected:
|
||||
void depositEnergy() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Screeps::Structure> getEnergyStructureTarget();
|
||||
void searchEnergyStructure();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_SUPPLIER_HPP
|
||||
18
douwco_hivemind/include/Creeps/Upgrader.hpp
Normal file
18
douwco_hivemind/include/Creeps/Upgrader.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef DOUWCO_HIVEMIND_HARVESTER_UPGRADER_HPP
|
||||
#define DOUWCO_HIVEMIND_HARVESTER_UPGRADER_HPP
|
||||
|
||||
#include "Creeps/Worker.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Upgrader : public Worker
|
||||
{
|
||||
public:
|
||||
Upgrader(Screeps::Creep creep) : Worker(creep) {}
|
||||
|
||||
protected:
|
||||
void depositEnergy() override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_HARVESTER_UPGRADER_HPP
|
||||
29
douwco_hivemind/include/Creeps/Worker.hpp
Normal file
29
douwco_hivemind/include/Creeps/Worker.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef DOUWCO_HIVEMIND_HARVESTER_HPP
|
||||
#define DOUWCO_HIVEMIND_HARVESTER_HPP
|
||||
|
||||
#include "Creeps/CreepBase.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Worker : public CreepBase
|
||||
{
|
||||
private:
|
||||
bool harvesting;
|
||||
|
||||
public:
|
||||
Worker(Screeps::Creep crp);
|
||||
~Worker() override;
|
||||
|
||||
void loop() override;
|
||||
|
||||
protected:
|
||||
virtual void depositEnergy(){}
|
||||
|
||||
private:
|
||||
void harvestSource();
|
||||
std::unique_ptr<Screeps::Source> getSourceTarget();
|
||||
void searchSource();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_HARVESTER_HPP
|
||||
28
douwco_hivemind/include/Engine.hpp
Normal file
28
douwco_hivemind/include/Engine.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef DOUWCO_HIVEMIND_ENGINE_HPP
|
||||
#define DOUWCO_HIVEMIND_ENGINE_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Creeps/CreepBase.hpp"
|
||||
#include "Structures/StructureBase.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Engine
|
||||
{
|
||||
private:
|
||||
std::vector<std::unique_ptr<CreepBase>> creeps;
|
||||
std::vector<std::unique_ptr<StructureBase>> structures;
|
||||
|
||||
public:
|
||||
Engine();
|
||||
void loop();
|
||||
|
||||
private:
|
||||
void ReadOutCreeps();
|
||||
void ReadOutStructures();
|
||||
void clearDeadCreepMemory();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_ENGINE_HPP
|
||||
@@ -3,18 +3,18 @@
|
||||
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
|
||||
#include "Structures/Structure.hpp"
|
||||
#include "Structures/StructureBase.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Spawn : public Structure
|
||||
class Spawn : public StructureBase
|
||||
{
|
||||
private:
|
||||
Screeps::StructureSpawn spawn;
|
||||
|
||||
public:
|
||||
Spawn(Screeps::StructureSpawn spwn) : spawn(spwn),
|
||||
Structure() {}
|
||||
StructureBase() {}
|
||||
~Spawn() {}
|
||||
|
||||
void loop() override;
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Structure
|
||||
class StructureBase
|
||||
{
|
||||
public:
|
||||
virtual void loop(){}
|
||||
33
douwco_hivemind/include/Tools/JsonTool.hpp
Normal file
33
douwco_hivemind/include/Tools/JsonTool.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef DOUWCO_HIVEMIND_JSON_TOOLS_HPP
|
||||
#define DOUWCO_HIVEMIND_JSON_TOOLS_HPP
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> jsonToVector(const nlohmann::json &json)
|
||||
{
|
||||
std::vector<T> vector;
|
||||
for (const auto &item : json)
|
||||
{
|
||||
vector.emplace_back(item.get<T>());
|
||||
}
|
||||
return vector;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
nlohmann::json vectorToJson(const std::vector<T> &vector)
|
||||
{
|
||||
nlohmann::json json;
|
||||
for (const auto &item : vector)
|
||||
{
|
||||
json.emplace_back(item);
|
||||
}
|
||||
return json;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_JSON_TOOLS_HPP
|
||||
19
douwco_hivemind/include/Tools/MeasureTool.hpp
Normal file
19
douwco_hivemind/include/Tools/MeasureTool.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef DOUWCO_HIVEMIND_MEASURE_TOOL_HPP
|
||||
#define DOUWCO_HIVEMIND_MEASURE_TOOL_HPP
|
||||
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
static bool isNearTo(const Screeps::RoomPosition &pos1, const Screeps::RoomPosition &pos2, int dist)
|
||||
{
|
||||
int dx = pos1.x() - pos2.x();
|
||||
int dy = pos1.y() - pos2.y();
|
||||
int dist2 = dist * dist;
|
||||
return dx * dx <= dist2 &&
|
||||
dy * dy <= dist2 &&
|
||||
pos1.roomName() == pos2.roomName();
|
||||
}
|
||||
} // namespace Screeps
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_MEASURE_TOOL_HPP
|
||||
40
douwco_hivemind/include/Tools/PathTool.hpp
Normal file
40
douwco_hivemind/include/Tools/PathTool.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef DOUWCO_HIVEMIND_PATH_TOOL_HPP
|
||||
#define DOUWCO_HIVEMIND_PATH_TOOL_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <Screeps/Room.hpp>
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
static std::vector<int> flattenPathSteps(const std::vector<Screeps::Room::PathStep> &pathSteps)
|
||||
{
|
||||
std::vector<int> flattened;
|
||||
for (const auto &step : pathSteps)
|
||||
{
|
||||
flattened.push_back(step.x);
|
||||
flattened.push_back(step.y);
|
||||
flattened.push_back(step.dx);
|
||||
flattened.push_back(step.dy);
|
||||
flattened.push_back(step.direction);
|
||||
}
|
||||
return flattened;
|
||||
}
|
||||
|
||||
static std::vector<Screeps::Room::PathStep> unflattenPathSteps(const std::vector<int> &flattened)
|
||||
{
|
||||
std::vector<Screeps::Room::PathStep> pathSteps;
|
||||
for (size_t i = 0; i < flattened.size(); i += 5)
|
||||
{
|
||||
Screeps::Room::PathStep step;
|
||||
step.x = flattened[i];
|
||||
step.y = flattened[i+1];
|
||||
step.dx = flattened[i+2];
|
||||
step.dy = flattened[i+3];
|
||||
step.direction = flattened[i+4];
|
||||
pathSteps.emplace_back(step);
|
||||
}
|
||||
return pathSteps;
|
||||
}
|
||||
} // namespace Screeps
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_PATH_TOOL_HPP
|
||||
83
douwco_hivemind/src/Builder.cpp
Normal file
83
douwco_hivemind/src/Builder.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include <Screeps/Source.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
#include <Screeps/RoomObject.hpp>
|
||||
#include <Screeps/Structure.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <Screeps/StructureExtension.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Constants.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#include <Screeps/ConstructionSite.hpp>
|
||||
|
||||
#include "Creeps/Builder.hpp"
|
||||
|
||||
void DouwcoHivemind::Builder::depositEnergy()
|
||||
{
|
||||
auto constructionSite = getConstructionSiteTarget();
|
||||
if (!constructionSite)
|
||||
return;
|
||||
|
||||
if (isNearTo(constructionSite->pos(), 1))
|
||||
{
|
||||
int resp = creep.build(*constructionSite);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Screeps::ConstructionSite> DouwcoHivemind::Builder::getConstructionSiteTarget()
|
||||
{
|
||||
auto roomObj = getRoomObjectTarget();
|
||||
if (!roomObj)
|
||||
{
|
||||
searchConstructionSite();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto constructionSite = std::unique_ptr<Screeps::ConstructionSite>(dynamic_cast<Screeps::ConstructionSite *>(roomObj.release()));
|
||||
if (!constructionSite)
|
||||
{
|
||||
searchConstructionSite();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(constructionSite);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Builder::searchConstructionSite()
|
||||
{
|
||||
int leastProgressLeft = INT16_MAX;
|
||||
Screeps::ConstructionSite *selectedConstructionSite;
|
||||
auto constructionSites = creep.room().find(Screeps::FIND_MY_CONSTRUCTION_SITES);
|
||||
for (auto &constructionSiteObject : constructionSites)
|
||||
{
|
||||
auto constructionSite = dynamic_cast<Screeps::ConstructionSite *>(constructionSiteObject.get());
|
||||
if (!constructionSite)
|
||||
continue;
|
||||
|
||||
int progressLeft = constructionSite->progressTotal() - constructionSite->progress();
|
||||
|
||||
if(constructionSite->structureType() == Screeps::STRUCTURE_ROAD) progressLeft *= 100;
|
||||
if (progressLeft < leastProgressLeft)
|
||||
{
|
||||
leastProgressLeft = progressLeft;
|
||||
selectedConstructionSite = constructionSite;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedConstructionSite)
|
||||
target_id = selectedConstructionSite->id();
|
||||
else
|
||||
target_id.clear();
|
||||
}
|
||||
143
douwco_hivemind/src/CreepBase.cpp
Normal file
143
douwco_hivemind/src/CreepBase.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
|
||||
#include "Creeps/CreepBase.hpp"
|
||||
|
||||
#include "Tools/JsonTool.hpp"
|
||||
#include "Tools/PathTool.hpp"
|
||||
#include "Tools/MeasureTool.hpp"
|
||||
|
||||
DouwcoHivemind::CreepBase::CreepBase(Screeps::Creep crp) : creep(crp),
|
||||
memory(crp.memory())
|
||||
{
|
||||
role = memory.contains("role") ? static_cast<CreepRole>(memory["role"]) : CreepRole::UNEMPLOYED;
|
||||
target_id = memory.contains("target_id") ? static_cast<std::string>(memory["target_id"]) : std::string();
|
||||
}
|
||||
|
||||
DouwcoHivemind::CreepBase::~CreepBase()
|
||||
{
|
||||
memory["target_id"] = target_id;
|
||||
creep.setMemory(memory);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::CreepBase::moveToTarget(int dist)
|
||||
{
|
||||
// Is move required?
|
||||
auto target = getRoomObjectTarget();
|
||||
if (isNearTo(target->pos(), dist))
|
||||
{
|
||||
memory.erase("path");
|
||||
return;
|
||||
}
|
||||
|
||||
// Is wating?
|
||||
if (memory.contains("wait") && memory["wait"] > 0)
|
||||
{
|
||||
memory["wait"] = memory["wait"].get<int>() - 1;
|
||||
creep.say("Waiting..");
|
||||
return;
|
||||
}
|
||||
|
||||
// Is there a path to walk?
|
||||
if (!memory.contains("path") || memory["path"].empty())
|
||||
{
|
||||
creep.say("Searching route!");
|
||||
auto target_pos = target->pos();
|
||||
auto path = creep.room().findPath(creep.pos(), target_pos);
|
||||
auto last = path.back();
|
||||
if (last.x - target_pos.x() > dist || last.y - target_pos.y() > dist)
|
||||
{
|
||||
creep.say("No possible path");
|
||||
memory["wait"] = rand() % 20;
|
||||
return;
|
||||
}
|
||||
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)
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
pathStepData[i] = memory["path"][i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memory.erase("path");
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the move of last tick executed?
|
||||
int x = creep.pos().x();
|
||||
int y = creep.pos().y();
|
||||
|
||||
Screeps::Room::PathStep step;
|
||||
step.x = pathStepData[0];
|
||||
step.y = pathStepData[1];
|
||||
step.dx = pathStepData[2];
|
||||
step.dy = pathStepData[3];
|
||||
step.direction = pathStepData[4];
|
||||
|
||||
if (memory.contains("last_pos"))
|
||||
{
|
||||
int last_x = memory["last_pos"]["x"];
|
||||
int last_y = memory["last_pos"]["y"];
|
||||
memory.erase("last_pos");
|
||||
if (x == last_x && y == last_y)
|
||||
{
|
||||
creep.say("I'm stuck!");
|
||||
memory["wait"] = rand() % 5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Is the creep on the place intended by the path?
|
||||
if (!(x == step.x - step.dx && y == step.y - step.dy))
|
||||
{
|
||||
creep.say("I'm lost!");
|
||||
memory["wait"] = rand() % 5;
|
||||
memory.erase("path");
|
||||
return;
|
||||
}
|
||||
|
||||
// Lets move forward
|
||||
int resp = creep.move(step.direction);
|
||||
if (resp == Screeps::OK)
|
||||
{
|
||||
memory["last_pos"]["x"] = x;
|
||||
memory["last_pos"]["y"] = y;
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
memory["path"].erase(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Screeps::RoomObject> DouwcoHivemind::CreepBase::getRoomObjectTarget()
|
||||
{
|
||||
// Check if game can find target
|
||||
auto roomObj = Screeps::Game.getObjectById(target_id);
|
||||
if (!roomObj)
|
||||
{
|
||||
JS::console.log(creep.name() + ": Game can\'t find target id");
|
||||
return nullptr;
|
||||
}
|
||||
return std::move(roomObj);
|
||||
}
|
||||
|
||||
bool DouwcoHivemind::CreepBase::isNearTo(const Screeps::RoomPosition &pos, int dist)
|
||||
{
|
||||
return DouwcoHivemind::isNearTo(creep.pos(), pos, dist);
|
||||
}
|
||||
88
douwco_hivemind/src/Engine.cpp
Normal file
88
douwco_hivemind/src/Engine.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Memory.hpp>
|
||||
|
||||
#include "Engine.hpp"
|
||||
|
||||
#include "Creeps/Supplier.hpp"
|
||||
#include "Creeps/Upgrader.hpp"
|
||||
#include "Creeps/Builder.hpp"
|
||||
#include "Creeps/Maintainer.hpp"
|
||||
|
||||
#include "Structures/Spawn.hpp"
|
||||
|
||||
DouwcoHivemind::Engine::Engine()
|
||||
{
|
||||
ReadOutCreeps();
|
||||
ReadOutStructures();
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Engine::loop()
|
||||
{
|
||||
JS::console.log(std::string("Iterating over creeps"));
|
||||
for (auto &creep : creeps)
|
||||
creep->loop();
|
||||
|
||||
JS::console.log(std::string("Iterating over structures"));
|
||||
for (auto &structure : structures)
|
||||
structure->loop();
|
||||
|
||||
if (Screeps::Game.time() % 1000 == 0)
|
||||
{
|
||||
clearDeadCreepMemory();
|
||||
}
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Engine::ReadOutCreeps()
|
||||
{
|
||||
JS::console.log(std::string("Reading out creeps"));
|
||||
auto src_creeps = Screeps::Game.creeps();
|
||||
for (auto &creep : src_creeps)
|
||||
{
|
||||
CreepRole role = creep.second.memory()["role"];
|
||||
if (role == CreepRole::SUPPLIER)
|
||||
creeps.push_back(std::make_unique<Supplier>(creep.second));
|
||||
else if (role == CreepRole::UPGRADER)
|
||||
creeps.push_back(std::make_unique<Upgrader>(creep.second));
|
||||
else if (role == CreepRole::BUILDER)
|
||||
creeps.push_back(std::make_unique<Builder>(creep.second));
|
||||
else if (role == CreepRole::MAINTAINER)
|
||||
creeps.push_back(std::make_unique<Maintainer>(creep.second));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (!containsname)
|
||||
creepMemory.erase(name);
|
||||
}
|
||||
Screeps::Memory.set("creeps", creepMemory);
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Engine.hpp"
|
||||
#include "Structures/Spawn.hpp"
|
||||
|
||||
89
douwco_hivemind/src/Maintainer.cpp
Normal file
89
douwco_hivemind/src/Maintainer.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include <Screeps/Source.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
#include <Screeps/RoomObject.hpp>
|
||||
#include <Screeps/Structure.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <Screeps/StructureExtension.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#include "Creeps/Maintainer.hpp"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 lowestMaintaince = INT16_MAX;
|
||||
Screeps::Structure *selectedStructure;
|
||||
auto structures = creep.room().find(Screeps::FIND_STRUCTURES);
|
||||
for (auto &structureObject : structures)
|
||||
{
|
||||
auto structure = dynamic_cast<Screeps::Structure *>(structureObject.get());
|
||||
if (!structure)
|
||||
continue;
|
||||
|
||||
int maintance = structure->hits();
|
||||
auto structureType = structure->structureType();
|
||||
if (structureType == Screeps::STRUCTURE_CONTROLLER)
|
||||
continue;
|
||||
if (maintance < lowestMaintaince)
|
||||
{
|
||||
lowestMaintaince = maintance;
|
||||
selectedStructure = structure;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedStructure)
|
||||
target_id = selectedStructure->id();
|
||||
else
|
||||
target_id.clear();
|
||||
}
|
||||
74
douwco_hivemind/src/Spawn.cpp
Normal file
74
douwco_hivemind/src/Spawn.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
|
||||
#include "Creeps/CreepBase.hpp"
|
||||
#include "Structures/Spawn.hpp"
|
||||
|
||||
void DouwcoHivemind::Spawn::loop()
|
||||
{
|
||||
// Only run every 50 ticks
|
||||
if (Screeps::Game.time() % 50 != 0)
|
||||
return;
|
||||
|
||||
int energyAvailable = spawn.room().energyAvailable();
|
||||
int energyCapacityAvailable = spawn.room().energyCapacityAvailable();
|
||||
|
||||
int required_upgraders = 1;
|
||||
int required_suppliers = 1;
|
||||
int required_maintainers = spawn.room().find(Screeps::FIND_MY_STRUCTURES).size() <= 2 ? 0 : 1;;
|
||||
int required_builders = spawn.room().find(Screeps::FIND_MY_CONSTRUCTION_SITES).size() == 0 ? 0 : 1;
|
||||
|
||||
for (auto &creep : Screeps::Game.creeps())
|
||||
{
|
||||
CreepRole role = creep.second.memory()["role"];
|
||||
|
||||
if (role == CreepRole::SUPPLIER)
|
||||
required_suppliers--;
|
||||
else if (role == CreepRole::UPGRADER)
|
||||
required_upgraders--;
|
||||
else if (role == CreepRole::MAINTAINER)
|
||||
required_maintainers--;
|
||||
else if (role == CreepRole::BUILDER)
|
||||
required_builders--;
|
||||
}
|
||||
|
||||
if (energyAvailable < energyCapacityAvailable && required_suppliers < 2)
|
||||
return;
|
||||
std::string name;
|
||||
JSON opts;
|
||||
if (required_suppliers > 0)
|
||||
{
|
||||
opts["memory"]["role"] = CreepRole::SUPPLIER;
|
||||
name = "Supplier: ";
|
||||
}
|
||||
else if (required_upgraders > 0)
|
||||
{
|
||||
opts["memory"]["role"] = CreepRole::UPGRADER;
|
||||
name = "Upgrader: ";
|
||||
}
|
||||
else if (required_builders > 0)
|
||||
{
|
||||
opts["memory"]["role"] = CreepRole::BUILDER;
|
||||
name = "Builder: ";
|
||||
}
|
||||
else if (required_maintainers > 0)
|
||||
{
|
||||
opts["memory"]["role"] = CreepRole::MAINTAINER;
|
||||
name = "Maintainer: ";
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
std::vector<std::string> body;
|
||||
for (int i = 0; i < energyAvailable / 200; i++)
|
||||
{
|
||||
body.push_back("work");
|
||||
body.push_back("carry");
|
||||
body.push_back("move");
|
||||
}
|
||||
|
||||
spawn.spawnCreep(
|
||||
body,
|
||||
name + std::to_string(Screeps::Game.time()),
|
||||
opts);
|
||||
}
|
||||
121
douwco_hivemind/src/Supplier.cpp
Normal file
121
douwco_hivemind/src/Supplier.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include <Screeps/Source.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
#include <Screeps/RoomObject.hpp>
|
||||
#include <Screeps/Structure.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <Screeps/StructureExtension.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#include "Creeps/Supplier.hpp"
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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()));
|
||||
if (!structure)
|
||||
{
|
||||
searchEnergyStructure();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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 (energyCapacity == 0)
|
||||
{
|
||||
searchEnergyStructure();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
33
douwco_hivemind/src/Upgrader.cpp
Normal file
33
douwco_hivemind/src/Upgrader.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include <Screeps/Source.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
#include <Screeps/RoomObject.hpp>
|
||||
#include <Screeps/Structure.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <Screeps/StructureExtension.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Constants.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#include "Creeps/Upgrader.hpp"
|
||||
|
||||
void DouwcoHivemind::Upgrader::depositEnergy()
|
||||
{
|
||||
auto controller = creep.room().controller().value();
|
||||
target_id = controller.id();
|
||||
if (isNearTo(controller.pos(), 3))
|
||||
{
|
||||
int resp = creep.upgradeController(controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveToTarget();
|
||||
}
|
||||
}
|
||||
123
douwco_hivemind/src/Worker.cpp
Normal file
123
douwco_hivemind/src/Worker.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include <Screeps/Source.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
#include <Screeps/RoomObject.hpp>
|
||||
#include <Screeps/Structure.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <Screeps/StructureExtension.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Constants.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#include "Creeps/Worker.hpp"
|
||||
|
||||
DouwcoHivemind::Worker::Worker(Screeps::Creep crp) : CreepBase(crp)
|
||||
{
|
||||
harvesting = memory.contains("harvesting") ? static_cast<bool>(memory["harvesting"]) : false;
|
||||
}
|
||||
|
||||
DouwcoHivemind::Worker::~Worker()
|
||||
{
|
||||
memory["harvesting"] = harvesting;
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Worker::loop()
|
||||
{
|
||||
if (harvesting)
|
||||
{
|
||||
if (creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0)
|
||||
{
|
||||
harvesting = false;
|
||||
target_id.clear();
|
||||
}
|
||||
harvestSource();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (creep.store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0)
|
||||
{
|
||||
harvesting = true;
|
||||
target_id.clear();
|
||||
}
|
||||
depositEnergy();
|
||||
}
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Worker::harvestSource()
|
||||
{
|
||||
auto source = getSourceTarget();
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
if (isNearTo(source->pos(), 1))
|
||||
{
|
||||
int resp = creep.harvest(*source);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Screeps::Source> DouwcoHivemind::Worker::getSourceTarget()
|
||||
{
|
||||
auto roomObj = getRoomObjectTarget();
|
||||
if (!roomObj)
|
||||
{
|
||||
searchSource();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if found roomobject is an actual source
|
||||
auto source = std::unique_ptr<Screeps::Source>(dynamic_cast<Screeps::Source *>(roomObj.release()));
|
||||
if (!source)
|
||||
{
|
||||
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')}, creep.name().c_str());
|
||||
searchSource();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if the source still has energy to harvest
|
||||
if (source->energy() == 0)
|
||||
{
|
||||
searchSource();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(source);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::Worker::searchSource()
|
||||
{
|
||||
target_id.clear();
|
||||
|
||||
auto sources = creep.room().find(Screeps::FIND_SOURCES_ACTIVE);
|
||||
if (sources.size() == 0)
|
||||
return;
|
||||
|
||||
int x = creep.pos().x();
|
||||
int y = creep.pos().y();
|
||||
|
||||
int closestDistance = INT16_MAX;
|
||||
Screeps::Source *selectedSource;
|
||||
for(auto &sourceObject : sources){
|
||||
auto source =dynamic_cast<Screeps::Source *>(sourceObject.get());
|
||||
if(source->energy()==0) continue;
|
||||
int dx = source->pos().x() - x;
|
||||
int dy = source->pos().y() - y;
|
||||
int distance = dx*dx + dy*dy;
|
||||
if(distance < closestDistance){
|
||||
closestDistance = distance;
|
||||
selectedSource = source;
|
||||
}
|
||||
}
|
||||
if(!selectedSource) return;
|
||||
target_id = selectedSource->id();
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef DOUWCO_HIVEMIND_CONSTANTS_HPP
|
||||
#define DOUWCO_HIVEMIND_CONSTANTS_HPP
|
||||
|
||||
namespace DouwcoHivemind{
|
||||
|
||||
enum CreepRole{ UNEMPLOYED, HARVESTER };
|
||||
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_CONSTANTS_HPP
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef DOUWCO_HIVEMIND_CREEP_HPP
|
||||
#define DOUWCO_HIVEMIND_CREEP_HPP
|
||||
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include "Constants.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Creep
|
||||
{
|
||||
public:
|
||||
CreepRole role;
|
||||
|
||||
protected:
|
||||
Screeps::Creep creep;
|
||||
JSON memory;
|
||||
|
||||
public:
|
||||
Creep(Screeps::Creep crp) : creep(crp),
|
||||
memory(crp.memory())
|
||||
{
|
||||
role = memory.contains("role") ? static_cast<CreepRole>(memory["role"]) : CreepRole::UNEMPLOYED;
|
||||
}
|
||||
|
||||
virtual ~Creep() {
|
||||
creep.setMemory(memory);
|
||||
}
|
||||
|
||||
virtual void loop() {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_CREEP_HPP
|
||||
@@ -1,47 +0,0 @@
|
||||
#ifndef DOUWCO_HIVEMIND_HARVESTER_HPP
|
||||
#define DOUWCO_HIVEMIND_HARVESTER_HPP
|
||||
|
||||
#include <Screeps/Creep.hpp>
|
||||
|
||||
#include "Creeps/Creep.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class HarvesterRole : public Creep
|
||||
{
|
||||
private:
|
||||
bool harvesting;
|
||||
std::string target_id;
|
||||
int taskCounter;
|
||||
|
||||
public:
|
||||
HarvesterRole(Screeps::Creep crp) : Creep(crp)
|
||||
{
|
||||
harvesting = memory.contains("harvesting") ? static_cast<bool>(memory["harvesting"]) : false;
|
||||
target_id = memory.contains("target_id") ? static_cast<std::string>(memory["target_id"]) : std::string();
|
||||
taskCounter = memory.contains("taskCounter") ? static_cast<int>(memory["taskCounter"]) : 0;
|
||||
}
|
||||
|
||||
~HarvesterRole() override
|
||||
{
|
||||
memory["harvesting"] = harvesting;
|
||||
memory["target_id"] = target_id;
|
||||
memory["taskCounter"] = taskCounter;
|
||||
}
|
||||
|
||||
void loop() override;
|
||||
|
||||
private:
|
||||
void harvestSource();
|
||||
std::unique_ptr<Screeps::Source> getSourceTarget();
|
||||
void searchSource();
|
||||
|
||||
void depositEnergy();
|
||||
std::unique_ptr<Screeps::Structure> getDepositTarget();
|
||||
void searchDeposit();
|
||||
|
||||
std::unique_ptr<Screeps::RoomObject> getRoomObjectTarget();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_HARVESTER_HPP
|
||||
@@ -1,74 +0,0 @@
|
||||
#ifndef DOUWCO_HIVEMIND_ENGINE_HPP
|
||||
#define DOUWCO_HIVEMIND_ENGINE_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <Screeps/JS.hpp>
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Creeps/Creep.hpp"
|
||||
#include "Creeps/Harvester.hpp"
|
||||
#include "Structures/Structure.hpp"
|
||||
#include "Structures/Spawn.hpp"
|
||||
|
||||
namespace DouwcoHivemind
|
||||
{
|
||||
class Creep;
|
||||
class Structure;
|
||||
|
||||
class Engine
|
||||
{
|
||||
private:
|
||||
std::vector<std::unique_ptr<Creep>> creeps;
|
||||
std::vector<std::unique_ptr<Structure>> structures;
|
||||
|
||||
public:
|
||||
Engine()
|
||||
{
|
||||
ReadOutCreeps();
|
||||
ReadOutStructures();
|
||||
}
|
||||
~Engine() {}
|
||||
|
||||
void loop()
|
||||
{
|
||||
for (auto &creep : creeps)
|
||||
creep->loop();
|
||||
|
||||
for (auto &structure : structures)
|
||||
structure->loop();
|
||||
}
|
||||
|
||||
private:
|
||||
void ReadOutCreeps()
|
||||
{
|
||||
auto src_creeps = Screeps::Game.creeps();
|
||||
for (auto &creep : src_creeps)
|
||||
{
|
||||
CreepRole role = creep.second.memory()["role"];
|
||||
switch (role)
|
||||
{
|
||||
case CreepRole::HARVESTER:
|
||||
creeps.push_back(std::make_unique<HarvesterRole>(creep.second));
|
||||
break;
|
||||
case CreepRole::UNEMPLOYED:
|
||||
default:
|
||||
EM_ASM({console.log('Undefined role for creep' + $0)}, creep.first.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOutStructures()
|
||||
{
|
||||
auto spawns = Screeps::Game.spawns();
|
||||
for (auto &spawn : spawns)
|
||||
{
|
||||
structures.push_back(std::make_unique<Spawn>(spawn.second));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DOUWCO_HIVEMIND_ENGINE_HPP
|
||||
@@ -1,15 +0,0 @@
|
||||
# Emsdk
|
||||
Use emsdk 2.0.0 to only use ES5 syntax for js.
|
||||
|
||||
cd emsdk && \
|
||||
./emsdk install 2.0.0 && \
|
||||
./emsdk activate 2.0.0 && \
|
||||
source ./emsdk_env.sh && \
|
||||
cd ..
|
||||
|
||||
# Cmake
|
||||
In screeps project run dit om cmake setup in te stellen:
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake ..
|
||||
|
||||
Run dit om de code te compilen:
|
||||
cmake --build .
|
||||
Submodule screepsxx updated: 8500506e1c...3567060bf5
@@ -1,255 +0,0 @@
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Creep.hpp>
|
||||
#include <Screeps/Source.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/RoomPosition.hpp>
|
||||
#include <Screeps/RoomObject.hpp>
|
||||
#include <Screeps/Structure.hpp>
|
||||
#include <Screeps/StructureController.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <Screeps/StructureExtension.hpp>
|
||||
#include <Screeps/StructureTower.hpp>
|
||||
#include <Screeps/Constants.hpp>
|
||||
#include <Screeps/Store.hpp>
|
||||
|
||||
#include "Creeps/Harvester.hpp"
|
||||
|
||||
bool isNearTo(const Screeps::RoomPosition &pos1, const Screeps::RoomPosition &pos2, int dist);
|
||||
|
||||
void DouwcoHivemind::HarvesterRole::loop()
|
||||
{
|
||||
if (harvesting)
|
||||
{
|
||||
if (creep.store().getFreeCapacity(Screeps::RESOURCE_ENERGY) == 0)
|
||||
{
|
||||
harvesting = false;
|
||||
target_id.clear();
|
||||
}
|
||||
harvestSource();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (creep.store().getUsedCapacity(Screeps::RESOURCE_ENERGY) == 0)
|
||||
{
|
||||
harvesting = true;
|
||||
target_id.clear();
|
||||
}
|
||||
depositEnergy();
|
||||
}
|
||||
}
|
||||
|
||||
void DouwcoHivemind::HarvesterRole::harvestSource()
|
||||
{
|
||||
auto source = getSourceTarget();
|
||||
if (!source)
|
||||
return;
|
||||
|
||||
if (isNearTo(creep.pos(), source->pos(), 1))
|
||||
{
|
||||
int resp = creep.harvest(*source);
|
||||
}
|
||||
else
|
||||
creep.moveTo(*source);
|
||||
}
|
||||
|
||||
std::unique_ptr<Screeps::Source> DouwcoHivemind::HarvesterRole::getSourceTarget()
|
||||
{
|
||||
auto roomObj = getRoomObjectTarget();
|
||||
if (!roomObj)
|
||||
{
|
||||
searchSource();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if found roomobject is an actual source
|
||||
auto source = std::unique_ptr<Screeps::Source>(dynamic_cast<Screeps::Source *>(roomObj.release()));
|
||||
if (!source)
|
||||
{
|
||||
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')}, creep.name().c_str());
|
||||
searchSource();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if the source still has energy to harvest
|
||||
if (source->energy() == 0)
|
||||
{
|
||||
searchSource();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(source);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::HarvesterRole::searchSource()
|
||||
{
|
||||
target_id.clear();
|
||||
|
||||
auto sources = creep.room().find(Screeps::FIND_SOURCES_ACTIVE);
|
||||
if (sources.size() == 0)
|
||||
return;
|
||||
|
||||
Screeps::Source *selectedSource;
|
||||
int maxEnergy = 0;
|
||||
for (auto &sourceObj : sources)
|
||||
{
|
||||
auto source = dynamic_cast<Screeps::Source *>(sourceObj.get());
|
||||
if (!source)
|
||||
continue;
|
||||
|
||||
auto sourceEnergy = source->energy();
|
||||
if (sourceEnergy > maxEnergy)
|
||||
{
|
||||
maxEnergy = sourceEnergy;
|
||||
selectedSource = source;
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedSource)
|
||||
{
|
||||
// EM_ASM({console.log($0 + ': No sources with energy found!')}, creep.name().c_str());
|
||||
return;
|
||||
}
|
||||
target_id = selectedSource->id();
|
||||
}
|
||||
|
||||
void DouwcoHivemind::HarvesterRole::depositEnergy()
|
||||
{
|
||||
auto structure = getDepositTarget();
|
||||
if (!structure)
|
||||
return;
|
||||
|
||||
if (structure->structureType() == Screeps::STRUCTURE_CONTROLLER)
|
||||
{
|
||||
if (isNearTo(creep.pos(), structure->pos(), 3))
|
||||
{
|
||||
auto controller = dynamic_cast<Screeps::StructureController *>(structure.get());
|
||||
if (!controller)
|
||||
return;
|
||||
int resp = creep.upgradeController(*controller);
|
||||
}
|
||||
else
|
||||
creep.moveTo(*structure);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isNearTo(creep.pos(), structure->pos(), 1))
|
||||
{
|
||||
int resp = creep.transfer(*structure, Screeps::RESOURCE_ENERGY);
|
||||
}
|
||||
else
|
||||
creep.moveTo(*structure);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Screeps::Structure> DouwcoHivemind::HarvesterRole::getDepositTarget()
|
||||
{
|
||||
auto roomObj = getRoomObjectTarget();
|
||||
if (!roomObj)
|
||||
{
|
||||
searchDeposit();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if found roomobject is an actual structure
|
||||
auto structure = std::unique_ptr<Screeps::Structure>(dynamic_cast<Screeps::Structure *>(roomObj.release()));
|
||||
if (!structure)
|
||||
{
|
||||
// EM_ASM({console.log($0 + ': Can\'t cast target to Source')}, creep.name().c_str());
|
||||
searchDeposit();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check if the structure can receive energy to harvest
|
||||
int energyCapacity;
|
||||
auto structureType = structure->structureType();
|
||||
if (structureType == Screeps::STRUCTURE_CONTROLLER)
|
||||
{
|
||||
energyCapacity = 1;
|
||||
}
|
||||
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();
|
||||
}
|
||||
if (energyCapacity == 0)
|
||||
{
|
||||
searchDeposit();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(structure);
|
||||
}
|
||||
|
||||
void DouwcoHivemind::HarvesterRole::searchDeposit()
|
||||
{
|
||||
int highestEnergyNeed = 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 energyNeed;
|
||||
|
||||
auto structureType = structure->structureType();
|
||||
if (structureType == Screeps::STRUCTURE_SPAWN)
|
||||
{
|
||||
auto spawn = dynamic_cast<Screeps::StructureSpawn *>(structure);
|
||||
energyNeed = spawn->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
}
|
||||
else if (structureType == Screeps::STRUCTURE_EXTENSION)
|
||||
{
|
||||
auto extension = dynamic_cast<Screeps::StructureExtension *>(structure);
|
||||
energyNeed = extension->store().getFreeCapacity(Screeps::RESOURCE_ENERGY).value();
|
||||
}
|
||||
else if (structureType == Screeps::STRUCTURE_CONTROLLER)
|
||||
{
|
||||
energyNeed = 1;
|
||||
}
|
||||
|
||||
if (energyNeed > highestEnergyNeed)
|
||||
{
|
||||
highestEnergyNeed = energyNeed;
|
||||
selectedStructure = structure;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedStructure)
|
||||
target_id = selectedStructure->id();
|
||||
else
|
||||
target_id.clear();
|
||||
}
|
||||
|
||||
std::unique_ptr<Screeps::RoomObject> DouwcoHivemind::HarvesterRole::getRoomObjectTarget()
|
||||
{
|
||||
// Check if game can find target
|
||||
auto roomObj = Screeps::Game.getObjectById(target_id);
|
||||
if (!roomObj)
|
||||
{
|
||||
JS::console.log(creep.name() + ": Game can\'t find target id");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(roomObj);
|
||||
}
|
||||
|
||||
bool isNearTo(const Screeps::RoomPosition &pos1, const Screeps::RoomPosition &pos2, int dist)
|
||||
{
|
||||
int dx = pos1.x() - pos2.x();
|
||||
int dy = pos1.y() - pos2.y();
|
||||
int dist2 = dist * dist;
|
||||
return dx * dx <= dist2 &&
|
||||
dy * dy <= dist2 &&
|
||||
pos1.roomName() == pos2.roomName();
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <Screeps/JS.hpp>
|
||||
#include <Screeps/Game.hpp>
|
||||
#include <Screeps/Room.hpp>
|
||||
#include <Screeps/StructureSpawn.hpp>
|
||||
#include <emscripten.h>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "Structures/Spawn.hpp"
|
||||
|
||||
void DouwcoHivemind::Spawn::loop()
|
||||
{
|
||||
int creepcount = spawn.room().find(Screeps::FIND_MY_CREEPS).size();
|
||||
if (creepcount > 10)
|
||||
{
|
||||
EM_ASM({ console.log('To much creeps in this room'); });
|
||||
return;
|
||||
}
|
||||
EM_ASM({ console.log('Creating a harvester'); });
|
||||
|
||||
JSON opts;
|
||||
opts["memory"]["role"] = CreepRole::HARVESTER;
|
||||
|
||||
int resp = spawn.spawnCreep(
|
||||
{"work", "carry", "move"},
|
||||
"harvester" + std::to_string(Screeps::Game.time()),
|
||||
opts);
|
||||
}
|
||||
Reference in New Issue
Block a user