8 Replies Latest reply on Jul 8, 2013 12:16 PM by elainecc

    Get random, non-repeating items from array

    bettiesac212

      Hello!

       

      I am making a 20-question, multiple choice quiz. Each question is randomly selected from an array, and each time the user clicks on the right answer another randomly-selected question comes up. I haven't been able to figure out how to make it so the questions already selected don't repeat. I have tried pushing the selected items into an array and then using $.grep and an if statement to check if the next randomly selected question is already in the new array or not, but I couldn't seem to get that to work.

       

      My code in the compositionReady panel is:

       

      var arr = ['Symbol_1', 'Symbol_2', 'Symbol_3', 'Symbol_4', 'Symbol_5', 'Symbol_6', 'Symbol_7', 'Symbol_8', 'Symbol_9', 'Symbol_10', 'Symbol_11', 'Symbol_12', 'Symbol_13', 'Symbol_14', 'Symbol_15', 'Symbol_16', 'Symbol_17', 'Symbol_18', 'Symbol_19', 'Symbol_20'];

       

      sym.setVariable("arr", arr);

       

      arr.sort(function() {return 0.5 - Math.random()});

      arr.length = 20;

       

      var ques = Math.floor(Math.random()*100)%arr.length;

       

      for (i=0; i<20; i++){

                sym.$(arr[i]).hide();

                sym.$(arr[ques]).show();

      };

       

      and each time the correct answer is clicked I run this:

       

      sym.getComposition().getStage().$("try_again1").hide();

      sym.getComposition().getStage().$("correct1").show();

      sym.getComposition().getStage().getSymbol("correct1").play();

       

      var arr = sym.getComposition().getStage().getVariable("arr");

      var ques = Math.floor(Math.random()*100)%arr.length;

       

      for (i=0; i<=20; i++){

       

      sym.getComposition().getStage().$(arr[i]).hide();

      sym.getComposition().getStage().$(arr[ques]).show();

       

      }

       

      Any insight into this would be much appreciated!


        • 1. Re: Get random, non-repeating items from array
          elainecc Adobe Employee

          Hey, bettie-

           

          Take a look at the "Floral Match Maker" sample now available on html.adobe.com:

          http://html.adobe.com/edge/animate/showcase.html

           

          I solved the same problem you're talking about in this sample by using an object as an associative array.

           

          -Elaine

          1 person found this helpful
          • 2. Re: Get random, non-repeating items from array
            bettiesac212 Level 1

            Elaine,

             

            Thank you for posting this, but I am very confused. I see the part of the project you have directed me to, but I don't understand how to apply it to my own code.

             

            -Bettie

            • 3. Re: Get random, non-repeating items from array
              elainecc Adobe Employee

              Hi, bettie-

               

              Okay, I've overthought this a little bit - the approach in the game might be too complex for what you want to do.  Let's approach this conceptually first:

               

              Let's say you have 12 shoes that you want to stuff into 12 slots.  You don't want any shoe to be in a slot with any other shoe, and you want them to be in a random order.  Let's say the slots are numbered and you have a bag with numbered slips of paper.  One way you can do it is to choose a number from the bag and stick the shoe in that numbered slot.  Then you put the number back in the bag and choose a number from the bag to stick the second shoe in a slot.

               

              At this point, your number could be the same one that the first shoe is in, so you have to check to see if there's a shoe already in there.  If it is, you stick the number back in the bag and try again, repeating that process until you have an empty space in the numbered slot you draw.  (This is the point that is similar to my game.)

               

              For your array, randomizing it in place is more complicated than randomizing it into a new array.  So I'd recommend you do something like this:

               

              function randomizeArray(sourceArray) {

                 var newArray = new Array();

                 var currentIndex = 0;

               

                 // forgot how many questions you have, but let's assume 12

                 while (currentIndex < 12) {

                    // random number between 0 and 11

                    var randomNumber = (Math.random() * 100) % 12;

               

                    // is there something in the slot?

                    if (newArray[randomNumber] == undefined) {

                       // we can place an object!

                       newArray[randomNumber] = sourceArray[currentIndex];

                       currentIndex++;

                    }

               

                    // by not incrementing the currentIndex, we basically force it to draw again

                 }

               

                 // at this point, we should have a new, randomized array

                 return newArray;

              }

               

              Hope that helps,

               

              -Elaine

              • 4. Re: Get random, non-repeating items from array
                bettiesac212 Level 1

                Hi Elaine,

                 

                For the record, it was not me who marked that last answer as correct.

                 

                This is not working either. The questions are still repeating, and var currentIndex returns at 20 and never changes. Here is a link to my project if it helps: https://www.dropbox.com/sh/s9hw60un6bqagzk/2cbTIUChSX

                 

                Here is what I have on compositionReady now. It is the exact same in each symbol for the right answer.

                 

                var arr = ['Symbol_1', 'Symbol_2', 'Symbol_3', 'Symbol_4', 'Symbol_5', 'Symbol_6', 'Symbol_7', 'Symbol_8', 'Symbol_9', 'Symbol_10', 'Symbol_11', 'Symbol_12', 'Symbol_13', 'Symbol_14', 'Symbol_15', 'Symbol_16', 'Symbol_17', 'Symbol_18', 'Symbol_19', 'Symbol_20'];

                 

                sym.setVariable("arr", arr);

                 

                arr.sort(function() {return 0.5 - Math.random()});

                arr.length = 20;

                 

                var ques = Math.floor(Math.random()*100)%arr.length;

                 

                for (i=0; i<20; i++){

                          sym.$(arr[i]).hide();

                          sym.$(arr[ques]).show();

                };

                 

                   var usedArr = new Array();

                   var currentIndex = 0;

                 

                function randomizeArray(arr) {

                 

                while (currentIndex < 20) {

                 

                if (usedArr[ques] == undefined) {

                         usedArr[ques] = arr[currentIndex];

                         currentIndex++;

                      }

                   }

                return usedArr;

                }

                 

                randomizeArray(e);

                 

                console.log('id=%d', ques);

                console.log(arr);

                console.log(usedArr);

                console.log(currentIndex);

                • 5. Re: Get random, non-repeating items from array
                  elainecc Adobe Employee

                  Hi, bettiesac212-

                   

                  Okay, I took a look at your project (including the project files was very helpful, by the way).  So what's going on is that you included my code snippet in the midst of all of the other stuff that was going on in your file.  There are a lot of questions that I had when looking at your code, like:

                  • what's "e"?  Where did that come from?
                  • why did you do an array.sort at the beginning?
                  • why do you assign arr.length?  it's a property of arr already, so there's no reason to assign it

                   

                  Anyway, I cleaned up the code a little bit and put my snippet in.  I did leave some of it "as an exercise to the student," to paraphrase some of my old textbooks, but hopefully the console log will show you that usedArr is now a randomized array that you can save.  If you save a variable that has the index, (aka "which question am I on?"), then you can look up where you are right now, add one, save that variable, and look up the next item in usedArr and know that it's properly randomized.

                   

                  For those who are looking for an answer, this is the code I ended up using:

                   

                           var usedArr = new Array();

                           var currentIndex = 0;

                          

                           while (currentIndex < 20) {

                              var randNum = Math.floor((Math.random() * 100)) % 20;

                              if (usedArr[randNum] == undefined) {

                                    // we can place an object!

                                    usedArr[randNum] = arr[currentIndex];

                                    currentIndex++;

                              }

                              // by not incrementing the currentIndex, we basically force it to draw again

                           }

                          

                           for (i = 0; i < usedArr.length; i++) {

                               console.log("usedArr index " + i + ": " + usedArr[i]);

                           }

                          

                           // you can save your new array and just iterate through it each time

                           // you say "next question"

                   

                  ... which I believe is more or less what I posted in my previous answer.  Bettie, I'll send you a link to your project files via private message in a few minutes.

                   

                  Thanks,

                   

                  -Elaine

                  • 6. Re: Get random, non-repeating items from array
                    bettiesac212 Level 1

                    Elaine,

                     

                    Is there any way you can post the files in version 1.5?

                    • 7. Re: Get random, non-repeating items from array
                      bettiesac212 Level 1

                      Elaine,

                       

                      I was able to get the programmer in our office to look at this for me. Fortunately she had a better understanding of it, and it is working now. I do not have a hardcore programming background so it is not as easy for me to understand all the "unspokens." I probably should've mentioned that, but I assumed my questions gave it away, lol.

                       

                      You were still a huge help. Thank you

                      1 person found this helpful
                      • 8. Re: Get random, non-repeating items from array
                        elainecc Adobe Employee

                        Awesome, glad you got it working!

                         

                        -Elaine