Нежелательное поведение в функции JavaScript, которая использует Math.random в цикле for - PullRequest
0 голосов
/ 20 июня 2020

Я смотрел обучающее видео на YouTube о кодировании игры 2048 в Vanilla JavaScript, HTML и CSS. Пока я смотрел учебник, я подумал, что могу также реорганизовать код, предоставленный инструктором. В определенный момент она дважды вызывает функцию для создания двух пронумерованных квадратов (не 0) в случайных местах сетки. Я подумал, что могу написать функцию (назовите ее randomSquaresGenerator), которая при желаемом количестве различных позиций могла бы генерировать соответствующее количество случайных пронумерованных квадратов. Дело в том, что после некоторых тестов (обновлений в моем браузере) иногда я вижу меньше квадратов, чем нужно. Я понял, что это связано с тем, что при определенных вызовах функция может проверять уже пронумерованный квадрат и проходить. Я до сих пор не понял, как это решить. Есть идеи?

Вот мой JavaScript код:

document.addEventListener("DOMContentLoaded", () => {
  const gridDisplay = document.querySelector(".grid");
  const scoreDisplay = document.querySelector(".score");
  const resultDisplay = document.querySelector(".result");
  const width = 4;
  const squaredWidth = width ** 2;
  let squares = [];

  function createBoard(width) {
    for (let i = 0; i < squaredWidth; i++) {
      square = document.createElement("div"); 
      square.innerHTML = 0; 
      gridDisplay.appendChild(square); 
      squares.push(square);
    }
  }
  
  //The function with the unwanted behavior.
  function randomSquaresGenerator(positions) {
    for (let i = 0; i < positions; i++) {
      let randomSquare = Math.floor(Math.random() * squaredWidth);
      if (squares[randomSquare].innerHTML == 0) {
        squares[randomSquare].innerHTML = 2;
      }
    }
  }

  createBoard();
  randomSquaresGenerator(2);
});

И мой HTML код:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>2048</title>
    <link rel="stylesheet" href="style.css" />
    <script src="app.js" charset="utf-8"></script>
  </head>
  <body>
    <div class="score-container">
      <div class="score-title">SCORE</div>
      <span class="score">1000</span>
    </div>
    <div class="grid"></div>
    <div class="result"></div>
  </body>
</html>

Ответы [ 2 ]

1 голос
/ 20 июня 2020

Я последовал совету @Andreas и некоторое время использовал l oop. Работает нормально. Вот код:

function randomSquareGenerator(positions) {
    let generatedSquares = 0;
    while (generatedSquares != positions) {
      let randomSquare = Math.floor(Math.random() * squaredWidth);
      if (squares[randomSquare].innerHTML == 0) {
        squares[randomSquare].innerHTML = 2;
        generatedSquares += 1;
      }
    }
  }
0 голосов
/ 20 июня 2020

Я думаю, проблема здесь в том, что в

let randomSquare = Math.floor(Math.random() * squaredWidth);

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

function randomSquaresGenerator(positions) {
 let arrIndex=[];
 for(let i=0;i<squares.length;i++){
     arrIndex.push(i);
 }

 for (let i = 0; i < positions; i++) {
   let randomIndex = Math.floor(Math.random() * arrIndex.length);
   let randomSquare = arrIndex[randomIndex];
   arrIndex= [].concat(arrIndex.slice(0,randomIndex),arrIndex.slice(randomIndex+1,arrIndex.length));
   
     squares[randomSquare].innerHTML = 2;
   
 }

Там я определил массив с индексами основного массива, поэтому вы просто выбираете случайное число оттуда, и оно отображает вас в позицию массива, которая имеет 0. Затем вы удаляете этот элемент из массива и делаете то же самое, зная, что вы всегда получите доступную позицию. Вы можете на всякий случай добавить оператор if, чтобы проверять, больше ли позиций, чем размер массива.

Надеюсь, вам понравится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...