Задача двадцатигранника в игре Dungeons & Dragons

После вызова функции - функция показывает результат: число от 1 до 20. В случае если результат 20 или 1, должно быть показано дополнительное число.

Результат: dice() 3 dice() 1 14

Думал выполнить задачу, с помощью массива, где будет выбираться рандомное число, но не понимаю какой код выведет не 1, а 2 значение, если результат 1 или 20

let sizeOfDice =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

function getRandNumber(sizeOfDice) {
  
  let rand = Math.floor(Math.random() * sizeOfDice.length); 
  
  return sizeOfDice[rand]
} 

getRandNumber(sizeOfDice)

Ответы (2 шт):

Автор решения: jimwia

Если я правильно понял, то что - то такое должно помочь. Если нужен вывод, то давайте добавим console.log, но если что можно и поменять. а второе условие с возвратом просто уберём. Функцию можно расширить, добавив входимый параметр в виде массива, чтобы при рекурсии у неё уже были предыдущие значения, после чего можно было вернуть их все сразу, чтобы работать с этими значениями дальше.

    function throwDice() {
      let dice;
      let min = 1,
          max = 20;

      dice = Math.floor(Math.random() * (max - min + 1)) + min;
      console.log(dice);
      if (dice === 20 || dice === 1) {
        throwDice();
      }
}

Если нужна работа с несколькими значениями - можно попробовать так. Он вам и выведет всё, что есть, и вернёт массив.

    function throwDice(results = []) {
      results = [];
      let dice;
      let min = 1,
          max = 20;

      dice = Math.floor(Math.random() * (max - min + 1)) + min;
      results.push(dice);
      console.log(dice);
      if (dice === 20 || dice === 1) {
        throwDice(results);
      } else {
        return results;
      }
  }
→ Ссылка
Автор решения: EzioMercer

Эту задачу можно решить и без массива

Математика:

  • Math.random() - выдаёт занчения от 0 включительно до 1 не включительно. Далее включительно буду обозначать квадратными скобками, а не включительно круглыми. Т.е. Math.random() выдаёт значения [0, 1)

  • Умножаем на 20 и получаем [0, 20)

  • Округляя вверх получаем целое число из отрезка [1, 20]

const dice = () => {
  const getRandomNumber = () => Math.ceil(Math.random() * 20);
  
  const value1 = getRandomNumber();
  
  if (value1 === 1 || value1 === 20) {
    return [value1, getRandomNumber()]
  }
  
  return value1;
}

for (let i = 0; i < 40; ++i) {
  console.log(dice());
}

В приведённом выше примере, как указали в комментариях, есть очень маленькая вероятность получить 0. Дело в том, что если вдруг Math.random() выдаст ровно 0, то мой алгоритм вернёт просто 0. Чтобы этого избежать, можно функцию получения рандомного числа чутка подправить

Математика:

  • Math.random() выдаёт значения [0, 1)

  • Умножаем на 20 и получаем [0, 20)

  • Округляя вниз и получаем [0, 19]

  • Прибавляем 1 и получаем целое число из отрезка [1, 20]

const dice = () => {
  const getRandomNumber = () => Math.floor(Math.random() * 20) + 1;
  
  const value1 = getRandomNumber();
  
  if (value1 === 1 || value1 === 20) {
    return [value1, getRandomNumber()]
  }
  
  return value1;
}

for (let i = 0; i < 40; ++i) {
  console.log(dice());
}

→ Ссылка