如何使用Array.prototype.map向战舰游戏二维网格无突变插入带索引的ship对象
问题排查
你遇到的两个问题根源如下:
返回undefined的原因
- 内层
map回调没有设置返回值:匹配到目标坐标时没有return你定义的ship对象,非目标坐标也没有return原元素,导致所有元素处理后都为undefined - 现有逻辑只覆盖了单个坐标的判断,完全没有处理
ship.length对应的多格舰船填充逻辑
index值计算逻辑缺失
你需要先约定舰船放置方向(下方示例默认横向放置,可扩展参数支持纵向):
- 横向放置时,舰船固定在第
x行,占据y到y + ship.length - 1列,每个位置的index为当前列索引 - 起始y值 - 纵向放置时,舰船固定在第
y列,占据x到x + ship.length - 1行,每个位置的index为当前行索引 - 起始x值
完整实现方案
首先补充边界校验逻辑(避免舰船越界、重叠),再通过双层map生成新网格,符合纯函数要求无副作用:
const placeShip = (grid, ship, x, y, direction = 'horizontal') => { // 前置校验:越界直接返回原网格 const maxX = direction === 'horizontal' ? x : x + ship.length - 1; const maxY = direction === 'horizontal' ? y + ship.length - 1 : y; if (maxX >= grid.length || maxY >= grid[0].length) return grid; // 前置校验:位置重叠直接返回原网格 const isOccupied = Array.from({length: ship.length}).some((_, i) => { const currX = direction === 'horizontal' ? x : x + i; const currY = direction === 'horizontal' ? y + i : y; return grid[currX][currY] !== null; }) if (isOccupied) return grid; // 生成新网格,不修改原数组 return grid.map((row, indexX) => row.map((element, indexY) => { // 横向放置判断 if (direction === 'horizontal') { if (indexX === x && indexY >= y && indexY < y + ship.length) { return { name: ship.name, index: indexY - y } } } // 纵向放置判断 else { if (indexY === y && indexX >= x && indexX < x + ship.length) { return { name: ship.name, index: indexX - x } } } // 非舰船位置返回原元素 return element; })) }
调用示例
// 原5*5空白网格 const originalGrid = Array.from({length:5}, () => Array(5).fill(null)); // 定义长度为2的小艇 const boat = {name: 'boat', length: 2}; // 放置舰船:在第0行,第1列开始横向放置 const newGrid = placeShip(originalGrid, boat, 0, 1); /* 生成的newGrid第0行结果为: [null, {name: 'boat', index:0}, {name: 'boat', index:1}, null, null] */
内容的提问来源于stack exchange,提问作者LearningPython
相关产品推荐
相关产品推荐

