使用 Array.prototype.map 将带有索引的对象插入到二维数组中

using Array.prototype.map to insert object with index into 2D array

对于上下文,这是针对经典战舰游戏的。

我有一个像这样的游戏板网格阵列:

[[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null]],

我正在尝试将一个 ship 对象放入数组中。该对象由一些属性组成,例如船的namelengthindex(以便在船对象上标记船被击中的位置)。例如,放在第一行的船可能如下所示:

[null, {name: 'boat' , index: 0 }, {name: 'boat' , index: 1 }, null, null]

我想使用函数式编程原则来实现这一点并避免改变数组,这正是我目前正在做的(即使用 for 循环和设置 array[x][y] = {ship})。

我知道实现此目的的最佳方法是使用 map()

由于数组是二维的,所以我将两个地图嵌套在一起。到目前为止,我的功能如下所示:

const placeShip = (ship, x, y) => {
    if (grid[x][y] !== null) return;
    const newGrid = grid.map((row, indexX) => row.map((element, indexY) => {
      if (indexX === x && indexY === y) {
        {
          name: ship.name,
          index: XXX
        } // how to insert the index position?
      }
    }
    return newGrid
  }

我遇到的麻烦是双重的。首先,我无法弄清楚如何使用嵌套地图将船舶的索引位置正确插入对象中。使用 for 循环非常简单,因为它们从 0 开始并在 ship.length 结束。

其次,我哪里出错了,我的函数没有返回一个包含任何对象的二维数组,我只是收到 undefined.

我哪里错了?

谢谢

如果你只考虑水平放置的船只,你可以像这样检查船只是否出现在瓷砖上:

ri === r &&    // The ship sails on the current row
ci >= c &&     // The start of the ship lies left of this column
ci < c + size  // The end of the ship lies right of this column

然后,0shipSize 之间的索引可以使用以下公式计算:ci - c

这是一个简化的例子:

const grid = Array.from(Array(4), () => Array(4).fill("~~"));

const placeShipH = (r, c, size, name, grid) => grid.map(
  (row, ri) => row.map(
    (col, ci) => ri === r && ci >= c && ci < c + size
      ? `${name}${ci - c + 1}`
      : col
  )
);

const placeShipV = (r, c, size, name, grid) => grid.map(
  (row, ri) => row.map(
    (col, ci) => ci === c && ri >= r && ri < r + size
      ? `${name}${ri - r + 1}`
      : col
  )
);

const gridToString = grid => grid.map(row => row.join(" ")).join("\n");

const afterShipA = placeShipH(1, 1, 2, "A", grid);
const afterShipB = placeShipH(3, 0, 3, "B", afterShipA);
const afterShipC = placeShipV(0, 3, 3, "C", afterShipB)

console.log(gridToString(afterShipC));