Как убедиться, что div никогда не касаются друг друга?

#javascript #html #css #arrays #ecmascript-6

#javascript #HTML #css #массивы #ecmascript-6

Вопрос:

Я создаю приложение для линкоров. Цель состоит в том, чтобы случайным образом генерировать корабли на доске каждый раз, когда страница обновляется. Моя проблема в том, что я должен убедиться, что корабли никогда не касаются друг друга, я просто не могу понять это.

Вот мой массив кораблей, каждый корабль в виде имени и двух направлений :

 const shipArray = [
        // sous marins x4
      
    {
      name: "destroyer",
      directions: [
        [0, 1],
        [0, width],
      ],
    },
    {
      name: "destroyer",
      directions: [
        [0, 1],
        [0, width],
      ],
    },
    {
      name: "destroyer",
      directions: [
        [0, 1],
        [0, width],
      ],
    },
    {
      name: "destroyer",
      directions: [
        [0, 1],
        [0, width],
      ],
    },

    //torpilleurs x3
    {
      name: "cruiser",
      directions: [
        [0, 1, 2],
        [0, width, width * 2],
      ],
    },
    {
      name: "cruiser",
      directions: [
        [0, 1, 2],
        [0, width, width * 2],
      ],
    },
    {
      name: "cruiser",
      directions: [
        [0, 1, 2],
        [0, width, width * 2],
      ],
    },
    //escorteurs x2
    {
      name: "battleship",
      directions: [
        [0, 1, 2, 3],
        [0, width, width * 2, width * 3],
      ],
    },

    {
      name: "battleship",
      directions: [
        [0, 1, 2, 3],
        [0, width, width * 2, width * 3],
      ],
    },
    //croiseur x1
    {
      name: "carrier",
      directions: [
        [0, 1, 2, 3, 4],
        [0, width, width * 2, width * 3, width * 4],
      ],
    },
  ];
  

Вот код, который случайным образом генерирует корабли на доске :

 function generate(ship) {
    
    let randomDirection = Math.floor(Math.random() * ship.directions.length);
    let current = ship.directions[randomDirection];
    if (randomDirection === 0) direction = 1;
    if (randomDirection === 1) direction = 10;
    
    let randomStart = Math.abs(
      Math.floor(
        Math.random() * userSquares.length -
          ship.directions[0].length * direction
      )
    );

    

    const isTaken = current.some((index) =>
      userSquares[randomStart   index].classList.contains("taken")
    );

    const isAtRightEdge = current.some(
      (index) => (randomStart   index) % width === width - 1
    );

    const isAtLeftEdge = current.some(
      (index) => (randomStart   index) % width === 0
    );

    if (!isTaken amp;amp; !isAtRightEdge amp;amp; !isAtLeftEdge)
      current.forEach((index) =>
        userSquares[randomStart   index].classList.add("taken", ship.name)
      );
    else generate(ship);
}

  generate(shipArray[0]);
  generate(shipArray[1]);
  generate(shipArray[2]);
  generate(shipArray[3]);
  generate(shipArray[4]);
  generate(shipArray[5]);
  generate(shipArray[6]);
  generate(shipArray[7]);
  generate(shipArray[8]);
  generate(shipArray[9]);

    
  

введите описание изображения здесь

Комментарии:

1. Если задача не имеет других ограничений и попытка поместить корабль в какое-либо случайно выбранное место является подходящим подходом, тогда вы можете представить, что каждый новый корабль имеет одно квадратное заполнение, а его размеры будут 3 x (2 ship_width) или (2 ship_height) x 3. Если корабль с заполнением не сталкивается с другими, вы можете разместить его без заполнения на доске.

2. Смотрите также Калькулятор вероятности линкора и ManInTheBox / battleship

Ответ №1:

Если вы хотите не создавать корабль на корабле:

Идея

Я обращусь к случайно сгенерированному кораблю theShip и любому кораблю aShip (возможно, добавьте имя класса к каждому кораблю).
Вы можете сравнить theShip.offsetLeft с elementFromPoint . Создайте функцию, которая выполняет следующее, и добавьте ее к функции, которая создает новые корабли после точки, в которой она создала корабль.

  • Установить theShip.style.pointerEvents = "none" .
  • Вернитесь и сгенерируйте новый корабль, если какой-либо из них aShip находится в theShip позиции.
     if (document.elementFromPoint(theShip.offsetLeft, theShip.offsetTop)) {return}
      

Вам нужно установить, theShip.style.pointerEvents = "none" чтобы это elementFromPoint не theShip было само по себе.

Смотрите: