Ensuring a Random Number is not Re-picked

This one might be for the javascript experts in the community, but open to all.

I think someone (and it might have been Owen Holt) posted how you can use javascript to create a random variable and in that same coding ensure any of the x numbers is not re-picked.  I may be imagining this though.  (If this does exist can someone point us to the discussion thread)

With the Storyline 360 and the random variable option, does someone have a method they have come up with to ensure the same random number does not get picked more than once?

10 Replies
Tracy Parish

Update:  this might be the discussion thread using Javascript to remove those that have already been selected.

https://community.articulate.com/discussions/building-better-courses/trivia-game-using-variables-and-javascript-to-remove-answered-questions-from-the-deck


Still wondering about using the built in random feature though.  (I can think of way to do it if I'm do a small set of random numbers, but what about between  something like 1 and 1500000)

 

OWEN HOLT

You've got the right thread for my JavaScript solution. It does have a heavy dependence on variables so the bigger the number range, the more variables required. 

Stephanie Harnett just published a thread where she used the new random number variable but also controlled it such that previously selected numbers were not used. Her thread only included the published file so I am not sure how she was controlling the valid selections.  Link to Stephanie's thread

OWEN HOLT

I streamlined my JS for you with a slightly more elegant solution that only uses 3 variables.

WHAT YOU NEED:

  1. A variable to store a single text array formatted like this: 1,2,3,4,5,6,7,8,9,10,11.... through your top number. Separate values with a comma only; NOT a comma + space. In my example, the variable is named Text_Array and goes from 1 to 100.
  2. A variable to receive your Random Number. This can be either a text or numeric variable depending on what you want to do with it. In my example, it is a text variable named Random.  My example doesn't do anything other than display the random number chosen, but obviously you would want to evaluate the value and then do something based on it like go to layer, play media, jump to slide, etc.
  3. A variable to track how many items are left in your list. You will use this to track when you have used all of the numbers to do something different.
  4. Something to trigger your JavaScript. I'm using a button.  Here is the JavaScript code commented out so you can see what it is doing:


    //get the StoryLine player
    var player=GetPlayer();

    //get Storyline variable value as a string
    var textArray=player.GetVar("Text_Array");

    //Convert string to a numeric array
    numArray=textArray.split(",").map(Number);

    //Get a random number from the array and send it to StoryLine
    var randNum = numArray[Math.floor(Math.random() * numArray.length)];
    player.SetVar("Random",randNum);

    //Remove the random number from your array and get the array's length
    numArray.splice(numArray.indexOf(randNum), 1);
    var itemsLeft=numArray.length;

    //Convert array to a string and send it back to SL along with the array's length
    textArray=numArray.map(String).toString();
    player.SetVar("Items_Left", itemsLeft);
    player.SetVar("Text_Array", textArray);

See it in action here

Example is SL360
Attached file is SL2

OWEN HOLT

Alternative SL360 file that adds some code to make setting the range easier. 
On slide one, designate the high end of your range. JavaScript will create the array, convert it to a string, and send it to your variable so you don't have to type in 1,2,3,4,..... as the default value for the variable.  Note, the input is optional as you could hard code the upper limit if it is known and not going to be variable.  

Here is the additional JS on slide one:

// get the SL player
var player=GetPlayer();

//Optional: only use this if you are not hard coding the upper range limit.
//The value is supplied by a numeric entry box tied to a SL variable called HighRange
var highLimit=player.GetVar("HighRange");

//Create and populate the array
//If you are hard coding the upper limit, replace "highLimit" with the numeric value of your upper limit.
var textArray = [];
    for (var i = 1; i <= highLimit; i++) {
    textArray.push(i);
    };

//Get the length of the array
var itemsLeft = textArray.length;

//Convert the array to a string and send the variable values to SL
textArray=textArray.map(String).toString();
player.SetVar("Text_Array", textArray);
player.SetVar("Items_Left", itemsLeft);

See it working here.
SL2 version provided below.

Bridget Brown

Owen - I have a knowledge check dice game with only 6 numbers.  Currently I am using the Random number variable, but of course the learner roll 1-5, answer questions 1-5 and have to roll 10 more times to get question #6.

If I use your java - do I take out the random number variable?   I am also not clear how, when the array picks a number I plug that number into a text variable (%diceroll%!) so that I can trigger a jump to a slide/question.

Thanks.

OWEN HOLT

Correct, you would not need to use StoryLine's random number if you are using JavaScript.

Once you generate a random number using JS, you send it back to SL using the setvariable code.
In this example -> player.SetVar("Text_Array", textArray);

player.SetVar is the command.
"TextArray" is the name of the StoryLine variable being used.
textArray is the JS variable that has the value you are sending back to StoryLine.