Screeps路径计算一致性问题:如何固定容器放置位置?
解决Room布局中容器位置不稳定的问题
这个问题我之前也碰到过——Jump Point寻路算法确实会因为存在多条长度相同的等效路径,每次运行返回不同的路径结果,导致你依赖路径末尾位置的容器放置逻辑不稳定。要解决这个问题,核心思路是不依赖寻路的动态结果,而是直接筛选符合条件的固定位置,具体可以这么做:
方法思路:直接锁定符合要求的最优位置
我们的目标是找「距离Controller仅1格、且离Spawn最近的可放置容器的位置」,完全可以跳过寻路步骤,直接定位这类位置并按固定规则排序选择:
- 先获取Controller周围所有相邻的位置(距离1格的区域)
- 过滤掉不能放置容器的位置(比如墙、已有建筑/建筑工地的位置)
- 把剩下的有效位置按「离Spawn的距离由近到远」排序,距离相同的情况下按固定的坐标顺序(比如x轴升序,再y轴升序)排序,确保每次选同一个点
- 最后取排序后的第一个位置创建容器建筑工地
修改后的代码示例
Room.prototype.layoutRoom = function(){ var s = this.spawns()[0]; var c = this.controller; // 1. 获取Controller周围1格的所有相邻位置 const controllerAdjacent = c.pos.getAdjacentPositions(); // 2. 过滤出可放置容器的有效位置 const validPositions = controllerAdjacent.filter(pos => { const terrain = this.getTerrain().get(pos.x, pos.y); // 排除墙、已有建筑、已有建筑工地的位置 const hasStructure = this.lookForAt(LOOK_STRUCTURES, pos.x, pos.y).length > 0; const hasConstruction = this.lookForAt(LOOK_CONSTRUCTION_SITES, pos.x, pos.y).length > 0; return terrain !== TERRAIN_MASK_WALL && !hasStructure && !hasConstruction; }); if (validPositions.length === 0) { console.log('No valid position for container near controller'); return; } // 3. 按固定规则排序:先离Spawn近,再x升序,再y升序 validPositions.sort((a, b) => { const distA = s.pos.getRangeTo(a); const distB = s.pos.getRangeTo(b); if (distA !== distB) { return distA - distB; } if (a.x !== b.x) { return a.x - b.x; } return a.y - b.y; }); // 4. 取第一个固定位置创建容器 const loc = validPositions[0]; console.log('layout room, put container: '+loc.x+' '+loc.y); this.createConstructionSite(loc.x, loc.y, STRUCTURE_CONTAINER); }
为什么原来的方法不稳定?
你之前的代码依赖findPath返回的路径末尾第3个点,但Jump Point寻路在遇到多条长度相同的路径时,每次可能随机返回其中一条,导致path数组的内容变化,自然path[path.length-3]的位置也会跟着变。而直接筛选+固定排序的方式,完全不依赖寻路的动态结果,能确保每次运行都选中同一个位置。
另外,代码里还加了「检查是否已有建筑/建筑工地」的逻辑,避免重复创建多个建筑工地的问题。
内容的提问来源于stack exchange,提问作者Rilcon42
相关产品推荐
相关产品推荐

