Fixes Closest Source
This commit is contained in:
@@ -15,11 +15,11 @@ declare global {
|
|||||||
id: string;
|
id: string;
|
||||||
spots: SourcePositionMatrix;
|
spots: SourcePositionMatrix;
|
||||||
pos: RoomPosition;
|
pos: RoomPosition;
|
||||||
currentHarvesters: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GameState {
|
interface GameState {
|
||||||
sourcesStates: { [sourceId: string]: SourceState };
|
sourcesStates: { [sourceId: string]: SourceState };
|
||||||
|
maxHarvesters: number; // Maximum number of harvesters allowed in the game
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory extension samples
|
// Memory extension samples
|
||||||
@@ -35,6 +35,7 @@ declare global {
|
|||||||
spawnId: string;
|
spawnId: string;
|
||||||
working: boolean;
|
working: boolean;
|
||||||
destination?: CreepDestination;
|
destination?: CreepDestination;
|
||||||
|
previousDestination?: CreepDestination;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syntax for adding proprties to `global` (ex "global.log")
|
// Syntax for adding proprties to `global` (ex "global.log")
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class HarvesterHandler extends RoleHandler {
|
|||||||
const sourceState = state.sourcesStates[source.id];
|
const sourceState = state.sourcesStates[source.id];
|
||||||
const emptySpot = getNextEmptySpot(sourceState.spots);
|
const emptySpot = getNextEmptySpot(sourceState.spots);
|
||||||
|
|
||||||
if (!emptySpot) {
|
if (emptySpot === null) {
|
||||||
continue; // No empty spots available, skip to next source
|
continue; // No empty spots available, skip to next source
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +47,6 @@ class HarvesterHandler extends RoleHandler {
|
|||||||
type: "source",
|
type: "source",
|
||||||
sourceSpot: emptySpot
|
sourceSpot: emptySpot
|
||||||
};
|
};
|
||||||
console.log(`Source ${creep.memory.destination.id} - `, state.sourcesStates[creep.memory.destination.id].spots)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,12 +61,7 @@ class HarvesterHandler extends RoleHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
||||||
setSpotStatus(
|
creep.memory.previousDestination = creep.memory.destination;
|
||||||
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 = {
|
creep.memory.destination = {
|
||||||
id: creep.memory.spawnId,
|
id: creep.memory.spawnId,
|
||||||
type: "spawn"
|
type: "spawn"
|
||||||
@@ -76,7 +70,7 @@ class HarvesterHandler extends RoleHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const source = getSourceById(creep.memory.destination.id);
|
const source = getSourceById(creep.memory.destination.id);
|
||||||
if (!source) {
|
if (source === null) {
|
||||||
console.log(`Source not found for creep: ${creep.name}`);
|
console.log(`Source not found for creep: ${creep.name}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -85,12 +79,20 @@ class HarvesterHandler extends RoleHandler {
|
|||||||
const sourceSpotPosition = getPositionWithDelta(
|
const sourceSpotPosition = getPositionWithDelta(
|
||||||
source.pos, creep.memory.destination.sourceSpot
|
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) {
|
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 = {
|
creep.memory.destination = {
|
||||||
id: creep.memory.spawnId,
|
id: creep.memory.spawnId,
|
||||||
type: "spawn"
|
type: "spawn"
|
||||||
@@ -109,7 +111,7 @@ class HarvesterHandler extends RoleHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (creep.transfer(spawn, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
|
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)
|
const sources = Object.keys(state.sourcesStates)
|
||||||
.map(sourceId => getSourceById(sourceId))
|
.map(sourceId => getSourceById(sourceId))
|
||||||
.filter(source => source !== null)
|
.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 as Source[];
|
||||||
|
|
||||||
return sources;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,17 +33,18 @@ class SpawnHandler {
|
|||||||
|
|
||||||
private updateSpawnState(state: GameState) {
|
private updateSpawnState(state: GameState) {
|
||||||
const sources = this.spawn.room.find(FIND_SOURCES);
|
const sources = this.spawn.room.find(FIND_SOURCES);
|
||||||
|
if (!state.sourcesStates) {
|
||||||
|
state.sourcesStates = {};
|
||||||
|
state.maxHarvesters = 0
|
||||||
|
}
|
||||||
for (const source of sources) {
|
for (const source of sources) {
|
||||||
if (!state.sourcesStates) {
|
|
||||||
state.sourcesStates = {};
|
|
||||||
}
|
|
||||||
const sourceId = source.id.toString();
|
const sourceId = source.id.toString();
|
||||||
|
|
||||||
if (!state.sourcesStates[sourceId]) {
|
if (!state.sourcesStates[sourceId]) {
|
||||||
state.sourcesStates[sourceId] = {
|
state.sourcesStates[sourceId] = {
|
||||||
"id": sourceId,
|
"id": sourceId,
|
||||||
"pos": source.pos,
|
"pos": source.pos,
|
||||||
"spots": createSourcePositionMatrix(),
|
"spots": createSourcePositionMatrix(),
|
||||||
"currentHarvesters": 0
|
|
||||||
};
|
};
|
||||||
forEachMatrixSpot(state.sourcesStates[sourceId].spots, (delta, status) => {
|
forEachMatrixSpot(state.sourcesStates[sourceId].spots, (delta, status) => {
|
||||||
if (status !== SourceSpotStatus.UNKNOWN) {
|
if (status !== SourceSpotStatus.UNKNOWN) {
|
||||||
@@ -52,11 +53,11 @@ class SpawnHandler {
|
|||||||
const pos = getPositionWithDelta(source.pos, delta);
|
const pos = getPositionWithDelta(source.pos, delta);
|
||||||
if (checkPositionWalkable(pos)) {
|
if (checkPositionWalkable(pos)) {
|
||||||
setSpotStatus(state.sourcesStates[sourceId].spots, delta, SourceSpotStatus.EMPTY);
|
setSpotStatus(state.sourcesStates[sourceId].spots, delta, SourceSpotStatus.EMPTY);
|
||||||
|
state.maxHarvesters = state.maxHarvesters + 1;
|
||||||
} else {
|
} else {
|
||||||
setSpotStatus(state.sourcesStates[sourceId].spots, delta, SourceSpotStatus.INVALID);
|
setSpotStatus(state.sourcesStates[sourceId].spots, delta, SourceSpotStatus.INVALID);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ export type GameConfig = {
|
|||||||
* @type {GameConfig}
|
* @type {GameConfig}
|
||||||
*/
|
*/
|
||||||
export const DEFAULT_GAME_CONFIG: GameConfig = {
|
export const DEFAULT_GAME_CONFIG: GameConfig = {
|
||||||
maxCreeps: 7,
|
maxCreeps: 5,
|
||||||
minCreepsPerRole: {
|
minCreepsPerRole: {
|
||||||
harvester: 7,
|
harvester: 5,
|
||||||
upgrader: 0,
|
upgrader: 0,
|
||||||
builder: 0
|
builder: 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,68 +12,70 @@ export type SourceSpotStatus = (typeof SourceSpotStatus)[keyof typeof SourceSpot
|
|||||||
|
|
||||||
export type PositionDeltaValue = -1 | 0 | 1;
|
export type PositionDeltaValue = -1 | 0 | 1;
|
||||||
|
|
||||||
export type PositionDelta = {
|
export type PositionDelta = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||||
x: PositionDeltaValue;
|
|
||||||
y: PositionDeltaValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SourcePositionMatrix = [
|
export type SourcePositionMatrix = {
|
||||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus,
|
locked: boolean;
|
||||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus,
|
data: [
|
||||||
SourceSpotStatus, SourceSpotStatus, SourceSpotStatus
|
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
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 => {
|
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) {
|
if (index === -1) {
|
||||||
return null; // No empty spot found
|
return null; // No empty spot found
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return index as PositionDelta; // Convert index to PositionDelta
|
||||||
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)
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const setSpotStatus = (matrix: SourcePositionMatrix, delta: PositionDelta, status: SourceSpotStatus): void => {
|
export const setSpotStatus = (matrix: SourcePositionMatrix, delta: PositionDelta, status: SourceSpotStatus): void => {
|
||||||
const x = delta.x + 1; // Convert to index (0, 1, 2)
|
matrix.data[delta as number] = status;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getPositionWithDelta = (pos: RoomPosition, delta: PositionDelta): RoomPosition => {
|
export const getPositionWithDelta = (pos: RoomPosition, delta: PositionDelta): RoomPosition => {
|
||||||
|
const matrixPoint = indexToMatrixPoint(delta as number);
|
||||||
return new RoomPosition(
|
return new RoomPosition(
|
||||||
pos.x + delta.x,
|
pos.x + matrixPoint.x,
|
||||||
pos.y + delta.y,
|
pos.y + matrixPoint.y,
|
||||||
pos.roomName
|
pos.roomName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const forEachMatrixSpot = (matrix: SourcePositionMatrix, callback: (delta: PositionDelta, status: SourceSpotStatus) => void): void => {
|
export const forEachMatrixSpot = (matrix: SourcePositionMatrix, callback: (delta: PositionDelta, status: SourceSpotStatus) => void): void => {
|
||||||
for (let y = -1; y <= 1; y++) {
|
for (const index in matrix.data) {
|
||||||
for (let x = -1; x <= 1; x++) {
|
callback(index as PositionDelta, matrix.data[index]);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user