@mk11

Почем цикл do while вызывает зависание страниц браузера?

Есть функция:
function generator(gameBorad, boardSize, maxBombs) {
    let bombs = [];
    do {
        let x = getRandom();
        let y = getRandom();
        if (bombs.length == 0) continue;
        for (bomb in bombs) {
            if (!(bomb.x == x && bomb.y == y)) {
                bombs.push({
                    x: x,
                    y: y
                });
                console.log('+1');
            } 
        }
    } while (bombs.length < maxBombs)
    console.log(bombs);
}

При ее использовании страницы браузера, да и сам браузер зависают, скорее всего это из-за цикла, но почему так происходит?
UPD: если убрать
for (bomb in bombs) {
            if (!(bomb.x == x && bomb.y == y)) {

то все работает, что с этим не так не могу понять...
  • Вопрос задан
  • 119 просмотров
Решения вопроса 1
sergiks
@sergiks Куратор тега JavaScript
♬♬
Предложил бы редуцировать измерения )
свести двумерное поле к одномерной колбасе.

Если поле 6x6, то это одномерный массив длиной 36 элементов. Каждый элемент — одна из клеток на поле.
Номер элемента однозначно переводится в координаты (x, y), если известна длина стороны поля.

Например, поле 6x6. Нумерация от нуля: 0..5 Число, допустим, 13.
X = 13 % 6 = 1 
Y = floor(13 / 6) = 2

Теперь, из колбасы всех возможностей надо отобрать случайным образом сколько требуется случайных.

В цикле брать один случайный элемент из оставшихся в колбасе. Причём забирать, вынимать его оттуда, сокращая массив оставшихся возможностей.

Так не понадобится холостых повторных попаданий в ранее выбранные клетки. Не понадобится по два случайных генерить. Один рандом — одно 100% попадание.

function generator(quantity, side = 6) {
  const length = side * side;
  if (quantity > length) throw new Error('too much u ask');

  const options = Array.from({ length }, (_, i) => i); // [0,1,2,3, .. ,35]
  const nToPoint = n => ({ x: n % side, y: Math.floor(n / side) }); // 13 => {x:1, y:2}
  return Array.from({ length: quantity }, () =>
    nToPoint(
      options.splice(Math.floor(Math.random() * options.length), 1).pop()
    )
  );
}

console.log(generator(4));
// [{x:1,y:2}, {x:0,y:4}, {x:1,y:0}, {x:4,y:4}]
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
noder_ss
@noder_ss
Линуксоид-энтузиаст и SQL разработчик
Цикл вызывает лаги только в том случае, если условие бесконечное. Должно быть, в коде ошибка
Ответ написан
@AUser0
Чем больше знаю, тем лучше понимаю, как мало знаю.
На сколько я понимаю, для каждой уже добавленной бомбы добавляется ещё одна бомба. То есть 1б+=1б -> 2б+=2б -> 4б+=4б, и т.д. При чём все добавленные бомбы - с одними и теми же координатами, ведь x,y при каждом добавлении не меняются. И добавление идёт в конец массива, то есть for(bomb in bombs) должна и по этим добавленным бомбам тоже пройтись с проверкой.

P.S. Может сделать тривиальное for(i=0;i++;i<maxBombs){}?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы