寻找能量最高的结构
Finding structure with highest energy screeps
所以我有一个名为 storer
的 creep 角色,它应该从容器中获取能量并将其带到存储中。然而,目前,它会找到距离路径最近且能量水平大于某个阈值的容器,这样它就不会在每次矿工重新装满容器时都在那里等待数小时。
我遇到的问题是,如果我降低阈值,storer
将 运行 来回移动到相同的容器,忽略房间内更远的任何容器并让它们填满。
而提高门槛会让他在外面等太久,没有足够的时间清空容器,因此仓库几乎一直都是空的。
我需要一种方法让 creep 确定能量最高的容器并从那里填满。
这是其 运行ning 的代码:
if ((source = creep.pos.findClosestByPath(FIND_STRUCTURES, {filter: (s) => {return (s.structureType == STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] >= 150)}})) != undefined) {
if (creep.withdraw(source, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo(source);
}
}
编辑:这是我试过的代码,但我觉得它使用了太多 CPU 功率并且可以用更好的方式完成:
for (let i = 2000; i>=0; i=i-100) {
source = creep.pos.findClosestByPath(FIND_STRUCTURES, {filter: (s) => {return s.structureType == STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] >= i}});
if (source != undefined) {
break;
}
}
if (creep.withdraw(source, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo(source);
}
}
为什么不让过滤器为您做所有事情,为什么不 return 一个符合您标准的结构列表,然后找出列表中哪个结构具有最大能量?像这样的东西会找到所有的容器,找出哪个容器的能量最多,如果你的能量并列,选择最近的一个(直线,不考虑障碍物)。
var sources = creep.room.find(FIND_STRUCTURES, {
filter: (structure) => {
return (structure.structureType == STRUCTURE_CONTAINER);
}
});
var maxAmount = -1;
var maxSource = null;
var maxRange = 100;
for (var i = 0; i < sources.length; i++) {
if (sources[i].store[RESOURCE_ENERGY] >= maxAmount) {
var range = creep.pos.getRangeTo(sources[i]);
if (sources[i].store[RESOURCE_ENERGY] > maxAmount || range < maxRange) {
maxAmount = sources[i].store[RESOURCE_ENERGY];
maxSource = sources[i];
maxRange = range;
}
}
}
console.log(maxAmount);
console.log(maxSource);
console.log(maxRange);
你可以做的是遍历所有容器一次,了解它们的能量水平并选择最高的一个。在 creep 工作时设置一个值,这样 creep 就不会移动到另一个容器,如果他变得更高。
这是我为存储角色编写的代码:
module.exports = {
run: function( creep ) {
// Setting the working variable so the creep focus
// on getting the ressource or returning it.
if ( creep.memory.working && creep.carry.energy == 0 ) {
creep.memory.working = false;
}
if ( ! creep.memory.working && creep.carry.energy == creep.carryCapacity ) {
creep.memory.working = true;
creep.memory.targetContainer = false;
}
if ( creep.memory.working ) {
// Bring the ressources to the storage.
var theStorage = creep.pos.findClosestByRange(FIND_MY_STRUCTURES, {
filter: (structure) => {
return (structure.structureType == STRUCTURE_STORAGE );
}
});
if ( creep.transfer( theStorage, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo( theStorage );
}
} else {
// If the creep have a target.
if ( creep.memory.targetContainer ) {
// Go to the container.
var theContainer = Game.getObjectById( creep.memory.targetContainer );
if ( creep.withdraw( theContainer, RESOURCE_ENERGY ) == ERR_NOT_IN_RANGE ) {
creep.moveTo( theContainer );
}
} else {
// Find the container with the most energy.
var target = creep.room.find( FIND_STRUCTURES, {
filter: (structure) => {
return (structure.structureType == STRUCTURE_CONTAINER );
}
});
if ( target.length ) {
var allContainer = [];
// Calculate the percentage of energy in each container.
for ( var i = 0; i < target.length; i++ ) {
allContainer.push( { energyPercent: ( ( target[i].store.energy / target[i].storeCapacity ) * 100 ), id: target[i].id } );
}
// Get the container containing the most energy.
var highestContainer = _.max( allContainer, function( container ){ return container.energyPercent; });
console.log( 'Going for the container id "' + highestContainer.id + '" at ' + highestContainer.energyPercent + '% full.' );
// set the target in memory so the creep dosen't
// change target in the middle of the room.
creep.memory.targetContainer = highestContainer.id;
}
}
}
}
};
我不知道这个方法是否使用更多CPU,但是使用JavaScript的内置排序方法要简单得多。它允许根据任何 属性 或涉及它的计算对数组中的对象进行排序。如果您想查看完整语法和一些示例:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
此代码应该适合您的目的。 A 和 B 是它比较的数组的两个部分。 return 部分告诉它对数组元素进行比较。
var sources = creep.pos.findClosestByPath(FIND_STRUCTURES,
{filter: (s) => {return (s.structureType == STRUCTURE_CONTAINER &&
s.store[RESOURCE_ENERGY] >= 150)
}});
sources.sort(function(a, b) {return b.store[RESOURCE_ENERGY] - a.store[RESOURCE_ENERGY]});
然后只需 运行 您的正常代码即可从源头获取能量。如果它开始从能量最少的那个开始吸收能量,我可能在 return 部分弄错了 a 和 b 的顺序,所以只需翻转它们即可。
所以我有一个名为 storer
的 creep 角色,它应该从容器中获取能量并将其带到存储中。然而,目前,它会找到距离路径最近且能量水平大于某个阈值的容器,这样它就不会在每次矿工重新装满容器时都在那里等待数小时。
我遇到的问题是,如果我降低阈值,storer
将 运行 来回移动到相同的容器,忽略房间内更远的任何容器并让它们填满。
而提高门槛会让他在外面等太久,没有足够的时间清空容器,因此仓库几乎一直都是空的。
我需要一种方法让 creep 确定能量最高的容器并从那里填满。
这是其 运行ning 的代码:
if ((source = creep.pos.findClosestByPath(FIND_STRUCTURES, {filter: (s) => {return (s.structureType == STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] >= 150)}})) != undefined) {
if (creep.withdraw(source, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo(source);
}
}
编辑:这是我试过的代码,但我觉得它使用了太多 CPU 功率并且可以用更好的方式完成:
for (let i = 2000; i>=0; i=i-100) {
source = creep.pos.findClosestByPath(FIND_STRUCTURES, {filter: (s) => {return s.structureType == STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] >= i}});
if (source != undefined) {
break;
}
}
if (creep.withdraw(source, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo(source);
}
}
为什么不让过滤器为您做所有事情,为什么不 return 一个符合您标准的结构列表,然后找出列表中哪个结构具有最大能量?像这样的东西会找到所有的容器,找出哪个容器的能量最多,如果你的能量并列,选择最近的一个(直线,不考虑障碍物)。
var sources = creep.room.find(FIND_STRUCTURES, {
filter: (structure) => {
return (structure.structureType == STRUCTURE_CONTAINER);
}
});
var maxAmount = -1;
var maxSource = null;
var maxRange = 100;
for (var i = 0; i < sources.length; i++) {
if (sources[i].store[RESOURCE_ENERGY] >= maxAmount) {
var range = creep.pos.getRangeTo(sources[i]);
if (sources[i].store[RESOURCE_ENERGY] > maxAmount || range < maxRange) {
maxAmount = sources[i].store[RESOURCE_ENERGY];
maxSource = sources[i];
maxRange = range;
}
}
}
console.log(maxAmount);
console.log(maxSource);
console.log(maxRange);
你可以做的是遍历所有容器一次,了解它们的能量水平并选择最高的一个。在 creep 工作时设置一个值,这样 creep 就不会移动到另一个容器,如果他变得更高。
这是我为存储角色编写的代码:
module.exports = {
run: function( creep ) {
// Setting the working variable so the creep focus
// on getting the ressource or returning it.
if ( creep.memory.working && creep.carry.energy == 0 ) {
creep.memory.working = false;
}
if ( ! creep.memory.working && creep.carry.energy == creep.carryCapacity ) {
creep.memory.working = true;
creep.memory.targetContainer = false;
}
if ( creep.memory.working ) {
// Bring the ressources to the storage.
var theStorage = creep.pos.findClosestByRange(FIND_MY_STRUCTURES, {
filter: (structure) => {
return (structure.structureType == STRUCTURE_STORAGE );
}
});
if ( creep.transfer( theStorage, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
creep.moveTo( theStorage );
}
} else {
// If the creep have a target.
if ( creep.memory.targetContainer ) {
// Go to the container.
var theContainer = Game.getObjectById( creep.memory.targetContainer );
if ( creep.withdraw( theContainer, RESOURCE_ENERGY ) == ERR_NOT_IN_RANGE ) {
creep.moveTo( theContainer );
}
} else {
// Find the container with the most energy.
var target = creep.room.find( FIND_STRUCTURES, {
filter: (structure) => {
return (structure.structureType == STRUCTURE_CONTAINER );
}
});
if ( target.length ) {
var allContainer = [];
// Calculate the percentage of energy in each container.
for ( var i = 0; i < target.length; i++ ) {
allContainer.push( { energyPercent: ( ( target[i].store.energy / target[i].storeCapacity ) * 100 ), id: target[i].id } );
}
// Get the container containing the most energy.
var highestContainer = _.max( allContainer, function( container ){ return container.energyPercent; });
console.log( 'Going for the container id "' + highestContainer.id + '" at ' + highestContainer.energyPercent + '% full.' );
// set the target in memory so the creep dosen't
// change target in the middle of the room.
creep.memory.targetContainer = highestContainer.id;
}
}
}
}
};
我不知道这个方法是否使用更多CPU,但是使用JavaScript的内置排序方法要简单得多。它允许根据任何 属性 或涉及它的计算对数组中的对象进行排序。如果您想查看完整语法和一些示例:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
此代码应该适合您的目的。 A 和 B 是它比较的数组的两个部分。 return 部分告诉它对数组元素进行比较。
var sources = creep.pos.findClosestByPath(FIND_STRUCTURES,
{filter: (s) => {return (s.structureType == STRUCTURE_CONTAINER &&
s.store[RESOURCE_ENERGY] >= 150)
}});
sources.sort(function(a, b) {return b.store[RESOURCE_ENERGY] - a.store[RESOURCE_ENERGY]});
然后只需 运行 您的正常代码即可从源头获取能量。如果它开始从能量最少的那个开始吸收能量,我可能在 return 部分弄错了 a 和 b 的顺序,所以只需翻转它们即可。