停止重复相同的随机数

时间:2016-11-02 21:57:30

标签: javascript

function setUpEventHandlerForShowBallButton() {

  var myshowballbutton = document.getElementById('showball');   // local variable

  myshowballbutton.addEventListener('click', function () {

    // Generate a random number then draw a circle to display it
    // for loop not really needed if only displaying one ball

    for (var i = 0; i < numberOfCircles; i++) {
      randomNumber = Math.floor(Math.random() * 90 + 1);

      drawCircle(myContext, circleCentreX, circleCentreY, circleRadius, circleColours[0], randomNumber);

      //circleCentreX += circleOffsetX;  // The adds the offset to the current x coord.
    }

  }, false);
}

这是我用来创建1-90随机数的代码但是如何阻止相同的数字再次重复?

5 个答案:

答案 0 :(得分:1)

生成一个长度为n的数组(在您的情况下为numberOfCircles),其中包含整数[0..n],使用lodash's .shuffle() function或类似方法随机化它,然后使用此数字数组根据需要:

var array = [];
for (var i = 0; i < numberOfCircles; i++) {
  array[i] = i;
}
array = _.shuffle(array);
for (var i = 0; i < numberOfCircles; i++) {
  randomNumber = array[i];
  // do more here
}

答案 1 :(得分:0)

一种方法是使用while循环生成随机数,并保留已使用值的对象以检查该值是否已被使用。

我认为值得一提的两件事:

1)正如其他人所提到的,如果你有超过90个值,你必须有重复

2)通常当我做这样的事情时,根据我尝试做的事情,我会在前进之前为我允许的循环迭代创建一个阈值。跳到脑海的一个例子是随机颜色生成器,它确保任何两种颜色都不会太相似&#34;。但是,在x次循环迭代之后,我只是使用颜色并继续前进,因此它不会锁定浏览器并显着影响性能。这实际上取决于你想要做什么。

我将留下添加公差和&gt; 90个值作为练习,但这是基本的想法:

function setUpEventHandlerForShowBallButton() {

  var myshowballbutton = document.getElementById('showball'); // local variable

  myshowballbutton.addEventListener('click', function() {

    // Generate a random number then draw a circle to display it
    // for loop not really needed if only displaying one ball
    var usedValues = {};
    var randomNumber;
    for (var i = 0; i < numberOfCircles; i++) {
      while (typeof randomNumber === "undefined" || typeof usedValues[randomNumber] !== "undefined") {
        randomNumber = Math.floor(Math.random() * 90 + 1);
      }
      usedValues[randomNumber] = randomNumber;
      drawCircle(myContext, circleCentreX, circleCentreY, circleRadius, circleColours[0], randomNumber);

      //circleCentreX += circleOffsetX;  // The adds the offset to the current x coord.
    }

  }, false);
}

答案 2 :(得分:0)

您是否尝试使用变量来保留先前的randomNumber?

const previousNumber; //simple constant to store generated number

function setUpEventHandlerForShowBallButton() {

  var myshowballbutton = document.getElementById('showball');   // local variable

  myshowballbutton.addEventListener('click', function () {

    // Generate a random number then draw a circle to display it
    // for loop not really needed if only displaying one ball

    for (var i = 0; i < numberOfCircles; i++) {
    if(Math.floor(Math.random() * 90 + 1) !==previousNumber)
      {randomNumber = Math.floor(Math.random() * 90 + 1)}  
      previousNumber = randomNumber;

      drawCircle(myContext, circleCentreX, circleCentreY, circleRadius, circleColours[0], randomNumber);

      //circleCentreX += circleOffsetX;  // The adds the offset to the current x coord.
    }

  }, false);
}

答案 3 :(得分:0)

你可以创建一个从1到90的数字数组,然后使用它作为 index 从1到90中选取一个随机数,用于提取数组中相应的数字

之后你重新创建没有提取数字的数组(或者将数字的位置移动到+1偏移量),然后从1到89中选择一个新的随机数作为索引

依此类推,直到你在数组中有一个元素

但我认为最快的方法是将包含1到90之间数字的数组混洗,然后在for cicle中提取数字

我更喜欢第二种方法,我不认为使用字典提取数字是一个好主意,因为在一些提取后你会得到很多错过,导致执行缓慢

答案 4 :(得分:0)

使用自调用命名匿名本地函数和静态变量的解决方案:

function setUpEventHandlerForShowBallButton() {
    var myshowballbutton = document.getElementById('showball'),
        randomNumber;        

    // self-invoked named anonymous function
    (function getNumber(){
        randomNumber = Math.floor(Math.random() * 90 + 1);
        if (setUpEventHandlerForShowBallButton.numbers.indexOf(randomNumber) !== -1) {
            getNumber();
        }
    }())
    setUpEventHandlerForShowBallButton.numbers.push(randomNumber);

    myshowballbutton.addEventListener('click', function () {

        drawCircle(myContext, circleCentreX, circleCentreY, circleRadius, circleColours[0], randomNumber);

    }, false);
}
setUpEventHandlerForShowBallButton.numbers = [];  // static variable

setUpEventHandlerForShowBallButton();