diff --git a/src/roleHandlers/harvesterHandler.ts b/src/roleHandlers/harvesterHandler.ts index 565d4d0..b9505ee 100644 --- a/src/roleHandlers/harvesterHandler.ts +++ b/src/roleHandlers/harvesterHandler.ts @@ -1,6 +1,6 @@ import { getSourceById, getSpawnById } from "utils/funcs/get_by_id"; import { RoleHandler } from "./roleHandler.interface"; -import { getNextEmptySpot } from "types/source"; +import { forEachMatrixSpot, getNextEmptySpot, getPositionWithDelta, setSpotStatus, SourceSpotStatus } from "types/source"; @@ -10,37 +10,82 @@ class HarvesterHandler extends RoleHandler { case "spawn": this.onSpawnDestination(creep, state); break; - default: + case "source": this.onSourceDestination(creep, state); break; + default: + this.onFindNewSource(creep, state); + break; } return state; } - private static onSourceDestination(creep: Creep, state: GameState) { - if (!creep.memory.destination) { - const sources = this.findClosestSource(creep, state); - if (sources.length > 0) { - creep.memory.destination = { - id: sources[0].id, - type: "source", - sourceSpot: getNextEmptySpot(state.sourcesStates[sources[0].id].spots) || { x: 0, y: 0 } - }; - } else { - console.warn(`No sources found for creep: ${creep.name}`); - return; + private static onFindNewSource(creep: Creep, state: GameState) { + if (creep.memory.destination) { + console.log(`Creep ${creep.name} already has a destination set.`); + return; // Already has a destination, no need to find a new one + } + + const sources = this.findClosestSource(creep, state); + + for (const source of sources) { + const sourceState = state.sourcesStates[source.id]; + const emptySpot = getNextEmptySpot(sourceState.spots); + + if (!emptySpot) { + continue; // No empty spots available, skip to next source } + + setSpotStatus( + sourceState.spots, + emptySpot, + SourceSpotStatus.OCCUPIED + ); + creep.memory.destination = { + id: source.id, + type: "source", + sourceSpot: emptySpot + }; + console.log(`Source ${creep.memory.destination.id} - `, state.sourcesStates[creep.memory.destination.id].spots) + return + } + + console.log(`Creep ${creep.name} could not find a valid source.`); + } + + private static onSourceDestination(creep: Creep, state: GameState) { + if (!creep.memory.destination || creep.memory.destination.type !== "source") { + console.log(`Creep ${creep.name} has no valid destination set.`); + delete creep.memory.destination; + return; + } + + if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) { + setSpotStatus( + state.sourcesStates[creep.memory.destination.id].spots, + creep.memory.destination.sourceSpot, + SourceSpotStatus.EMPTY + ); + console.log(`Source ${creep.memory.destination.id} - `, state.sourcesStates[creep.memory.destination.id].spots) + creep.memory.destination = { + id: creep.memory.spawnId, + type: "spawn" + }; + return; } const source = getSourceById(creep.memory.destination.id); if (!source) { - console.warn(`Source not found for creep: ${creep.name}`); + console.log(`Source not found for creep: ${creep.name}`); return; } if (creep.harvest(source) === ERR_NOT_IN_RANGE) { - creep.moveTo(source, { reusePath: true }); + const sourceSpotPosition = getPositionWithDelta( + source.pos, creep.memory.destination.sourceSpot + ) + creep.moveTo(sourceSpotPosition, { reusePath: true, ignoreCreeps: true }); } } @@ -51,29 +96,34 @@ class HarvesterHandler extends RoleHandler { type: "spawn" } } - if (creep.store.getFreeCapacity() <= 0) { + + if (creep.store.getUsedCapacity(RESOURCE_ENERGY) === 0) { delete creep.memory.destination; return; } const spawn = getSpawnById(creep.memory.destination.id); if (!spawn) { - console.warn(`Spawn not found for creep: ${creep.name}`); + console.log(`Spawn not found for creep: ${creep.name}`); return; } if (creep.transfer(spawn, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) { - creep.moveTo(spawn, { reusePath: true }); + creep.moveTo(spawn, { reusePath: true, ignoreCreeps: true }); } } private static findClosestSource(creep: Creep, state: GameState): Source[] { - return Object.keys(state.sourcesStates) + const sources = Object.keys(state.sourcesStates) .map(sourceId => getSourceById(sourceId)) .filter(source => source !== null) - .sort((a, b) => creep.pos.getRangeTo(a) - creep.pos.getRangeTo(b)); + .sort((a, b) => Math.abs(creep.pos.getRangeTo(a) - creep.pos.getRangeTo(b))) + + // console.log(`Creep ${creep.name} found ${sources.length} sources.`); + + return sources; } } diff --git a/src/spawnHandler.ts b/src/spawnHandler.ts index 8847ac3..a51b755 100644 --- a/src/spawnHandler.ts +++ b/src/spawnHandler.ts @@ -14,17 +14,17 @@ class SpawnHandler { public run(state: GameState): GameState { this.updateSpawnState(state); - // for(const name in Game.creeps) { - // const creep = Game.creeps[name]; + for(const name in Game.creeps) { + const creep = Game.creeps[name]; - // const roleDefinition = CreepRoles[creep.memory.role as CreepRole]; - // if (!roleDefinition) { - // console.warn(`Creep ${creep.name} has an unknown role: ${creep.memory.role}`); - // continue; - // } + const roleDefinition = CreepRoles[creep.memory.role as CreepRole]; + if (!roleDefinition) { + console.log(`Creep ${creep.name} has an unknown role: ${creep.memory.role}`); + continue; + } - // state = roleDefinition.handler.run(creep, state); - // } + state = roleDefinition.handler.run(creep, state); + } this.validateSpawnState(); @@ -63,19 +63,19 @@ class SpawnHandler { private validateSpawnState() { if (this.spawn.spawning) { - console.log(`Spawn ${this.spawn.name} is currently spawning a creep.`); + // console.log(`Spawn ${this.spawn.name} is currently spawning a creep.`); return; } const creepRequisition = this.checksNeedsCreeps(); if (Object.values(creepRequisition).every(count => count <= 0)) { - console.log(`Spawn ${this.spawn.name} has no creep needs.`); + // console.log(`Spawn ${this.spawn.name} has no creep needs.`); return; } const totalCreeps = Object.values(Game.creeps).length; if (totalCreeps >= DEFAULT_GAME_CONFIG.maxCreeps) { - console.log(`Spawn ${this.spawn.name} cannot spawn more creeps, limit reached.`); + // console.log(`Spawn ${this.spawn.name} cannot spawn more creeps, limit reached.`); return; } @@ -83,7 +83,7 @@ class SpawnHandler { for (const role of rolesToSpawn) { if (this.spawn.store[RESOURCE_ENERGY] < get_role_cost(role)) { - console.log(`Spawn ${this.spawn.name} does not have enough energy to spawn a ${role.name}.`); + // console.log(`Spawn ${this.spawn.name} does not have enough energy to spawn a ${role.name}.`); continue; } @@ -119,7 +119,7 @@ class SpawnHandler { }; for (const role in DEFAULT_GAME_CONFIG.minCreepsPerRole) { if (!(role in CreepRoles)) { - console.warn(`Unknown creep role: ${role}`); + console.log(`Unknown creep role: ${role}`); continue; } const roleType = role as CreepRole; diff --git a/src/types/gameConfig.ts b/src/types/gameConfig.ts index 9d1ea62..b649019 100644 --- a/src/types/gameConfig.ts +++ b/src/types/gameConfig.ts @@ -22,9 +22,9 @@ export type GameConfig = { * @type {GameConfig} */ export const DEFAULT_GAME_CONFIG: GameConfig = { - maxCreeps: 1, + maxCreeps: 7, minCreepsPerRole: { - harvester: 1, + harvester: 7, upgrader: 0, builder: 0 } diff --git a/src/types/source.ts b/src/types/source.ts index 57d091c..42b801c 100644 --- a/src/types/source.ts +++ b/src/types/source.ts @@ -34,7 +34,7 @@ export const createSourcePositionMatrix = () : SourcePositionMatrix => { export const getNextEmptySpot = (matrix: SourcePositionMatrix): PositionDelta | null => { - const index = matrix.findIndex( status => status === SourceSpotStatus.EMPTY || status === SourceSpotStatus.UNKNOWN); + const index = matrix.findIndex( status => status === SourceSpotStatus.EMPTY); if (index === -1) { return null; // No empty spot found diff --git a/src/utils/funcs/get_by_id.ts b/src/utils/funcs/get_by_id.ts index 7c23dab..c01ce98 100644 --- a/src/utils/funcs/get_by_id.ts +++ b/src/utils/funcs/get_by_id.ts @@ -1,12 +1,12 @@ export const getSourceById = (sourceId: string): Source | null => { if (!sourceId) { - console.warn("getSourceById called with an empty or undefined sourceId."); + console.log("getSourceById called with an empty or undefined sourceId."); return null; } const source = Game.getObjectById(sourceId); if (!source) { - console.warn(`No source found with ID: ${sourceId}`); + console.log(`No source found with ID: ${sourceId}`); return null; } @@ -16,13 +16,13 @@ export const getSourceById = (sourceId: string): Source | null => { export const getSpawnById = (spawnId: string): StructureSpawn | null => { if (!spawnId) { - console.warn("getSpawnById called with an empty or undefined spawnId."); + console.log("getSpawnById called with an empty or undefined spawnId."); return null; } const spawn = Game.getObjectById(spawnId); if (!spawn) { - console.warn(`No spawn found with ID: ${spawnId}`); + console.log(`No spawn found with ID: ${spawnId}`); return null; }