Use weights for source selection
This commit is contained in:
parent
c51647312f
commit
420cd3f72e
@ -1,8 +1,8 @@
|
||||
import { randomIntInRange } from '../utils/Random';
|
||||
import { selectSource } from './common';
|
||||
|
||||
interface BuilderMemory extends CreepMemory {
|
||||
building: boolean | undefined;
|
||||
sourceNum: number | undefined;
|
||||
sourceId: Id<Source> | undefined;
|
||||
}
|
||||
|
||||
export function runAsBuilder(creep: Creep) {
|
||||
@ -16,9 +16,8 @@ export function runAsBuilder(creep: Creep) {
|
||||
memory.building = true;
|
||||
}
|
||||
|
||||
if (memory.sourceNum === undefined) {
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
memory.sourceNum = randomIntInRange(0, sources.length);
|
||||
if (memory.sourceId === undefined) {
|
||||
memory.sourceId = selectSource(creep);
|
||||
}
|
||||
|
||||
if (memory.building) {
|
||||
@ -34,11 +33,10 @@ export function runAsBuilder(creep: Creep) {
|
||||
creep.moveTo(spawns[0]);
|
||||
}
|
||||
} else {
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
const sourceNum = memory.sourceNum;
|
||||
if (creep.harvest(sources[sourceNum]) == ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest ' + sourceNum);
|
||||
creep.moveTo(sources[sourceNum], { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
const source = Game.getObjectById(memory.sourceId);
|
||||
if (source && creep.harvest(source) == ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest');
|
||||
creep.moveTo(source, { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { randomIntInRange } from '../utils/Random';
|
||||
import { randomValueFromArray } from '../utils/Random';
|
||||
|
||||
export interface SourceNumber {
|
||||
sourceNum: number | undefined;
|
||||
}
|
||||
|
||||
function selectSource(memory: SourceNumber) {
|
||||
if (memory.sourceNum === undefined) {
|
||||
export function selectSource(creep: Creep): Id<Source> {
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
memory.sourceNum = randomIntInRange(0, sources.length);
|
||||
const choices: Array<String> = [];
|
||||
for (let source of sources) {
|
||||
const weight = getSourceWeight(source);
|
||||
for (let i = 0; i < weight; ++i) {
|
||||
choices.push(source.id);
|
||||
}
|
||||
}
|
||||
console.log('Sources', choices);
|
||||
return randomValueFromArray(choices) as Id<Source>;
|
||||
}
|
||||
|
||||
function moveToSource(creep: Creep) {
|
||||
const memory = creep.memory as SourceNumber;
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
const sourceNum = memory.sourceNum;
|
||||
if (creep.harvest(sources[sourceNum]) == ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest ' + sourceNum);
|
||||
creep.moveTo(sources[sourceNum], { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
}
|
||||
function getSourceWeight(source: Source) {
|
||||
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);
|
||||
}
|
||||
|
@ -1,23 +1,21 @@
|
||||
import { randomIntInRange } from '../utils/Random';
|
||||
import { selectSource } from './common';
|
||||
|
||||
interface HarvesterMemory extends CreepMemory {
|
||||
sourceNum: number | undefined;
|
||||
sourceId: Id<Source> | undefined;
|
||||
}
|
||||
|
||||
export function runAsHarvester(creep: Creep) {
|
||||
const memory = creep.memory as HarvesterMemory;
|
||||
|
||||
if (memory.sourceNum === undefined) {
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
memory.sourceNum = randomIntInRange(0, sources.length);
|
||||
if (memory.sourceId === undefined) {
|
||||
memory.sourceId = selectSource(creep);
|
||||
}
|
||||
|
||||
if (creep.store.getFreeCapacity() > 0) {
|
||||
let sources = creep.room.find(FIND_SOURCES);
|
||||
const sourceNum = memory.sourceNum;
|
||||
if (creep.harvest(sources[sourceNum]) === ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest ' + sourceNum);
|
||||
creep.moveTo(sources[sourceNum], { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
const source = Game.getObjectById(memory.sourceId);
|
||||
if (source && creep.harvest(source) === ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest');
|
||||
creep.moveTo(source, { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
}
|
||||
} else {
|
||||
let targets = creep.room.find(FIND_STRUCTURES, {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { randomIntInRange } from '../utils/Random';
|
||||
import { selectSource } from './common';
|
||||
|
||||
interface UpgraderMemory extends CreepMemory {
|
||||
upgrading: boolean | undefined;
|
||||
sourceNum: number | undefined;
|
||||
sourceId: Id<Source> | undefined;
|
||||
}
|
||||
|
||||
export function runAsUpgrader(creep: Creep) {
|
||||
@ -16,9 +16,8 @@ export function runAsUpgrader(creep: Creep) {
|
||||
memory.upgrading = true;
|
||||
}
|
||||
|
||||
if (memory.sourceNum === undefined) {
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
memory.sourceNum = randomIntInRange(0, sources.length);
|
||||
if (memory.sourceId === undefined) {
|
||||
memory.sourceId = selectSource(creep);
|
||||
}
|
||||
|
||||
if (memory.upgrading) {
|
||||
@ -27,11 +26,10 @@ export function runAsUpgrader(creep: Creep) {
|
||||
creep.moveTo(creep.room.controller, { visualizePathStyle: { stroke: '#ffffff' } });
|
||||
}
|
||||
} else {
|
||||
const sources = creep.room.find(FIND_SOURCES);
|
||||
const sourceNum = memory.sourceNum;
|
||||
if (creep.harvest(sources[sourceNum]) == ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest ' + sourceNum);
|
||||
creep.moveTo(sources[sourceNum], { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
const source = Game.getObjectById(memory.sourceId);
|
||||
if (source && creep.harvest(source) == ERR_NOT_IN_RANGE) {
|
||||
creep.say('🔄 harvest');
|
||||
creep.moveTo(source, { visualizePathStyle: { stroke: '#ffaa00' } });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
33
src/main.ts
33
src/main.ts
@ -4,8 +4,8 @@ import { runAsBuilder } from './creep/builder';
|
||||
import { runAsUpgrader } from './creep/upgrader';
|
||||
import { uniqId } from './utils/Identity';
|
||||
|
||||
function makeName(role: string): string {
|
||||
return uniqId(role + '_');
|
||||
function makeName(): string {
|
||||
return uniqId();
|
||||
}
|
||||
|
||||
enum CreepRole {
|
||||
@ -19,17 +19,35 @@ function makeCreep(role: CreepRole, count: number) {
|
||||
console.log(`Make creep "${role}"`, 'need', count, 'has', creeps.length);
|
||||
if (creeps.length < count) {
|
||||
const firstSpawn = _.first(Object.values(Game.spawns));
|
||||
const name = makeName(role);
|
||||
const name = makeName();
|
||||
const memory = { role: role } as CreepMemory;
|
||||
const err = firstSpawn.spawnCreep([WORK, CARRY, MOVE], name, { memory });
|
||||
console.log(`Make creep "${role}"`, 'err', err);
|
||||
}
|
||||
}
|
||||
|
||||
function callHarvestersFromOthers(minHarvCount: number) {
|
||||
const harvesters = Object.values(Game.creeps).filter((c) => c.memory.role === CreepRole.HARVESTER);
|
||||
if (harvesters.length < minHarvCount) {
|
||||
const others = Object.values(Game.creeps).filter((c) => c.memory.role !== CreepRole.HARVESTER);
|
||||
const required = Math.min(minHarvCount, others.length);
|
||||
console.log('Call harvesters', required);
|
||||
let count = 0;
|
||||
for (let creep of others) {
|
||||
if (count >= required) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
creep.memory.role = CreepRole.HARVESTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When compiling TS to JS and bundling with rollup, the line numbers and file names in error messages change
|
||||
// This utility uses source maps to get the line numbers and file names of the original, TS source code
|
||||
export const loop = ErrorMapper.wrapLoop(() => {
|
||||
console.log(`\nCurrent game tick is ${Game.time}`);
|
||||
console.log('');
|
||||
console.log(`Current game tick is ${Game.time}`);
|
||||
|
||||
// Automatically delete memory of missing creeps
|
||||
for (const name in Memory.creeps) {
|
||||
@ -38,10 +56,15 @@ export const loop = ErrorMapper.wrapLoop(() => {
|
||||
}
|
||||
}
|
||||
|
||||
makeCreep(CreepRole.HARVESTER, 6);
|
||||
const harvCount = 8;
|
||||
const minHarvCount = Math.floor(harvCount * 0.6);
|
||||
|
||||
makeCreep(CreepRole.HARVESTER, harvCount);
|
||||
makeCreep(CreepRole.UPGRADER, 6);
|
||||
makeCreep(CreepRole.BUILDER, 6);
|
||||
|
||||
callHarvestersFromOthers(minHarvCount);
|
||||
|
||||
// Process current creeps
|
||||
for (let name in Game.creeps) {
|
||||
const creep = Game.creeps[name];
|
||||
|
@ -2,3 +2,9 @@ export function randomIntInRange(min: number, max: number): number {
|
||||
const delta = max - min;
|
||||
return Math.floor(Math.random() * delta) + min;
|
||||
}
|
||||
|
||||
export function randomValueFromArray<T>(items: Array<T>): T {
|
||||
const len = items.length;
|
||||
const index = randomIntInRange(0, len);
|
||||
return items[index];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user