From 732e8270b904bad4307e11fdac7607628051f05d Mon Sep 17 00:00:00 2001 From: Peery Date: Thu, 6 Oct 2022 01:28:25 +0200 Subject: [PATCH] Restructured SetupOverlord; Tuned down logging Changed the SetupOverlord to wotk with a state machine and added a todo_list property to keep track of its requirements and other utility that needs to be remembered. Also tuned down the logging to only log thrown errors or new decisions instead of all the constant noise. --- src/creeps/harvester.js | 4 +-- src/hivemind/hivemind.js | 12 +++---- src/overlords/overlord.js | 16 +++++++-- src/overlords/setup_overlord.js | 64 +++++++++++++++++++++++++++++---- 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/src/creeps/harvester.js b/src/creeps/harvester.js index 4a569ab..8dc470d 100644 --- a/src/creeps/harvester.js +++ b/src/creeps/harvester.js @@ -72,7 +72,7 @@ var roleHarvester = { return } - console.log("roleHarvester ["+creep.name+"]: run() " + creep + " id:", creep.id); + //console.log("roleHarvester ["+creep.name+"]: run() " + creep + " id:", creep.id); // TODO implement state machine here about what the harvester is up to. Currently it only moves to the nearest source. switch (creep.memory.state) { @@ -106,7 +106,7 @@ var roleHarvester = { */ switch_state: function(creep, state) { console.log("roleHarvester ["+creep.name+"]: Changing state to "+state); - console.log(creep, creep.memory); + //console.log(creep, creep.memory); creep.memory.state = state }, diff --git a/src/hivemind/hivemind.js b/src/hivemind/hivemind.js index 5b98671..ad8df40 100644 --- a/src/hivemind/hivemind.js +++ b/src/hivemind/hivemind.js @@ -14,13 +14,13 @@ var hivemind = { hivemind.initialize_memory(); } else { - console.log("Hivemind: Loading all overlords ..."); + //console.log("Hivemind: Loading all overlords ..."); hivemind.deserialize_overlords(); - console.log("Hivemind: Advancing state ..."); + //console.log("Hivemind: Advancing state ..."); hivemind.advance_state(); - console.log("Hivemind: Saving all overlords ..."); + //console.log("Hivemind: Saving all overlords ..."); hivemind.serialize_overlords(); } }, @@ -37,7 +37,7 @@ var hivemind = { init_overlord.add_spawn(curr_spawn_name); } - console.log("Hivemind: Saving all overlords ..."); + //console.log("Hivemind: Saving all overlords ..."); this.serialize_overlords(); }, @@ -90,14 +90,14 @@ var hivemind = { } for (let overlord of this.overlords) { - console.log("Hivemind: Running overlord \""+overlord.id+"\" now ..."); + //console.log("Hivemind: Running overlord \""+overlord.id+"\" now ..."); overlord.run(); } for (let name in Game.creeps) { let creep = Game.creeps[name]; let creep_role = creep.memory.role - console.log("Hivemind: Running creep \""+name+"|"+creep_role+"\""); + //console.log("Hivemind: Running creep \""+name+"|"+creep_role+"\""); let role = _.filter(roles, function(node) {return node.ident === creep_role})[0]; role.obj.run(creep); diff --git a/src/overlords/overlord.js b/src/overlords/overlord.js index a8e82ca..b857fc2 100644 --- a/src/overlords/overlord.js +++ b/src/overlords/overlord.js @@ -8,30 +8,40 @@ function overlord (name) { this.id = name; /** Goal the overlord follows */ - this.goal = undefined; + this.goal = null; // variable containing constant for overlord goal identification + this.todo_list = null; // utility obj containing todos and notes of the overlord + this.state = null; // variable for state machine of the overlord this.underlings = { "spawns": [], // list of spawn names "creeps": [], // list of creep names (NOT ids!) This is because creeps have no ID while being spawned. }; + this.get_memory = function() { + return Memory.overlords[this.id]; + } + /** Serializes the overlord state so that it can survive in memory */ this.serialize = function() { var data = { "id": this.id, "goal": this.goal, "underlings": this.underlings, + "state": this.state, + "todo": this.todo, }; Memory.overlords[this.id] = data; - console.log("Overlord: Wrote overlord "+this.id+" to memory!"); + //console.log("Overlord: Wrote overlord "+this.id+" to memory!"); }; /** Reconstructs the overlord state from memory given its identifier */ this.deserialize = function() { this.goal = Memory.overlords[this.id]["goal"]; this.underlings = Memory.overlords[this.id]["underlings"]; + this.state = Memory.overlords[this.id]["state"]; + this.todo = Memory.overlords[this.id]["todo"]; - console.log("Overlord: Read overlord "+this.id+" from memory!"); + //console.log("Overlord: Read overlord "+this.id+" from memory!"); }; /** diff --git a/src/overlords/setup_overlord.js b/src/overlords/setup_overlord.js index 700fbe4..0894fb3 100644 --- a/src/overlords/setup_overlord.js +++ b/src/overlords/setup_overlord.js @@ -6,20 +6,71 @@ var harvester = require('creeps_harvester'); * * Setup is considered finished once 3 spawns have been built and at least one creep is maintaining the RCL and at least one harvester is working */ +const STATE_INIT = 0; +const STATE_CREATE_HARVESTERS = 1; +const STATE_BUILD_SPAWNS = 3; +/** + * Switches the overlord into the given state + * @param {int} state + */ +setup_overlord.prototype.switch_state = function (state) { + this.state = state; + console.log("SetupOverlord: switching to state: "+state); +} /** Checks the room and sets out the tasks to achieve the goal */ setup_overlord.prototype.run = function () { - console.log("SetupOverlord: Running \""+this.id+"\"! :) Chilling for now ..."); - console.log("SetupOverlord: \""+this.id+"\"has the following underlings: ", this.underlings['spawns'], this.underlings['creeps']); + //console.log("SetupOverlord: Running \""+this.id+"\"! :) Chilling for now ..."); + //console.log("SetupOverlord: \""+this.id+"\"has the following underlings: ", this.underlings['spawns'], this.underlings['creeps']); + if (this.state === null) { + this.switch_state(STATE_INIT); + } + switch (this.state) { + case STATE_INIT: + this.init(); + break; + case STATE_CREATE_HARVESTERS: + this.create_harvesters(); + break; + case STATE_BUILD_SPAWNS: + console.log("SetupOverlord [ERROR] run(): state not implemented yet!"); + break; + default: + console.log("SetupOverlord [ERROR] run(): unknown state: "+this.state); + } +}; + +/** + * Checks that the requirements are given for the setup and then advances the state. + */ +setup_overlord.prototype.init = function() { + let source_count = Game.spawns[this.underlings["spawns"][0]].room.find(FIND_SOURCES).length; + + this.todo_list = { + req_harvesters: source_count, + req_spawns: 3, + req_RCL_maintainers: 1, + }; + if (this.underlings['creeps'].length === 0 && this.underlings['spawns'].length === 0) { // got NOTHING to work with console.log("SetupOverlord: ERROR "+this.id+" has nothing! ;W;"); } - else if (this.underlings['creeps'].length === 0 && this.underlings['spawns'].length > 0) { + else { + this.switch_state(STATE_CREATE_HARVESTERS); + } +} + +/** + * Function to be run every tick when the overlord aims to create more harvesters for every energy source. + * Switches to STATE_BUILD_SPAWNS if every source has a harvester assigned. + */ +setup_overlord.prototype.create_harvesters = function() { + if (this.underlings['creeps'].length === 0 && this.underlings['spawns'].length > 0) { // first harvester needs to be spawned console.log("SetupOverlord: \""+this.id+"\" is trying to create a harvester ..."); - for (let spawn_name of this.underlings['spawns']) { + for (let spawn_name of this.underlings['spawns']) { // check every spawn for energy available let spawn = Game.spawns[spawn_name]; if (spawn.store[RESOURCE_ENERGY] > harvester.min_cost) { // can afford a harvester console.log("SetupOverlord: Spawn "+spawn.name+" can afford a harvester! ("+harvester.min_cost+") \\o/"); @@ -29,9 +80,10 @@ setup_overlord.prototype.run = function () { break; } } - //spawn = Game.spawns[this.underlings['spawns']] // TODO set up some goals / overlord tasks } -}; + + +} /** * Set a creeps destination spot in their memory. This defines where a creep delivers their stuff to.