diff --git a/src/creep/builder.ts b/src/creep/builder.ts index 3de1f89..f10c124 100644 --- a/src/creep/builder.ts +++ b/src/creep/builder.ts @@ -2,7 +2,6 @@ import { selectSource } from './common'; interface BuilderMemory extends CreepMemory { building: boolean | undefined; - sourceId: Id | undefined; } export function runAsBuilder(creep: Creep) { @@ -16,8 +15,8 @@ export function runAsBuilder(creep: Creep) { memory.building = true; } - if (memory.sourceId === undefined) { - memory.sourceId = selectSource(creep); + if (!memory.sourceId) { + memory.sourceId = selectSource(creep.room); } if (memory.building) { diff --git a/src/creep/common.ts b/src/creep/common.ts index 71764ed..d691b92 100644 --- a/src/creep/common.ts +++ b/src/creep/common.ts @@ -1,21 +1,29 @@ -import { randomValueFromArray } from '../utils/Random'; - -export function selectSource(creep: Creep): Id { - const sources = creep.room.find(FIND_SOURCES); - const choices: Array = []; - for (let source of sources) { +export function selectSource(room: Room): Id { + console.log('Select source for room', room.name); + const creepsInRoom = room.find(FIND_MY_CREEPS); + const sourcesInRoom = room.find(FIND_SOURCES); + const rates: Weights = {}; + for (let source of sourcesInRoom) { + const creepCount = creepsInRoom.filter((c) => c.memory.sourceId === source.id).length; const weight = getSourceWeight(source); - for (let i = 0; i < weight; ++i) { - choices.push(source.id); - } + rates[source.id] = creepCount / weight; } - console.log('Sources', choices); - return randomValueFromArray(choices) as Id; + console.log('Sources', JSON.stringify(rates)); + return getKeyWithMinWeight(rates) as Id; } -function getSourceWeight(source: Source) { +function getSourceWeight(source: Source): number { const pos = source.pos; const terrains = source.room.lookForAtArea(LOOK_TERRAIN, pos.y - 1, pos.x - 1, pos.y + 1, pos.x + 1, true); const walked = terrains.filter((t) => t.terrain !== 'wall'); return Math.max(walked.length - 1, 1); } + +interface Weights { + [key: string]: number; +} + +function getKeyWithMinWeight(weights: Weights): string { + let keys = Object.keys(weights); + return keys.reduce((key, v) => (weights[v] < weights[key] ? v : key)); +} diff --git a/src/creep/harvester.ts b/src/creep/harvester.ts index 3e19fd8..dc2cd26 100644 --- a/src/creep/harvester.ts +++ b/src/creep/harvester.ts @@ -1,10 +1,6 @@ import { selectSource } from './common'; -const TARGET_TYPES = [STRUCTURE_EXTENSION, STRUCTURE_SPAWN, STRUCTURE_TOWER]; - -interface HarvesterMemory extends CreepMemory { - sourceId: Id | undefined; -} +const TARGET_TYPES = [STRUCTURE_EXTENSION, STRUCTURE_TOWER, STRUCTURE_SPAWN]; enum Action { Harvest = 'harvest', @@ -12,14 +8,14 @@ enum Action { } export function runAsHarvester(creep: Creep) { - const memory = creep.memory as HarvesterMemory; + const memory = creep.memory as CreepMemory; if (memory.action === undefined) { memory.action = Action.Harvest; } - if (memory.sourceId === undefined) { - memory.sourceId = selectSource(creep); + if (!memory.sourceId) { + memory.sourceId = selectSource(creep.room); } switch (memory.action) { diff --git a/src/creep/upgrader.ts b/src/creep/upgrader.ts index 034f7c0..176f7e0 100644 --- a/src/creep/upgrader.ts +++ b/src/creep/upgrader.ts @@ -2,7 +2,6 @@ import { selectSource } from './common'; interface UpgraderMemory extends CreepMemory { upgrading: boolean | undefined; - sourceId: Id | undefined; } export function runAsUpgrader(creep: Creep) { @@ -16,8 +15,8 @@ export function runAsUpgrader(creep: Creep) { memory.upgrading = true; } - if (memory.sourceId === undefined) { - memory.sourceId = selectSource(creep); + if (!memory.sourceId) { + memory.sourceId = selectSource(creep.room); } if (memory.upgrading) { diff --git a/src/main.ts b/src/main.ts index 2ede16a..db22187 100644 --- a/src/main.ts +++ b/src/main.ts @@ -20,8 +20,11 @@ function makeCreep(role: CreepRole, count: number) { if (creeps.length < count) { const firstSpawn = _.first(Object.values(Game.spawns)); const name = makeName(); - const memory = { role: role } as CreepMemory; - const err = firstSpawn.spawnCreep([WORK, WORK, CARRY, CARRY, MOVE, MOVE], name, { memory }); + const memory = { role: role, sourceId: '' } as CreepMemory; + const err = firstSpawn.spawnCreep([WORK, WORK, CARRY, CARRY, MOVE, MOVE], name, { + memory, + directions: [BOTTOM, BOTTOM_RIGHT, RIGHT] + }); console.log(`Make creep "${role}"`, 'err', err); } } diff --git a/src/types.d.ts b/src/types.d.ts index 0be1439..5bebc00 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -11,6 +11,10 @@ interface CreepMemory { * Действие, которое крип будет выполнять. */ action: string | undefined; + /** + * Идентификатор источника энергии для крипа. + */ + sourceId: Id | ''; room: string; working: boolean; }