首页 > 解决方案 > 有没有办法查看二维数组中的值是否与另一个二维数组中的任何值匹配?

问题描述

我正在用 Javascript 和 React 构建一个战舰游戏,即使经过大量谷歌搜索和 StackOverflowing 之后,我也已经在这个问题上停留了一段时间。

基本上我的电路板是一个二维数组,一个数组中有 10 个数组。我正在尝试随机放置船只,但我在检查一艘船是否与另一艘船相交时遇到了困难。

这是我为我的船准备的:

placeShips = () => {
        // Logic to place boats randomly below

        // Checks required before placing a boat:
        // 1. Does the boat go off the board
        // 2. Does the boat overlap another boat
        // 3. If checks above pass then place boat


        let placedPosition = []
        let board = this.state.board.slice()
        let i
        for (i = 0; i < this.state.ships.length; i++) {
            // First randomly select coordinates for where the boat will start
            let xcoord = Math.floor(Math.random() * 10)
            let ycoord = Math.floor(Math.random() * 10)

            // Get positions in array where a boat will be
            let potentialBoat = []
            let newCoords

            let j
            for (j = 0; j < this.state.ships[i].getLength(); j++) {
                newCoords = [xcoord, ycoord + j]
                potentialBoat.push(newCoords)

第一个 for 循环对留在我所在州的每艘船重复放置,第二个 for 循环采用船的长度,获取预期的坐标(例如,[[0, 1], [0,2]] 用于 2 长度的船)并将其存储在 potentialBoat 数组中。

我的想法是使用这个 potentialBoat 数组,看看是否有任何 [xcoordinate, ycoordinate] 已经存在于placedPosition 数组中,如果是,则再次循环当前船并获取新坐标,直到它们不相交。

这可能吗?还是我应该重新考虑我的整个实施?谢谢!

标签: javascriptarraysmultidimensional-array

解决方案


在内部循环中,在创建船的过程中,考虑创建一个表示坐标的字符串。例如,对于newCoordsof 1, 3,创建一个字符串1_3要验证位置,请检查该字符串是否存在于已验证船舶位置的数组(或集合)中。在内部循环结束时,一旦验证了船长的所有位置,将可能的位置组合到验证位置数组中:

placeShips = () => {
  const placedPosition = [];
  const board = this.state.board.slice();
  const validatedPositionStrings = []; // <---- Create this array
  for (const ship of this.state.ships) {
    const thisShipLength = ship.getLength();
    tryShip:
    while (true) {
      const thisBoatPossiblePositionStrings = [];
      // Generate ship positions until valid
      const xcoord = Math.floor(Math.random() * 10);
      const ycoord = Math.floor(Math.random() * 10);
      const potentialBoat = [];
      for (let j = 0; j < thisShipLength; j++) {
        // Then check to see if the below position is already in it
        const thisCoordinateString = `${x}_${y}`; 
        if (validatedPositionStrings.includes(thisCoordinateString)) {
          // Invalid
          continue tryShip;
        }
        thisBoatPossiblePositionStrings.push(thisCoordinateString);

        // If this point is reached, then this particular coordinate is valid
        // do whatever you need to do:
        const newCoords = [xcoord, ycoord + j];
        potentialBoat.push(newCoords);
      }
      // All positions for ship are valid
      // do something with potentialBoat here?
      // push positions to placedPosition?
      validatedPositionStrings.push(...thisBoatPossiblePositionStrings);
      break;
    }
  }
}

通过使用 Set 而不是数组,可以降低计算复杂性,但这可能无关紧要,除非有大量的迭代。

也可以搜索您的数组数组以查看该位置是否已放置,但这将需要大量的代码 IMO。

如果可能,您可能会考虑更改数据结构,以便您只有一个表示坐标的对象,而不是数组数组,其值指示该位置的船(以及特定点所需的可能其他属性),例如:

{
  1_3: { ship: 'destroyer', 'attackedYet': 'false' }
  // ...

这样的对象可能比 XY 对数组更容易查找和处理。


推荐阅读