#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
было само по себе.
Смотрите:
- elementFromPoint
- offsetLeft из MDN.