Skip to content

Commit

Permalink
rework the nuke planner fortify logic to get to minimum safe value, t…
Browse files Browse the repository at this point in the history
…hen balance fortifications instead of full true up of barriers in order of priority which could be a massive jump if behind
  • Loading branch information
ikiris committed Jun 4, 2020
1 parent d492973 commit 53df937
Showing 1 changed file with 45 additions and 9 deletions.
54 changes: 45 additions & 9 deletions src/overlords/core/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import {Visualizer} from '../../visuals/Visualizer';
import {Zerg} from '../../zerg/Zerg';
import {Overlord} from '../Overlord';

interface hitsCallback {
(structure: StructureWall|StructureRampart): number;
}

/**
* Spawns general-purpose workers, which maintain a colony, performing actions such as building, repairing, fortifying,
* paving, and upgrading, when needed
Expand All @@ -29,6 +33,7 @@ export class WorkerOverlord extends Overlord {
constructionSites: ConstructionSite[];
nukeDefenseRamparts: StructureRampart[];
nukeDefenseHitsRemaining: { [id: string]: number };
nukeDefenseHitsNeeded: { [id: string]: number };
useBoostedRepair?: boolean;

static settings = {
Expand Down Expand Up @@ -106,6 +111,7 @@ export class WorkerOverlord extends Overlord {
// Nuke defense ramparts needing fortification
this.nukeDefenseRamparts = [];
this.nukeDefenseHitsRemaining = {};
this.nukeDefenseHitsNeeded = {};
if (this.room.find(FIND_NUKES).length > 0) {
for (const rampart of this.colony.room.ramparts) {
const neededHits = this.neededRampartHits(rampart);
Expand Down Expand Up @@ -133,8 +139,11 @@ export class WorkerOverlord extends Overlord {
this.workers = this.zerg(Roles.worker);
}

private neededRampartHits(rampart: StructureRampart): number {
let neededHits = WorkerOverlord.settings.barrierHits[this.colony.level];
private neededNukeHits(rampart: StructureWall|StructureRampart): number {
if (this.nukeDefenseHitsNeeded[rampart.id] !== undefined) {
return this.nukeDefenseHitsNeeded[rampart.id]
}
let neededHits = 0;
for (const nuke of rampart.pos.lookFor(LOOK_NUKES)) {
neededHits += 10e6;
}
Expand All @@ -143,6 +152,13 @@ export class WorkerOverlord extends Overlord {
neededHits += 5e6;
}
}
this.nukeDefenseHitsNeeded[rampart.id] = neededHits;
return neededHits;
}

private neededRampartHits(rampart: StructureRampart): number {
let neededHits = WorkerOverlord.settings.barrierHits[this.colony.level];
neededHits =+ this.neededNukeHits(rampart);
return neededHits;
}

Expand Down Expand Up @@ -263,20 +279,29 @@ export class WorkerOverlord extends Overlord {
return false;
}
}

private fortifyActions(worker: Zerg, fortifyStructures = this.fortifyBarriers): boolean {

private lowBarriers(fortifyStructures = this.fortifyBarriers,
hitsCallback: hitsCallback
= function(structure: StructureWall|StructureRampart): number {return structure.hits;}
): (StructureWall | StructureRampart)[]
{
let lowBarriers: (StructureWall | StructureRampart)[];
const highestBarrierHits = _.max(_.map(fortifyStructures, structure => structure.hits));
const highestBarrierHits = _.max(_.map(fortifyStructures, structure => hitsCallback(structure)));
if (highestBarrierHits > WorkerOverlord.settings.hitTolerance) {
// At high barrier HP, fortify only structures that are within a threshold of the lowest
const lowestBarrierHits = _.min(_.map(fortifyStructures, structure => structure.hits));
lowBarriers = _.filter(fortifyStructures, structure => structure.hits <= lowestBarrierHits +
const lowestBarrierHits = _.min(_.map(fortifyStructures, structure => hitsCallback(structure)));
lowBarriers = _.filter(fortifyStructures, structure => hitsCallback(structure) <= lowestBarrierHits +
WorkerOverlord.settings.hitTolerance);
} else {
// Otherwise fortify the lowest N structures
const numBarriersToConsider = 5; // Choose the closest barrier of the N barriers with lowest hits
lowBarriers = _.take(fortifyStructures, numBarriersToConsider);
}
return lowBarriers
}

private fortifyActions(worker: Zerg, fortifyStructures = this.fortifyBarriers): boolean {
const lowBarriers = this.lowBarriers(fortifyStructures);
const target = worker.pos.findClosestByMultiRoomRange(lowBarriers);
if (target) {
worker.task = Tasks.fortify(target);
Expand All @@ -287,7 +312,17 @@ export class WorkerOverlord extends Overlord {
}

private nukeFortifyActions(worker: Zerg, fortifyStructures = this.nukeDefenseRamparts): boolean {
const target = minBy(fortifyStructures, rampart => {
var self = this;
const adaptedHits = _.reduce(fortifyStructures, function(obj,structure: StructureWall|StructureRampart) {
obj[structure.id] = structure.hits - self.neededNukeHits(structure);
return obj;
}, {} as {[key: string]: number});

const lowBarriers = this.lowBarriers()
const minBarrier = lowBarriers[lowBarriers.length - 1].hits
const urgent = _.filter(fortifyStructures, structure => adaptedHits[structure.id] < minBarrier)

const target = minBy(urgent, rampart => {
const structuresUnderRampart = rampart.pos.lookFor(LOOK_STRUCTURES);
return _.min(_.map(structuresUnderRampart, structure => {
const priority = _.findIndex(FortifyPriorities, sType => sType == structure.structureType);
Expand All @@ -298,11 +333,12 @@ export class WorkerOverlord extends Overlord {
}
}));
});

if (target) {
worker.task = Tasks.fortify(target);
return true;
} else {
return false;
return this.fortifyActions(worker, fortifyStructures);
}
}

Expand Down

0 comments on commit 53df937

Please sign in to comment.