Javascript and Captivate - javascript

I am trying to create a game for fun in Captivate. The game will mimic a wheel of fortune or spin the wheel format.
I am trying to put a different spin on it, and not have any repeating numbers.
Here is what I have so far:
function getRandomInt (min, max) {
var jsRandomNumber = Math.floor (Math.random () * (max - min + 1)) + min;
if(jsRandomNumber==1){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 1);
}else if (jsRandomNumber==2){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 2);
}else if (jsRandomNumber==3){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 3);
}else if (jsRandomNumber==4){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 4);
}else if (jsRandomNumber==5){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 5);
}else if (jsRandomNumber==6){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 6);
}else if (jsRandomNumber==7){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 7);
}else if (jsRandomNumber==8){
window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', 8);
}
}
getRandomInt(1,8);
I don't understand how to prevent repetitive numbers. I also can assign values in Captivate if a slide has been viewed, however I don't understand how to skip that slide if the random number is generated. Any help is greatly appreciated.

You can have an array store what is pending and keep on deleting what has been shown.
function getRandomInt () {
var min = 0; //1st arr element index
var max = arr.length-1; // last arr element index
if(max<0){
return false; //else repopulate the array or based on what you want
}
var randomIndex = Math.floor (Math.random () * (max - min + 1)) + min;
var randomNumber = arr.splice(randomIndex,1)[0];
//extract the item in that randomIndex position,
//since the array is global it will affect the array next time,
//we will not have that value in the next call.
//window.cpAPIInterface.setVariableValue('cpCmndGotoSlide', randomNumber);
console.log(randomNumber);
}
//generate a random array to keep track
var arr = function(){
var min = 1, max = 8, atr = [];
for(var i=min; i<=max; i++){
atr.push(i);
}
return atr;
}();
//run a few times to test.
getRandomInt();
getRandomInt();
getRandomInt();
getRandomInt();
getRandomInt();

Related

Why not unique numbers are still coming?

I need to generate the unique numbers, join it with the letter and push to array.
arr = []
for (var i = 0; i < 5; i++) {
function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var randomNum = generateRandomNumber(1, 15);
if (!arr.includes(randomNum)) {
arr.push('B' + randomNum.toString())
} else {
if (arr.length < 5) {
return generateRandomNumber(min, max)
} else break
}
}
I have provisioned uniqueness check, however the same values are still coming.
Condition only checked once in the loop.
Also if the condition is in the else state, there is a chance that there will also be same number as previous.
You can use this approach
let arr = []
function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function add(){
var randomNum = generateRandomNumber(1, 15);
if(arr.length < 5){
if (!arr.includes('B' + randomNum.toString())) {
arr.push('B' + randomNum.toString())
}
add()
}
}
add()
console.log(arr)
I have provisioned uniqueness check, however the same values are still coming.
The uniqueness check is incorrect.
The array contains only strings starting with letter 'B' (added by the line arr.push('B' + randomNum.toString())) while the uniqueness check searches for numbers.
The call arr.includes(randomNum) always returns false. Each and every generated value of randomNum is prefixed with 'B' and pushed into the array, no matter what the array contains.
Try a simpler approach: generate numbers, add them to the list if they are not already there, stop when the list is large enough (five items).
Then run through the list and add the 'B' prefix to each item.
Like this:
function generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// Generate 5 unique random numbers between 1 and 15
let arr = []
while (arr.length < 5) {
let num = generateRandomNumber(1, 15);
// Ignore a value that has already been generated
if (!arr.includes(num)) {
arr.push(num);
}
}
// Add the 'B' prefix to the generated numbers
arr = arr.map((num) => `B${num}`);
console.log(arr);

Why does this javascript while loop hang?

I was trying a very simple thing with javascript, to create a minesweeper grid.
gridsize=9;
//grid initialisation
var grid=Array(gridsize).fill(Array(gridsize).fill(null));
// this comes from <https://stackoverflow.com/questions/1527803/generating-random-whole-numbers-in-javascript-in-a-specific-range>
function randint(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
nbombs=20;
insertedbombs=0;
while (insertedbombs<nbombs){
rx=randint(0,gridsize-1);
ry=randint(0,gridsize-1);
if (grid[rx][ry] == null){
insertedbombs++;
grid[rx][ry]='b';
}
}
The while loop hangs, both in Chrome and Firefox consoles, all the values of the grid are filled, not just 20, i've no idea why, i guess i have some wrong understanding of javascript language, because the same code in python works.
Working python code:
grid= [[None for i in range(9)]for i in range(9)]
nbombs=20;
insertedbombs=0;
while (insertedbombs< nbombs):
rx=random.randint(0,8)
ry=random.randint(0,8)
if (grid[rx][ry]== None):
grid[rx][ry]='b'
insertedbombs+=1
The issues is that Array#fill doesn't do what you think it does.
In your example you create a SINGLE array Array(gridsize).fill(null) and then you put that array at each index of the outer array. Meaning that your grid actually contains the same array, 9 times over. So when you assign grid[0][0] you actually assign grid[0][0], grid[1][0], grid[2][0], grid[3][0], etc... all at once (ish).
const gridSize = 9;
//grid initialisation
const grid = Array(gridSize).fill(Array(gridSize).fill(null));
console.log(grid[0] === grid[1]);
grid[0][0] = 10;
console.log(grid[0][0], grid[0][0] === grid[1][0]);
What you want to do, is first fill the array with some dummy value, like null. Then map over the array and replace each entry with its own copy of Array(gridsize).fill(null).
const gridSize = 9;
//grid initialisation
const grid = Array(gridSize)
.fill(null)
.map(() => Array(gridSize)
.fill(null)
);
const randInt = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;
const nbombs = 20;
let insertedbombs = 0;
while (insertedbombs < nbombs){
const rx = randInt(0, gridSize - 1);
const ry = randInt(0, gridSize - 1);
if (grid[rx][ry] === null){
insertedbombs += 1;
grid[rx][ry] = 'b';
}
}
console.log(grid);

Javascript - function returning unexpected results

I am writing a couple of javascript functions to help randomly select articles from a JSON feed.
I have created a function called getRandomNumberFromRange which takes 2 parameters: the minimum and maximum numbers of a range of numbers to select from. The number of articles to be selected at random is provided via a data attribute on the DOM element which will eventually be populated with the articles.
The second function loadStories loops through the amount of articles which needs to be retrieved and calls the getRandomNumberFromRange function to get a number. This number will eventually be used as a key to select articles from the JSON feed array.
To ensure that a random number is not picked more than once, I have created an array to store previously picked numbers, which I will check against when the number is picked. If the number is in the array already, another number is picked, if it isn't it is added to the array.
This Codepen shows what I have so far. The code is also shown below:
var setupEmployeeStories = function () {
var
$element = $(".related-employee-stories"),
noOfStories = parseInt($element.attr("data-stories")),
arrSelectedNumbers = [],
getRandomNumberFromRange = function(min, max) {
var randomNumber = Math.floor(Math.random() * (max - min) + min);
if(arrSelectedNumbers.indexOf(randomNumber) === -1){
arrSelectedNumbers.push(randomNumber);
}else{
getRandomNumberFromRange(min, max);
}
return randomNumber;
},
loadStories = function(){
for(var i = 0; i < noOfStories; i++){
var rand = getRandomNumberFromRange(0, 4);
console.log(rand);
}
console.log(arrSelectedNumbers);
};
loadStories();
};
setupEmployeeStories();
Unfortunately I'm getting some odd results from the functions when the functions select the same random number multiple times. For some reason getRandomNumberFromRange tends to return a completely different number than what was actually picked by the function. This can be seen by the differences in the (console) logged results and the final array - arrSelectedNumbers
getRandomNumberFromRange = function(min, max) {
var randomNumber = Math.floor(Math.random() * (max - min) + min);
if(arrSelectedNumbers.indexOf(randomNumber) === -1){
arrSelectedNumbers.push(randomNumber);
}else{
randomNumber = getRandomNumberFromRange(min, max);
}
return randomNumber;
}
You need to set getRandomNumberFromRange to randomNumber to get the result of the recursive function.
var setupEmployeeStories = function () {
var
$element = $(".related-employee-stories"),
noOfStories = parseInt($element.attr("data-stories")),
arrSelectedNumbers = [],
getRandomNumberFromRange = function(min, max) {
var randomNumber = Math.floor(Math.random() * (max - min) + min);
if(arrSelectedNumbers.indexOf(randomNumber) === -1){
arrSelectedNumbers.push(randomNumber);
}else{
randomNumber = getRandomNumberFromRange(min, max);
}
return randomNumber;
},
loadStories = function(){
for(var i = 0; i < noOfStories; i++){
var rand = getRandomNumberFromRange(0, 4);
//console.log(rand);
}
console.log(arrSelectedNumbers);
};
loadStories();
};
setupEmployeeStories();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="related-employee-stories" data-stories="3"></div>

How to properly create JQuery inArray if statement?

I am generating a list of random numbers. Each random number is added to an array, but I want to check that the same number isnt entered twice. I am having a lot of trouble trying to get the if statement to work with this and am not sure what I have done wrong.
I have created:
//INITIALISE VARS, ARRAYS
var uniquearr = [];
i = 0;
while (i < 30){
var min = 0;
var max = 29;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
//SEARCH UNIQUE ARRAY FOR EXISTING
if (jQuery.inArray(random, uniquearr) > -1){
//ADD NUMBER TO UNIQUE ARRAY
uniquearr.push(random);
//*DO SOMETHING*
} //END IF
i++;
} //END WHILE
But the if statement never triggers. Can anyone point me in the right direction?
You need to test whether the random number does not exist in the array; only then should it be added to the array.
Also another problem with the logic was, you were not adding the 30 unique numbers always as the i variable was incremented outside the if condition. Here you do not have to use a different loop variable since you can check whether the destination array is of desired size
//INITIALISE VARS, ARRAYS
var uniquearr = [], min = 0, max = 29;
//SEARCH UNIQUE ARRAY FOR EXISTING
while (uniquearr.length < 30){
var random = Math.floor(Math.random() * (max - min + 1)) + min;
if (jQuery.inArray(random, uniquearr) == -1){
uniquearr.push(random);
}//END IF
}//END WHILE
console.log('uniquearr', uniquearr)
That's because your if statement always is false, your array is empty and as result $.inArray always returns -1, you should check whether the returned value is -1 or not.
while (uniquearr.length < 30) { // uniquearr.length !== 30
var min = 0,
max = 29,
random = Math.floor(Math.random() * (max - min + 1)) + min;
//SEARCH UNIQUE ARRAY FOR EXISTENCE
if (jQuery.inArray(random, uniquearr) === -1) {
//ADD NUMBER TO UNIQUE ARRAY
uniquearr.push(random);
}
}
http://jsfiddle.net/zzL7v/

JavaScript for Random Numbers with Recursion

I'm trying to create a javascript function that accepts 2 parameters min and max and generates a random number between the two integers. That part is easy.
Where things get rough is that I need to create a conditional that says
function generateNum (min, max) {
var randNumber = Math.ceil(Math.random()*(max - min)+min);
if (randNumber === max) {
// store the result (probably in an array) and generate a new
// number with the same behavior as randNumber (e.g. it is also
// stores it's total in the array and recursively "re-generates
// a new number until max is not hit)
}
}
The idea is to recursive-ise this so that a running total of the number of max hits is stored, combined, and then returned.
For example: The script receives min / max parameters of 5/10 generateNum(5,10){}. If the value generated by randNumber were 5, 6, 7, 8, or 9 then there would be no recursion and the function would return that value. If the value generated by randNumber is 10, then the value 10 is stored in an array and the function now "re-tries" recursively (meaning that as many times as 10 is generated, then that value is stored as an additional object in the array and the function re-tries). When the process stops (which could be infinite but has a parabolically decreasing probability of repeating with each recursion). The final number (5, 6, 7, 8, 9) would be added to the total of generated max values and the result would be returned.
Quite an unusual mathematic scenario, let me know how I can clarify if that doesn't make sense.
That part is easy.
Not as easy as you think... The algorithm that you have is broken; it will almost never give you the minimum value. Use the Math.floor method instead, and add one to the range:
var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;
To do this recursively is simple, just call the method from itself:
function generateNum (min, max) {
var randNumber = Math.floor(Math.random()*(max - min + 1)) + min;
if (randNumber == max) {
randNumber += generateNum(min, max);
}
return randNumber;
}
You can also solve this without recursion:
function generateNum (min, max) {
var randNumber = 0;
do {
var num = Math.floor(Math.random()*(max - min + 1)) + min;
randNumber += num;
} while (num == max);
return randNumber;
}
There is no need to use an array in either case, as you don't need the seprate values in the end, you only need the sum of the values.
I assume that you don't really need a recursive solution since you tagged this for-loop. This will return the number of times the max number was picked:
function generateNum (min, max) {
var diff = max - min;
if(diff <= 0)
return;
for(var i = 0; diff == Math.floor(Math.random()*(diff + 1)); i++);
return i;
}
Example outputs:
generateNum(1,2) // 3
generateNum(1,2) // 1
generateNum(1,2) // 0
generateNum(5,10) // 0
generateNum(5,10) // 1
Two things:
1) the probability to roll 10 stays (theoretically the same on each roll (re-try)), the low probability is of hitting n times 10 in a row
2) I don't see why recursion is needed, what about a while loop?
var randNumber;
var arr = [];
while ((randNumber = Math.ceil(Math.random()*(max - min)+min)) === max) {
arr.push(
}
I'd consider an idea that you don't need to use not only recursion and arrays but not even a for loop.
I think you need a simple expression like this one (separated into three for clarity):
function generateNum (min, max)
{
var randTail = Math.floor(Math.random()*(max - min)+min);
var randRepeatMax = Math.floor(Math.log(Math.random()) / Math.log(1/(max-min+1)));
return randRepeatMax*max + randTail;
}
Assuming one random number is as good as another, this should give you the same distribution of values as the straightforward loop.
Recursive method:
function generateNum (min, max) {
var res = Math.floor(Math.random() * (max - min + 1)) + min;
return (res === max) ? [res].concat(generateNum(min, max)) : res;
}

Categories

Resources