Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

javascript - How can I make a random array with no repeats?

I've been searching around for some answers to this issue, but nothing seems to work when I try to find a solution.

What I'm trying to achieve is to make a spinner in Javascript & Adobe Edge that randomly spins on a number, and does not repeat that number again until all numbers have been spinned.

I know this should be fairly easy to do for a decent coder, but I'm not that experienced yet.

This is what I have so far, but it is unfinished and buggy:

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!");
   }
});

Hope someone could help me out. Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are two ways you could achieve this.

  1. Store an array of values already spun. Then, when you generate a new number, check if it's in the array of spun numbers. If it is, generate a new number and check again, until you get a number which isn't in the array. Otherwise, add it to the array.

  2. Generate an array of all the valid numbers up front, as you are doing. Then, every time you spin a number, remove it from that array. That way, the next time you 'spin' you will be only selecting from values which haven't been spun already.

  3. Generate an array of all the valid numbers up front, and then sort it randomly. Then all you have to do is keep taking the first item in the array.

In order, Option 3. is the most elegant, but it has the downside that someone with a console open could potentially see exactly what number is coming next! Option 2 is the next best, and if the user is allowed to know that a number can't come up twice, they can't 'cheat' by seeing the remaining available numbers. Option 1 is the least efficient - because it means your code will need to do more and more work to try and find a 'free' number.

Honestly, if your game needs to be at all secure from hacking, then you would not want to generate any random numbers client side anyway, so if this is just for a bit of fun, it won't really matter which method you use. If you are writing it for a gambling website, first let me know which one so I can make a fortune, and then move your logic to the server.

So here is an example of Option 2. approach

<!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>

And Option 3. below. The main difference is that you can just shift() the next value instead of having to select randomly.

<!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>

Hopefully that gives you an idea of how you could incorporate this into your code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...