-
Notifications
You must be signed in to change notification settings - Fork 157
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] improve carry recycling #403
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,7 +142,13 @@ global.config = { | |
1800: [8, 15], // RCL 5 | ||
2300: [11, 21], // RCL 6 | ||
}, | ||
transferToCarry: false, | ||
// limit carry spawn rate when RCL < 4 | ||
minSpawnRate: 50, | ||
// when ticksToLive > recycleThreshold, reuse carry | ||
recycleThreshold: 200, | ||
// keep at least one carry for a target | ||
ensureOne: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't think up a better name... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is fine, maybe |
||
// Percentage should increase from base to target room. Decrease may cause stack on border | ||
carryPercentageBase: 0.1, | ||
carryPercentageHighway: 0.2, | ||
|
@@ -243,9 +249,9 @@ global.config = { | |
defender: 12, | ||
defendranged: 13, | ||
nextroomer: 15, | ||
carry: 17, | ||
reserver: 17, | ||
sourcer: 18, | ||
reserver: 19, | ||
carry: 19, | ||
}, | ||
}, | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,14 +43,14 @@ Creep.prototype.spawnCarry = function() { | |
return false; | ||
} | ||
|
||
const baseRoom = Game.rooms[this.memory.base]; | ||
|
||
const foundKey = Object.keys(config.carry.sizes).reverse() | ||
.find((key) => (key <= Game.rooms[this.memory.base].energyCapacityAvailable)); | ||
.find((key) => (key <= baseRoom.energyCapacityAvailable)); | ||
const carryCapacity = config.carry.sizes[foundKey][1] * CARRY_CAPACITY; | ||
|
||
const workParts = this.body.filter((part) => part.type === WORK).length; | ||
|
||
const waitTime = carryCapacity / (HARVEST_POWER * workParts); | ||
|
||
let resourceAtPosition = 0; | ||
const resources = this.pos.lookFor(LOOK_RESOURCES); | ||
for (const resource of resources) { | ||
|
@@ -63,15 +63,17 @@ Creep.prototype.spawnCarry = function() { | |
resourceAtPosition += _.sum(container.store); | ||
} | ||
|
||
const waitTime = carryCapacity / (HARVEST_POWER * workParts) * | ||
Math.sqrt(carryCapacity / Math.max(resourceAtPosition, carryCapacity)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the approach, can you explain a bit more what the idea is here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reduce There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. K, cool, let's see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. like it |
||
|
||
if (resourceAtPosition > carryCapacity) { | ||
Game.rooms[this.memory.base].checkRoleToSpawn('carry', 0, this.memory.routing.targetId, this.memory.routing.targetRoom); | ||
} else if (resourceAtPosition <= HARVEST_POWER * workParts) { | ||
const nearCarries = this.pos.findInRangePropertyFilter(FIND_MY_CREEPS, 2, 'memory.role', ['carry'], false, { | ||
filter: (creep) => creep.memory.routing.targetId === this.memory.routing.targetId, | ||
}); | ||
if (nearCarries.length > 1) { | ||
nearCarries[0].memory.recycle = true; | ||
} | ||
baseRoom.checkRoleToSpawn('carry', 0, this.memory.routing.targetId, this.memory.routing.targetRoom); | ||
} | ||
|
||
// limit carry spawn rate when RCL < 4 | ||
if (baseRoom.controller.level < 4) { | ||
this.memory.wait = Math.max(waitTime, config.carry.minSpawnRate); | ||
} else { | ||
this.memory.wait = waitTime; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normally, |
||
} | ||
this.memory.wait = Math.max(waitTime, config.carry.minSpawnRate); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,12 +29,8 @@ Creep.prototype.harvesterBeforeStorage = function() { | |
return true; | ||
}; | ||
|
||
Creep.prototype.checkEnergyTransfer = function(otherCreep) { | ||
Creep.prototype.checkEnergyTransfer = function(offset = 0) { | ||
// TODO duplicate from role_carry, extract to method | ||
let offset = 0; | ||
if (otherCreep) { | ||
offset = otherCreep.carry.energy; | ||
} | ||
|
||
// define minimum carryPercentage to move back to storage | ||
let carryPercentage = config.carry.carryPercentageHighway; | ||
|
@@ -65,7 +61,7 @@ Creep.prototype.findCreepWhichCanTransfer = function(creeps) { | |
if (otherCreep.checkHelperNoTransfer(this)) { | ||
continue; | ||
} | ||
return this.checkEnergyTransfer(otherCreep); | ||
return this.checkEnergyTransfer(otherCreep.carry[RESOURCE_ENERGY]); | ||
} | ||
continue; | ||
} | ||
|
@@ -79,10 +75,7 @@ Creep.prototype.checkForTransfer = function(direction) { | |
|
||
const adjacentPos = this.pos.getAdjacentPosition(direction); | ||
|
||
if (adjacentPos.x < 0 || adjacentPos.y < 0) { | ||
return false; | ||
} | ||
if (adjacentPos.x > 49 || adjacentPos.y > 49) { | ||
if (!adjacentPos.isValid()) { | ||
return false; | ||
} | ||
|
||
|
@@ -106,7 +99,7 @@ Creep.prototype.pickupWhileMoving = function(reverse) { | |
if (resources.length > 0) { | ||
const resource = resources[0]; | ||
const amount = this.pickupOrWithdrawFromSourcer(resource); | ||
return _.sum(this.carry) + amount > 0.5 * this.carryCapacity; | ||
return this.checkEnergyTransfer(amount); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
} | ||
|
||
if (this.room.name === this.memory.routing.targetRoom) { | ||
|
@@ -118,7 +111,7 @@ Creep.prototype.pickupWhileMoving = function(reverse) { | |
} | ||
if (container.store[RESOURCE_ENERGY]) { | ||
this.withdraw(container, RESOURCE_ENERGY); | ||
return container.store[RESOURCE_ENERGY] > 9; | ||
return this.checkEnergyTransfer(container.store[RESOURCE_ENERGY]); | ||
} | ||
} | ||
} | ||
|
@@ -297,6 +290,9 @@ const checkCreepForTransfer = function(creep) { | |
if (Game.creeps[creep.name].memory.role === 'powertransporter') { | ||
return false; | ||
} | ||
if (!config.carry.transferToCarry && Game.creeps[creep.name].memory.role === 'carry') { | ||
return false; | ||
} | ||
if (creep.carry.energy === creep.carryCapacity) { | ||
return false; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,20 +43,44 @@ roles.carry.updateSettings = function(room, creep) { | |
} | ||
}; | ||
|
||
roles.carry.reset = function(creep) { | ||
// TODO check new routing. if carry is on the new path, reset carry, otherwise move to pathStart | ||
const queue = Memory.rooms[creep.memory.base].queue || []; | ||
for (let i = 0; i < queue.length; i++) { | ||
if (queue[i].role === 'carry' && !queue[i].helper) { | ||
creep.memory.routing = queue[i].routing; | ||
queue.splice(i, 1); | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
|
||
roles.carry.ensureOne = function(creep) { | ||
if (config.carry.ensureOne) { | ||
const nearCarries = creep.pos.findInRangePropertyFilter(FIND_MY_CREEPS, 1, 'memory.role', ['carry'], false, { | ||
filter: (otherCreep) => !otherCreep.resetTarget && otherCreep.memory.routing.targetId === creep.memory.routing.targetId, | ||
}); | ||
if (nearCarries.length < 2) { | ||
creep.memory.resetTarget = false; | ||
} | ||
} | ||
}; | ||
|
||
roles.carry.checkHelperEmptyStorage = function(creep) { | ||
// Fix blocked helpers due to empty structure in the room where we get the energy from | ||
if (creep.room.name === creep.memory.routing.targetRoom) { | ||
const targetStructure = Game.getObjectById(creep.memory.routing.targetId); | ||
if (targetStructure === null) { | ||
creep.suicide(); | ||
creep.memory.resetTarget = true; | ||
return; | ||
} | ||
|
||
if (targetStructure.structureType === STRUCTURE_STORAGE) { | ||
creep.say('storage'); | ||
if (targetStructure.store.energy === 0) { | ||
creep.log('Suiciding the storage I should get the energy from is empty'); | ||
creep.suicide(); | ||
creep.log('the storage I should get the energy from is empty'); | ||
creep.memory.resetTarget = true; | ||
} | ||
} | ||
} | ||
|
@@ -67,6 +91,8 @@ roles.carry.handleMisplacedSpawn = function(creep) { | |
// TODO Somehow ugly and maybe better somewhere else | ||
if (creep.inBase() && (creep.room.memory.misplacedSpawn || creep.room.controller.level < 3)) { | ||
// creep.say('cmis', true); | ||
// don't recycle carry | ||
creep.memory.resetTarget = false; | ||
if (creep.carry.energy > 0) { | ||
const structure = creep.pos.findClosestByRange(FIND_MY_STRUCTURES, { | ||
filter: (object) => object.energy < object.energyCapacity, | ||
|
@@ -94,7 +120,7 @@ roles.carry.handleMisplacedSpawn = function(creep) { | |
} | ||
}; | ||
|
||
roles.carry.preMove = function(creep, directions) { | ||
roles.carry.preMove = function(creep, directions, routeLength, pathLength) { | ||
roles.carry.checkHelperEmptyStorage(creep); | ||
|
||
if (roles.carry.handleMisplacedSpawn(creep)) { | ||
|
@@ -122,7 +148,9 @@ roles.carry.preMove = function(creep, directions) { | |
|
||
let reverse = false; | ||
if (!creep.memory.routing.reverse) { | ||
reverse = creep.checkForTransfer(directions.forwardDirection); | ||
if (config.carry.transferToCarry) { | ||
reverse = creep.checkForTransfer(directions.forwardDirection); | ||
} | ||
if (!reverse && creep.isStuck() && directions.backwardDirection) { | ||
const adjacentPos = creep.pos.getAdjacentPosition(directions.backwardDirection); | ||
if (adjacentPos.isValid()) { | ||
|
@@ -164,6 +192,35 @@ roles.carry.preMove = function(creep, directions) { | |
} | ||
|
||
reverse = creep.pickupWhileMoving(reverse); | ||
|
||
// recycle carry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not like the recycling idea sooo much. If there is a problem with too many carries, the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The ultimate solution to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with adding this one and I'm also not so sure about the perfect solution, especially due to the fact that paths should be shared over multiple sources, which makes it more tricky. |
||
if (pathLength) { | ||
const routing = creep.memory.routing; | ||
if (routing.routePos === routeLength - 1 && routing.pathPos === pathLength - 2) { | ||
if (creep.isStuck() && !reverse) { | ||
creep.memory.resetTarget = true; | ||
} | ||
roles.carry.ensureOne(creep); | ||
} | ||
} | ||
if (creep.memory.resetTarget) { | ||
reverse = true; | ||
creep.say('reset'); | ||
if (creep.inBase()) { | ||
if (creep.ticksToLive > config.carry.recycleThreshold && roles.carry.reset(creep)) { | ||
creep.memory.resetTarget = false; | ||
} else { | ||
const spawn = creep.pos.findClosestByRangePropertyFilter(FIND_MY_STRUCTURES, 'structureType', [STRUCTURE_SPAWN]); | ||
if (spawn && spawn.recycleCreep(creep) === 'OK') { | ||
return true; | ||
} else if (creep.memory.routing.pathPos === 0) { | ||
creep.memory.recycle = true; | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (reverse) { | ||
// creep.log('reverse'); | ||
directions.direction = directions.backwardDirection; | ||
|
@@ -249,6 +306,10 @@ roles.carry.action = function(creep) { | |
|
||
creep.memory.routing.reached = false; | ||
creep.memory.routing.reverse = true; | ||
if (!creep.memory.helper) { | ||
creep.memory.resetTarget = true; | ||
roles.carry.ensureOne(creep); | ||
} | ||
|
||
return true; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what the intention is.
The default behavior should be that carries transfer to carries. If I understand the implementation correct, that would be disabled here.
And there are two methods, something like
transferToCreep
which actually transferrs and something likecheckForTransfer
which lets the carry move in the other direction because it will get energy in this tick.Both needs to be adapted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can swap carries' target when they transfer to each other.