寻找具有最高能量尖锐的结构

时间:2016-07-13 11:31:22

标签: javascript algorithm loops screeps

所以我有一个名为storer的蠕变角色应该从容器中获取能量并将其带到存储中。然而,目前,它发现容器最接近Path并且能量水平大于某个阈值,因此每次矿工重新填充容器时它不会在那里等待几个小时。

我遇到的问题是如果我降低阈值,storer将来回运行相同的容器,忽略房间内的任何容器并让它们填满。
提高门槛将使他坐下来等待太久,没有给他足够的时间来清空容器,因此存储器几乎一直都是空的。

我需要一种方法让蠕变来确定具有最高能量的容器并从那里填满。

这是运行的代码:

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);
    }
}

3 个答案:

答案 0 :(得分:5)

你可以做的是将所有容器循环一次,获得能量水平并选择最高容量。当蠕变工作时设置一个值,这样蠕变就不会移动到另一个容器,如果他变高了。

这是我为商店角色所做的代码:

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;

            }
        }
    }
  }
};

答案 1 :(得分:2)

我不知道这种方法是否使用了更多的CPU,但使用JavaScript的内置排序方法要简单得多。它允许根据涉及它的任何属性或计算对数组中的对象进行排序。如果您想查看完整语法和一些示例:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

此代码适用于您的目的。 A和B是它比较的两个数组。返回部分告诉它对数组元素进行比较。

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]});

然后只需运行您的常规代码即可从源中获取能量。如果它开始从能量最少的能量中获取能量,我可能在返回部分得到a和b的顺序,所以只需翻转它们。

答案 2 :(得分:0)

为什么不返回符合条件的结构列表,然后找出列表中哪个结构最耗能?像这样的东西会找到所有的容器,找出能量最多的容器,如果你有能量的平衡点,那就选择最接近的容器(直线,不考虑障碍物)。

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);