【问题标题】:Finding structure with highest energy screeps寻找能量最高的结构
【发布时间】:2016-11-15 23:19:13
【问题描述】:

所以我有一个名为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);
    }
}

【问题讨论】:

  • 您“感觉”它使用了过多的 CPU?还是您对其进行了分析并确定它实际上使用了过多的 CPU?
  • 我设法通过减少迭代次数来减少它的 cpu 使用率,即它减少了 100 而不是 1。但是是的,它仍然消耗更多的 CPU 功率,而目前的 CPU 功率就是我的'我在游戏中真的很缺乏

标签: javascript algorithm loops screeps


【解决方案1】:

与其让过滤器为您做所有事情,不如返回一个符合您条件的结构列表,然后找出列表中哪个结构的能量最大?像这样的东西会找到所有容器,找出哪个能量最多,如果能量相同,则选择最近的一个(直线,不考虑障碍)。

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

【讨论】:

    【解决方案2】:

    您可以做的是循环遍历所有容器一次,获取它们的能量水平并选择最高的一个。在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;
    
                }
            }
        }
      }
    };
    

    【讨论】:

    • 如果容器太低,存储者会一直靠近其中一个,直到他满了。如果你不想这样,你可以在他选择能量时改变工作变量。 if ( ! creep.memory.working &amp;&amp; creep.carry.energy &gt; 0 )
    【解决方案3】:

    我不知道这种方法是否使用更多的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 的顺序,所以只需翻转它们即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-26
      • 2010-12-12
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      相关资源
      最近更新 更多