首页 > 解决方案 > 在Javascript forEach中,循环直到函数结果不为假

问题描述

我正在用 javascript 构建一个战舰游戏。

我想要的是:在 forEach 循环中,一次又一次地执行一个函数,直到结果不为假。

我正在尝试编写 DRY 代码。这个结果有效,但需要不必要的重复,必须有一个更简单、更优雅的方法来获得这个结果。

设置是这样的:游戏有一个由许多 boardUnit 对象组成的棋盘。每个 boardUnit 都有一个坐标和一个布尔值来指定上面是否有船(hasShip:false 或 true)。

船舶根据其长度占用多个单元(长度为 1、2、3、4 或 5)

我想要的结果是这样的:

  1. 根据船长生成一组顺序随机坐标(示例 [[3,1],[3,2],[3,3]])// 工作正常
  2. 检查具有匹配坐标的 boardUnits 以查看 hasShip 是 false 还是 true // 工作正常
  3. 如果任何 boardUnits 具有 hasShip:true,则生成新坐标并重复循环 // 这里是我需要帮助的地方
  4. 如果所有 boardUnits 都具有 hasShip:false,则更新 boardUnits,以便选定坐标将 hasShip 设置为 true。// 工作正常
let ships = [{ length: 3 }, { length: 2 }, { length: 5 }];
let boardUnits = [
  { name: "unit1", coordinates: [1, 1], hasShip: false },
  { name: "unit2", coordinates: [1, 2], hasShip: false },
  // and on to 100
];

function placePlayerShipsOnBoard(player) {
  //The following function should be executed until result is not false

  function placeShipInUnit(coordinates, ship) {
    // Find input coordinates in boardUnits
    // Returns array of boardUnits (Ex. [{name:unit 31, coordinates: [3,1], hasShip: false},{name:unit 32, coordinates: [3,2], hasShip: false}, {name:unit 33, coordinates: [3,3], hasShip: false}])

    let selectedUnits = filterUnit(coordinates);

    // Checks if any of the board Units has hasShip:true. If unit has a ship, exits function

    if (!spaceChecker(selectedUnits)) {
      return false;
    }

    // Clones boardUnits, and updates units with specified coordinates with hasShip:true (Ex. {name:unit 33, coordinates: [3,3], hasShip: true})

    boardUnits = updateUnits(boardUnits, selectedUnits, true);
  }

  // ****** This is the function I need help with

  ships.forEach((ship) => {
    // Generate array of coordinates based on ship length (Ex. Ship of length three results in  [[3,1],[3,2],[3,3]]). Works OK

    const coordinates = generateRandomCoordinates();

    // Check if function is false. If false, it means that the units in the specified coordinates have a ship. Need help.

    checkIfValid = placeShipInUnit(shipCoordinates, ship);

    // If all boardUnits have hasShip: false, then execute function that changes "hasShip" to true in specified boardUnits. Need help.

    if (checkIfValid != false) {
      placeShip(shipCoordinates, ship);
    }
  });
}


标签: javascriptloopsecmascript-6foreach

解决方案


Array.prototype.every以及Array.prototype.some用于任何基于布尔值的数组条目验证的工具......

let isEmptyCoordinates = coordinates.every(coordinate =>
  !boardUnits[coordinate[0]][coordinate[1]].hasShip
);
if (isEmptyCoordinates) {
  placeShip(coordinates, ship);
}

... 甚至 ...

if (coordinates.every(coordinate =>
  !boardUnits[coordinate[0]][coordinate[1]].hasShip
)) {
  placeShip(coordinates, ship);
}

推荐阅读