【问题标题】:How can I make a random array with no repeats?如何制作没有重复的随机数组?
【发布时间】:2016-10-24 02:52:14
【问题描述】:

我一直在寻找这个问题的一些答案,但是当我尝试找到解决方案时似乎没有任何效果。

我想要实现的是在 Javascript 和 Adob​​e Edge 中制作一个 随机旋转数字的微调器,并且不会再次重复该数字,直到所有数字已被旋转。

我知道这对于一个体面的程序员来说应该很容易做到,但我还没有那么有经验。

这是我目前所拥有的,但它尚未完成且有问题:

var myArray = ['360', '330', '300', '270', '240', '210', '180', '150', '120', '90', '60', '30'];
var Spinner1 = sym.$('Spinner1');

Spinner1.click(function(){
// randomize the degree of spin.
var mySpin = myArray[Math.floor(Math.random() * myArray.length)];

sym.getSymbol('Spinner1').play();
        Spinner1.css({
                    '-webkit-transform': 'rotate(' + mySpin + 'deg)',
                    '-moz-transform': 'rotate(' + mySpin + 'deg)',
                    '-ms-transform': 'rotate(' + mySpin + 'deg)',
                    '-o-transform': 'rotate(' + mySpin + 'deg)',
                    'transform': 'rotate(' + mySpin + 'deg)',
   });
   Spinner1.css('-webkit-transition','all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000)');

   if (mySpin > 300 && mySpin < 360) {
   alert("Winner is number 1!");
   }
});

希望有人可以帮助我。提前致谢。

【问题讨论】:

标签: javascript random spinner repeat


【解决方案1】:

有两种方法可以实现。

  1. 存储已旋转的值数组。然后,当您生成一个新数字时,检查它是否在旋转数字数组中。如果是,则生成一个新数字并再次检查,直到您得到一个不在数组中的数字。否则,将其添加到数组中。

  2. 按照您的做法,预先生成一个包含所有有效数字的数组。然后,每次旋转一个数字时,将其从该数组中删除。这样,下次“旋转”时,您将只从尚未旋转的值中进行选择。

  3. 预先生成一个包含所有有效数字的数组,然后随机排序。那么你所要做的就是继续获取​​数组中的第一项。

按顺序,选项 3. 是最优雅的,但它的缺点是打开控制台的人可能会确切地看到接下来会出现什么数字!选项 2 是次优的,如果允许用户知道一个号码不能出现两次,他们就不能通过查看剩余的可用号码来“作弊”。选项 1 效率最低 - 因为这意味着您的代码需要做越来越多的工作才能尝试找到“免费”号码。

老实说,如果您的游戏需要完全不被黑客入侵,那么您无论如何都不想在客户端生成任何随机数,所以如果这只是为了一点乐趣,那么哪种方法并不重要你用。如果你是为赌博网站写的,先让我知道是哪一个,这样我就可以发财了,然后再把你的逻辑移到服务器上。

这里是选项 2 的示例。方法

<!DOCTYPE html>
<html>
<head>
    <script>

        var numbers = []; // this array will store the available numbers..

        function generateNumbers()
        {
            // populate the available numbers however you need to..
            for(var i=0; i<360; i+=30)
            {
                numbers.push(i);
            }
        }

        function spin()
        {
            if(numbers.length==0)
            {
                // then we've used  up all available numbers..start new game or whatever you need to do..
                alert("starting again");
                generateNumbers();
            }
            var rand = Math.floor(Math.random()*numbers.length); // select an index randomly based on the number of remaining available numbers..
            var num = numbers[rand];
            numbers.splice(rand,1); // remove the number we selected so it can't be selected next time..
            document.getElementById("number").innerHTML = num;
        }

    </script>
</head>
<body>
<button onclick="spin()">SPIN</button>
<div id="number"></div>
</body>
</html>

还有下面的选项 3。主要区别在于您可以只 shift() 下一个值,而不必随机选择。

<!DOCTYPE html>
<html>
<head>
    <script>

        var numbers = [];

        function generateNumbers()
        {
            for(var i=0; i<360; i+=30)
            {
                numbers.push(i);
            }
            function sort(a,b)
            {
                return (Math.random()>0.5)? -1 : 1;
            }
            numbers.sort(sort);
        }

        function spin()
        {
            if(numbers.length==0)
            {
                alert("starting again");
                generateNumbers();
            }
            var num = numbers.shift();
            document.getElementById("available").innerHTML = "Available:" + numbers.join(",");
            document.getElementById("number").innerHTML = "Selected:" + num;
        }

    </script>
</head>
<body>
<button onclick="spin()">SPIN</button>
<div id="available"></div>
<div id="number"></div>
</body>
</html>

希望这能让您了解如何将其合并到您的代码中。

【讨论】:

  • 我明白了。我正在为一个学校项目制作这个游戏,所以它不必非常安全,不会被黑客入侵哈哈。我该如何设置呢?检查号码是否已经旋转,否则生成一个新号码。
【解决方案2】:

看起来您已经有了一个可能值的数组。在这种情况下,您可以简单地打乱数组并遍历它。 JavaScript 没有内置的 shuffle 函数,但实现起来非常简单。

这是Fisher–Yates shuffle的示例

function shuffle(array) {
  for(var i = array.length; i > 1; i--) {
    var r = Math.floor(Math.random() * i);
    var temp = array[r];
    array[r] = array[i-1];
    array[i-1] = temp;
  }
}

【讨论】:

    【解决方案3】:

    您需要做的是,选择一个随机数并将其存储在一个数组中,但在存储它之前,检查它是否已经存在于该数组中 strong>,如果是,则选择另一个。 如果您选择的值数组包含所有可能的值,则重置数组。

    这里是示例:https://jsfiddle.net/5a7mqsbn/1/

    var alreadyArr = new Array();
    $(function() {
      $("#generate").click(function() {
        var newFound = false;
        do {
          var num = (Math.floor(Math.random() * 12) + 1) * 30;
          if (alreadyArr.length == 12) {
            alreadyArr = [num];
            newFound = true;
          } else if (alreadyArr.indexOf(num) < 0) {
            alreadyArr.push(num);
            newFound = true;
          }
        } while (!newFound);
        $("#numbers").text(alreadyArr);
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <p id="numbers"></p>
    <button id="generate">
      Next Random number
    </button>

    【讨论】:

      【解决方案4】:

      此函数将使用Math.random() 随机选择数组中的一个数字,直到所有数字都用完后才再次选择:

      var originalArray = ['360', '330', '300', '270', '240', '210', 
      '180', '150', '120', '90', '60', '30'];
      
      var totalSpin = [];
      
      function spinArray(){
          var spin = Math.floor(Math.random()*originalArray.length);
          if(totalSpin.indexOf(spin) == -1){
              totalSpin.push(spin);
              parag.innerHTML = originalArray[spin];
          } else { 
              spinArray(); 
          }
          if(totalSpin.length == originalArray.length)
                totalSpin = [];
      }
      

      这里是小提琴:https://jsfiddle.net/628yqz0v/4/

      【讨论】:

        【解决方案5】:
            var array = [];
        
            setInterval(function(){
        
                if(array .length === 0){ 
                    reload(); 
                }
        
                var result = getRandom();
        
                console.log(result);
        
            },1000);
        
            function getRandom(){
                var index = (array.length === 1 ? 0 : Math.floor(Math.random() * array.length));
                return array.splice(index, 1)[0];
            }
        
            function reload(){
                array = [2,3,4,5,6,7,8,9,0,1,44,66];
            }
        

        【讨论】:

        • 你的代码运行了吗?你应该检查一下,我不认为它在做你认为的那样。
        • 嗨,韦恩,我刚刚更新了代码。我想我这次做对了。
        【解决方案6】:

        鉴于您已经拥有数组值并且您需要randomize 他们的位置,您可以采取的另一种方法是使用Set 生成unique random values

        var data = ['360', '330', '300', '270', '240', '210','180', '150', '120', '90', '60', '30'];
        
        let getUniqueRandomNumbers = n => {
          let set = new Set()
          while (set.size < n) set.add(Math.floor(Math.random() * n))
          return Array.from(set)
        }
        
        let result = getUniqueRandomNumbers(data.length).map(x => data[x])
        
        console.log(result)

        这个想法是生成新数组的索引,然后使用这些索引通过Array.map 填充它。

        您可以采取的另一种方法是通过Array.sortMath.random

        var data = ['360', '330', '300', '270', '240', '210','180', '150', '120', '90', '60', '30'];
        
        let result = data.sort(function(a, b){
         return 0.5 - Math.random()  // <— sort needs a number and this makes it work
        });
        
        console.log(result);

        【讨论】:

          猜你喜欢
          • 2021-09-28
          • 1970-01-01
          • 2021-03-31
          • 1970-01-01
          • 2015-02-27
          • 2012-10-23
          • 2016-03-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多