基于一维数组的移动范围检测实现需求
实现带移动范围限制的路径生成功能
我来帮你搞定这个路径生成的需求,完全符合你提到的八方向移动、步数限制以及mask范围约束的要求。先理清楚需求细节:
需求细节
- 地图与图例:
0= 空地板(可移动)1= 墙体(不可移动)2= 起点3= 起点可到达的地板
- 移动规则:支持水平、垂直、对角线八方向移动,仅能移动到值为
0的位置,对角线可穿过墙体间的0位置 - 参数支持:可扩展至15x9规格地图,步数范围最大6
- 进阶需求:支持一维mask数组(
0表示该位置超出可移动范围,即使在步数内也不能到达)
示例数据
原始一维地图数组:
[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0]
示例mask数组:
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0]
现有代码框架
你提供的基础代码如下:
<div id="results" style="font-family: monospace; font-weight: bold; font-size: 24pt; background-color: #000000; color: #FFFFFF;"> </div> <script> var map=[0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,0,0,]; var mask=[0,0,0,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,]; function path_create(map,width,height,point,range,mask) { // map = pure map with 0 as floor and 1 as wall // width, height = size of map // point = starting point to calculate movement range // range = number of moves from starting point to each direction of horizontal, vertical, and diagonal // mask = (optional) if possible to do, array mask (0 is not in range) can change range for diagonal moves with special shapes like circle or rhombus var matrix=[]; return matrix; // one dimension array where 0 is no range, and 1 is ok } function path_show(matrix,width,height) { var v=""; for(var i=0; i<matrix.length; i++) { if(i!=0 && i%7==0){v=v+"<br>";} v=v+matrix[i]+" "; } document.getElementById('results').innerHTML=v; } path_show(path_create(map,7,7,25,3,mask)); //path_show(path_create(map,7,7,16,3,mask)); </script>
完善后的path_create函数实现
下面是完整的path_create函数实现,完全满足你的所有需求:
function path_create(map, width, height, point, range, mask) { // 先把一维数组转成二维矩阵方便处理坐标计算 const grid = []; for (let i = 0; i < height; i++) { grid.push(map.slice(i * width, (i + 1) * width)); } // 初始化结果矩阵,复制原始地图的值 const result = [...map]; // 设置起点为2 result[point] = 2; // 八方向移动的偏移量(上下左右+四个对角线) const directions = [ [-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 0], [1, 1] ]; // 用队列做广度优先搜索(BFS),记录每个位置的步数 const queue = []; // 计算起点的二维坐标 const startX = point % width; const startY = Math.floor(point / width); // 记录已访问的位置,避免重复处理 const visited = Array(height).fill().map(() => Array(width).fill(false)); visited[startY][startX] = true; // 队列元素格式:[x坐标, y坐标, 当前步数] queue.push([startX, startY, 0]); while (queue.length > 0) { const [x, y, steps] = queue.shift(); // 如果当前步数已经达到最大范围,跳过后续扩展 if (steps >= range) continue; // 遍历所有方向 for (const [dx, dy] of directions) { const newX = x + dx; const newY = y + dy; // 检查是否在地图边界内 if (newX < 0 || newX >= width || newY < 0 || newY >= height) continue; // 检查是否已经访问过 if (visited[newY][newX]) continue; // 检查是否是墙体(不可移动) if (grid[newY][newX] === 1) continue; // 检查mask约束:如果mask存在且当前位置mask为0,跳过 if (mask && mask[newY * width + newX] === 0) continue; // 标记为已访问 visited[newY][newX] = true; // 转换为一维索引 const idx = newY * width + newX; // 设置为可到达的地板(3) result[idx] = 3; // 加入队列,步数+1 queue.push([newX, newY, steps + 1]); } } return result; }
代码解释
- 二维矩阵转换:把一维地图转成二维数组,简化坐标计算逻辑
- BFS遍历:用广度优先搜索逐层扩展可移动范围,确保步数计算精准,严格符合“最多range步”的要求
- 八方向支持:定义8个方向的偏移量,覆盖所有水平、垂直和对角线移动路径
- Mask约束:如果传入mask数组,会优先检查目标位置的mask值,若为0则直接跳过,忽略步数限制
- 边界与墙体判断:确保不会移动到地图外或墙体上,同时标记已访问位置避免重复处理
- 结果生成:复制原始地图数据,设置起点为
2,可到达位置为3,其余保持原始值
把这个函数替换到你的代码里,就能得到你预期的结果啦~
内容的提问来源于stack exchange,提问作者ociebieda
相关产品推荐
相关产品推荐

