Fixes Closest Source
This commit is contained in:
@@ -15,11 +15,11 @@ declare global {
|
||||
id: string;
|
||||
spots: SourcePositionMatrix;
|
||||
pos: RoomPosition;
|
||||
currentHarvesters: number;
|
||||
}
|
||||
|
||||
interface GameState {
|
||||
sourcesStates: { [sourceId: string]: SourceState };
|
||||
maxHarvesters: number; // Maximum number of harvesters allowed in the game
|
||||
}
|
||||
|
||||
// Memory extension samples
|
||||
@@ -35,6 +35,7 @@ declare global {
|
||||
spawnId: string;
|
||||
working: boolean;
|
||||
destination?: CreepDestination;
|
||||
previousDestination?: CreepDestination;
|
||||
}
|
||||
|
||||
// Syntax for adding proprties to `global` (ex "global.log")
|
||||
|
||||
@@ -33,7 +33,7 @@ class HarvesterHandler extends RoleHandler {
|
||||
const sourceState = state.sourcesStates[source.id];
|
||||
const emptySpot = getNextEmptySpot(sourceState.spots);
|
||||
|
||||
if (!emptySpot) {
|
||||
if (emptySpot === null) {
|
||||
continue; // No empty spots available, skip to next source
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ class HarvesterHandler extends RoleHandler {
|
||||
type: "source",
|
||||
sourceSpot: emptySpot
|
||||
};
|
||||
console.log(`Source ${creep.memory.destination.id} - `, state.sourcesStates[creep.memory.destination.id].spots)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -62,12 +61,7 @@ class HarvesterHandler extends RoleHandler {
|
||||
}
|
||||
|
||||
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.previousDestination = creep.memory.destination;
|
||||
creep.memory.destination = {
|
||||
id: creep.memory.spawnId,
|
||||
type: "spawn"
|
||||
@@ -76,7 +70,7 @@ class HarvesterHandler extends RoleHandler {
|
||||
}
|
||||
|
||||
const source = getSourceById(creep.memory.destination.id);
|
||||
if (!source) {
|
||||
if (source === null) {
|
||||
console.log(`Source not found for creep: ${creep.name}`);
|
||||
return;
|
||||
}
|
||||
@@ -85,12 +79,20 @@ class HarvesterHandler extends RoleHandler {
|
||||
const sourceSpotPosition = getPositionWithDelta(
|
||||
source.pos, creep.memory.destination.sourceSpot
|
||||
)
|
||||
creep.moveTo(sourceSpotPosition, { reusePath: true, ignoreCreeps: true });
|
||||
creep.moveTo(sourceSpotPosition, { reusePath: 0, visualizePathStyle: { stroke: '#ffffff', lineStyle: 'dashed', strokeWidth: 0.1 } });
|
||||
}
|
||||
}
|
||||
|
||||
private static onSpawnDestination(creep: Creep, state: GameState) {
|
||||
if (!creep.memory.destination) {
|
||||
if (!!creep.memory.previousDestination && creep.memory.previousDestination.type === "source") {
|
||||
setSpotStatus(
|
||||
state.sourcesStates[creep.memory.previousDestination.id].spots,
|
||||
creep.memory.previousDestination.sourceSpot,
|
||||
SourceSpotStatus.EMPTY
|
||||
);
|
||||
delete creep.memory.previousDestination; // Clear previous destination if it exists
|
||||
}
|
||||
if (creep.memory.destination === undefined) {
|
||||
creep.memory.destination = {
|
||||
id: creep.memory.spawnId,
|
||||
type: "spawn"
|
||||
@@ -109,7 +111,7 @@ class HarvesterHandler extends RoleHandler {
|
||||
}
|
||||
|
||||
if (creep.transfer(spawn, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
|
||||
creep.moveTo(spawn, { reusePath: true, ignoreCreeps: true });
|
||||
creep.moveTo(spawn, { reusePath: 0, visualizePathStyle: { stroke: '#ffffff', lineStyle: 'dashed', strokeWidth: 0.1 } });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,11 +121,9 @@ class HarvesterHandler extends RoleHandler {
|
||||
const sources = Object.keys(state.sourcesStates)
|
||||
.map(sourceId => getSourceById(sourceId))
|
||||
.filter(source => source !== null)
|
||||
.sort((a, b) => Math.abs(creep.pos.getRangeTo(a) - creep.pos.getRangeTo(b)))
|
||||
.sort((a, b) => creep.pos.getRangeTo(a) - creep.pos.getRangeTo(b));
|
||||
|
||||
// console.log(`Creep ${creep.name} found ${sources.length} sources.`);
|
||||
|
||||
return sources;
|
||||
return sources as Source[];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,17 +33,18 @@ class SpawnHandler {
|
||||
|
||||
private updateSpawnState(state: GameState) {
|
||||
const sources = this.spawn.room.find(FIND_SOURCES);
|
||||
if (!state.sourcesStates) {
|
||||
state.sourcesStates = {};
|
||||
state.maxHarvesters = 0
|
||||
}
|
||||
for (const source of sources) {
|
||||
if (!state.sourcesStates) {
|
||||
state.sourcesStates = {};
|
||||
}
|
||||
const sourceId = source.id.toString();
|
||||
|
||||
if (!state.sourcesStates[sourceId]) {
|
||||
state.sourcesStates[sourceId] = {
|
||||
"id": sourceId,
|
||||
"pos": source.pos,
|
||||
"spots": createSourcePositionMatrix(),
|
||||
"currentHarvesters": 0
|
||||
};
|
||||
forEachMatrixSpot(state.sourcesStates[sourceId].spots, (delta, status) => {
|
||||
if (status !== SourceSpotStatus.UNKNOWN) {
|
||||
@@ -52,11 +53,11 @@ class SpawnHandler {
|
||||
const pos = getPositionWithDelta(source.pos, delta);
|
||||
if (checkPositionWalkable(pos)) {
|
||||
setSpotStatus(state.sourcesStates[sourceId].spots, delta, SourceSpotStatus.EMPTY);
|
||||
state.maxHarvesters = state.maxHarvesters + 1;
|
||||
} else {
|
||||
setSpotStatus(state.sourcesStates[sourceId].spots, delta, SourceSpotStatus.INVALID);
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ export type GameConfig = {
|
||||
* @type {GameConfig}
|
||||
*/
|
||||
export const DEFAULT_GAME_CONFIG: GameConfig = {
|
||||
maxCreeps: 7,
|
||||
maxCreeps: 5,
|
||||
minCreepsPerRole: {
|
||||
harvester: 7,
|
||||
harvester: 5,
|
||||
upgrader: 0,
|
||||
builder: 0
|
||||
}
|
||||
|
||||
@@ -12,68 +12,70 @@ export type SourceSpotStatus = (typeof SourceSpotStatus)[keyof typeof SourceSpot
|
||||
|
||||
export type PositionDeltaValue = -1 | 0 | 1;
|
||||
|
||||
export type PositionDelta = {
|
||||
x: PositionDeltaValue;
|
||||
y: PositionDeltaValue;
|
||||
}
|
||||
export type PositionDelta = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
|
||||
export type SourcePositionMatrix = [
|
||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus,
|
||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus,
|
||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus
|
||||
]
|
||||
|
||||
|
||||
export const createSourcePositionMatrix = () : SourcePositionMatrix => {
|
||||
return [
|
||||
SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN,
|
||||
SourceSpotStatus.UNKNOWN, SourceSpotStatus.CENTER, SourceSpotStatus.UNKNOWN,
|
||||
SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN
|
||||
export type SourcePositionMatrix = {
|
||||
locked: boolean;
|
||||
data: [
|
||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus,
|
||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus,
|
||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
type MatrixPoint = {
|
||||
x: PositionDeltaValue;
|
||||
y: PositionDeltaValue;
|
||||
}
|
||||
|
||||
|
||||
const indexToMatrixPoint = (index: number): MatrixPoint => {
|
||||
// where the 0,0 point is the center of the matrix and -1, -1 is the top-left corner
|
||||
const x = ((index % 3) - 1) as PositionDeltaValue; // Convert index to x coordinate (-1, 0, 1)
|
||||
const y = (Math.floor(index / 3) - 1) as PositionDeltaValue; // Convert index to y coordinate (-1, 0, 1)
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
export const createSourcePositionMatrix = () : SourcePositionMatrix => {
|
||||
return {
|
||||
locked: false,
|
||||
data: [
|
||||
SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN,
|
||||
SourceSpotStatus.UNKNOWN, SourceSpotStatus.CENTER, SourceSpotStatus.UNKNOWN,
|
||||
SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN, SourceSpotStatus.UNKNOWN
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export const getNextEmptySpot = (matrix: SourcePositionMatrix): PositionDelta | null => {
|
||||
const index = matrix.findIndex( status => status === SourceSpotStatus.EMPTY);
|
||||
const index = matrix.data.findIndex( status => status === SourceSpotStatus.EMPTY);
|
||||
|
||||
if (index === -1) {
|
||||
return null; // No empty spot found
|
||||
}
|
||||
|
||||
return {
|
||||
x: (index % 3 - 1) as PositionDeltaValue, // Convert index to x delta (-1, 0, 1)
|
||||
y: (Math.floor(index / 3) - 1) as PositionDeltaValue // Convert index to y delta (-1, 0, 1)
|
||||
};
|
||||
return index as PositionDelta; // Convert index to PositionDelta
|
||||
};
|
||||
|
||||
|
||||
export const setSpotStatus = (matrix: SourcePositionMatrix, delta: PositionDelta, status: SourceSpotStatus): void => {
|
||||
const x = delta.x + 1; // Convert to index (0, 1, 2)
|
||||
const y = delta.y + 1; // Convert to index (0, 1, 2)
|
||||
|
||||
if (x < 0 || x > 2 || y < 0 || y > 2) {
|
||||
throw new Error("Invalid position delta for source position matrix.");
|
||||
}
|
||||
|
||||
const index = y * 3 + x; // Calculate the index in the flat array
|
||||
matrix[index] = status;
|
||||
matrix.data[delta as number] = status;
|
||||
}
|
||||
|
||||
|
||||
export const getPositionWithDelta = (pos: RoomPosition, delta: PositionDelta): RoomPosition => {
|
||||
const matrixPoint = indexToMatrixPoint(delta as number);
|
||||
return new RoomPosition(
|
||||
pos.x + delta.x,
|
||||
pos.y + delta.y,
|
||||
pos.x + matrixPoint.x,
|
||||
pos.y + matrixPoint.y,
|
||||
pos.roomName
|
||||
);
|
||||
}
|
||||
|
||||
export const forEachMatrixSpot = (matrix: SourcePositionMatrix, callback: (delta: PositionDelta, status: SourceSpotStatus) => void): void => {
|
||||
for (let y = -1; y <= 1; y++) {
|
||||
for (let x = -1; x <= 1; x++) {
|
||||
const delta: PositionDelta = { x: x as PositionDeltaValue, y: y as PositionDeltaValue };
|
||||
const index = (y + 1) * 3 + (x + 1); // Convert delta to index
|
||||
callback(delta, matrix[index]);
|
||||
}
|
||||
for (const index in matrix.data) {
|
||||
callback(index as PositionDelta, matrix.data[index]);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user