JavaScript

Javascript как сделать так, чтобы два рандомных числа в одном цикле не повтрялись

Делаю игру наподобие сапера. Нужно сгенерировать рандомное число, которое будет индексом клетки таблицы с бомбой. Но дело в том, что часто одно и тоже число генерируется два раза (делаю с помощью цикла) и вместо трех бомбочек появляется две. Это нужно как-то исправить, но в голову вообще ничего не приходит.
Вот код:
//Функция отрисовки таблицы (поля)
var drawGrid = function (){
var gameZone = document.querySelector("#gameGrid");
var gameZoneHTML = "";
for (var i = 0; i < gridSize; i++){
gameZoneHTML += "";

for (var j = 0; j< gridSize; j++){
gameZoneHTML += ""
};
gameZoneHTML += "";
}
gameZone.innerHTML = gameZoneHTML;
}
//Функция генерации бомбочек легкой сложности
var placeBombsEasy = function(){
for (i = 0; i<3; i++){
var tds = document.querySelectorAll("td");
tds[Math.floor(Math.random()*25)].classList.add("bomb")}
}
//Функция генерации бомбочек средней сложности
var placeBombsNorm = function(){
for (i = 0; i<9; i++){
var tds = document.querySelectorAll("td");
tds[Math.floor(Math.random()*49)].classList.add("bomb")}
}
//Функция генерации бомбочек сложной сложности
var placeBombsHard = function(){
for (i = 0; i<15; i++){
var tds = document.querySelectorAll("td");
tds[Math.floor(Math.random()*100)].classList.add("bomb")}
}
//Добавляем переменную размера поля
var gridSize;
//Выбираем кнопку "легкая"
var difEasy = document.querySelector("#difEasy");
//Выбираем кнопку "нормальная"
var difNorm = document.querySelector("#difNorm");
//Выбираем кнопку "сложная"
var difHard = document.querySelector("#difHard");
//Если нажали на кнопку "легкая", построить таблицу 5х5 и расположить 3 бомбы
difEasy.addEventListener("click", function(){
gridSize = 5;
drawGrid();
placeBombsEasy();
});
//Если нажали на кнопку "нормальная", построить таблицу 7х7 расположить 9 бомб
difNorm.addEventListener("click", function(){
gridSize = 7;
drawGrid();
placeBombsNorm();
});
//Если нажали на кнопку "сложная", построить таблицу 10х10 расположить 10 бомб
difHard.addEventListener("click", function(){
gridSize = 10;
drawGrid();
placeBombsHard();
});
А два раза в одном цикле Math.random() не судьба вызвать ???

Владимир Лукашевич
Владимир Лукашевич
77 353
Лучший ответ
//Функция генерации бомбочек сложности 0..2
function placeBombs(difficulty) {
 let tds = document.querySelectorAll('td'),
   count, max;
 switch (difficulty) {
  case 0: count = 3; max = 25; break;
  case 1: count = 9; max = 49; break;
  case 2: count = 15; max = 100;
 }
 for (let cl; count; ) {
  cl = tds[Math.floor(Math.random() * max)].classList;
  if (cl.contains('bomb'))
   continue;
  cl.add('bomb');
  count--;
 }
}
вместо
tds[Math.floor(Math.random()*25)].classList.add("bomb")

написать
while(true) {
var x = tds[Math.floor(Math.random()*25)].classList;
if(!x.contains("bomb")) { x.add("bomb"); break; }
}
Ну читать все это нет желания. В таких случаях запоминают рандомные числа и если они совпали то еще раз дать рандомное число. Проверить есть ли уже бомба на этом месте и если есть то сгенерировать другое место.
проверять что сгенерировалось и генерировать ещё раз пока все три значения не будут разными (можно рекурсивно)
Читать все не хочется, но зачем выбирать рандомное число из всех возможных!?

Если заранее известно кол-во ячеек (например 5х5) = 25 ячеек -
Создаем массив из 25 элементов (как пример - new Table(25)),
где каждый элемет ссылается на определенную ячейку таблицы.
Выбираем (любым методом который вы создали) рандомное число, например:
var r = randomTableMinMax(1,Table.length); //выбрали к примеру 18
Далее выполняем действия с ячейкой 18, и исключаем ее из массива.
Table.splice(18, 1); // При этом в массиве удаляется элемент 18.
Следующий выбор randomTableMinMax(1,Table.length)
будет уже не function(1,25) а function(1,24)
и никогда не сможет выбрать ячейку, ссылка на которую уже удалена.

PS: имена методов/классов только как пример.
Метод arr.splice(...) - вы и сами знаете.
Шошкин Андрей
Шошкин Андрей
6 545