Getting all valid combinations in javascript - javascript

I think my title is not correct for this issue but since english is not my mother tongue i couldn't figure out a better way to title my problem.
So what i have is different Players with a few properties:
Player_one.name = "A";
Player_two.name = "B";
Player_three.name = "C";
Player_four.name = "D";
Players also have property:
Player_one.canPlay = ["B","D"];
Player_two.canPlay = ["A","D"];
Player_three.canPlay = ["A","C"];
Player_four.canPlay = ["B","D"]
//note that this is example and may not be accurate right now
Property canPlay shows with who player can play with.
Now players also have property called "placeInTable" which shows their current spot, for example position one, two or three etc.
What i would like to achieve is to check whether it is possible to make combinations from every canPlay array so that every player is able to play with another in the current round. In case there are several possible options, for example, if player one can play with player two and three and games still could be played with everyone then the player with higher "placeInTable" will be selected for an opponent.
To sum my idea up is that i'm trying to create a swiss system table which manages the next games properly. Algorithm should check every canPlay for each player and create combinations which would result in a way that every player is able to play with another and if several options for games are available it will choose the best opponent first according to "placeInTable".
What i've done so far is that i have an algorithm which will start checking the table from the beginning, if player can't play with another the lower one will be selected. Although my current algorithm is faulty since if the length-1 and length-2 players have played with each other the algorithm does not know what to do. So for that i'll add two upper players from which the algorithm crashes, currently length-1 and length-2 so the players length-3 and length-4 will be added and canPlay check will be ran.
I hope my description for this problem was not too misleading and could be understood and really big kudos to someone who is able to help.
If any questions i'd be happy to describe more about this issue.
Edit no. 1:
I forgot to add that in Swiss System two players can't play with each other once they've already played with each other. That's why i have canPlay and in first round the canPlay array length may be longer and in fifth or sixth it may be really small.
About answer which suggested that if A can play with B and B can play with C then A can play with C then no, it's not correct idea. Better understanding could be made with an example.
Let's say there are possible combinations like:
A vs B
C vs D
//and
A vs D
B vs C
Now in such manner every player can play with every other player but there's two options. Now if the table goes that player A has spot 1, player B spot 2, player C spot 3 and player D spot 4 then it should choose the first option because players in higher place in table should be placed together.
There could be of course a third option, player A vs player C && player B vs player D but i left it out right now. IF there would be third option then still the first one would be selected since it places the higher spots together.
Edit no. 2:
function reastaArray(){
var newArr = jQuery.extend(true,[],playerLst); //copy of original players
var original = jQuery.extend(true,[],playerLst);
var inPlay = []; //siia hakkame lisama
var firstRound = true;
var visitedCount = 1;
var i = 0;
var count = 0;
while (newArr.length != 0){
//this goes on until there are players left in playerList
count = i;
hereiam = false;
if (inPlay.length % 2 == 0){ //if the players in play are even amount then the first one gets pushed without a check
inPlay.push(newArr[i]);
newArr.splice(i,1);
}
else{ //now we need to search for opponent
var lastEl = inPlay[inPlay.length-1];
var element = newArr[i];
var played = hasPlayed(element,lastEl); //true/false, can we play with last element in inPlay, if it's true then while cycle begins
while (played == true){
count += 1;
if (count == newArr.length){ //if we've reached at the end of the newArr and still haven't found an opponent
//take in last played games into new array
takeLast(inPlay,newArr);
for (var y = 0; y<visitedCount;y++){
takeLast(inPlay,newArr);
takeLast(inPlay,newArr);
}
canWePlayNow(newArr);
//populize canPlay-s.
//IDEA FROM STACK
var combinations = findCombinations(newArr);
console.log("possible combinations");
combinations.forEach(function(comb) {
console.log(comb);
});
console.log(findBest(combinations,newArr));
visitedCount += 1;
}
else{
element = newArr[count];
played = hasPlayed(element,lastEl);
}
}
if (hereiam == false){
inPlay.push(element);
newArr.splice(count,1);
}
}
}
return inPlay;
}
function canWePlayNow(newArr){
for (var i = 0; i<newArr.length;i++){
var player = newArr[i];
player.canPlay = [];
var hasPlayed = player.playedNames;
for (var j = i+1; j<newArr.length;j++){
playerFromPlayed = newArr[j];
var inArr = isInArray(hasPlayed,playerFromPlayed.name);
if (inArr == false){
player.canPlay.push(playerFromPlayed.name);
}
}
}
}
The combination array could work better, right now as i tested it does:
As seen from image, first round is calculated great, now second round values are entered and third round calculation messes up: It could put together 5vs6 ; 1vs4 and 2vs3, but this algorithm you provided is pretty close already, could you give a further look to check out what's wrong?
Edit no 3:
With further inspection it seems like it's still doing something wrong. As seen from image below the correct result should be 1 & 2 and 5 vs 3 although next games shown are 1vs5 & 3vs2, which shouldn't be result.
The input for the array were Players who've had already one round of free or as in table "V". The algorithm you posted is unchanged.
As seen from console, the other option which i pointed out above is in combinations but it's not selected. Any ideas?
Edit no 4:
Added new image!
function findBest(combinations, players) {
if(combinations.length === 0) throw new Error();
var koht = {};
function score(comb) {
return comb.reduce(function(score, pair) {
//console.log("New calc:");
//console.log(score+koht[pair[0]]*koht[pair[1]]);
return score + koht[pair[0]] * koht[pair[1]];
}, 0);
};
players.forEach(function(p) {
koht[p.name] = p.koht;
});
var best = combinations[0];
combinations.slice(1).forEach(function(comb) {
console.log(score(comb) + " = combs & best = "+score(best));
console.log("Checked combs: ");
console.log(comb);
if(score(comb) > score(best)) {
best = comb;
}
});
console.log("Returned array: (best)");
console.log(best);
return best;
}
Added Log to KOHT

Here is some code that displays all possible combinations in which each player gets to play. It then tries to find the best one by preferring pairings of players in high spots.
function findCombinations(players) {
var combinations = [];
function removePlayer(a, name) {
for(var i = 0; i < a.length; i++) {
if(a[i].name === name) return a.slice(0, i).concat(a.slice(i+1));
}
return a;
}
function find(players, comb) {
if(players.length === 0) {
combinations.push(comb);
return;
};
var player = players[0];
player.canPlay.forEach(function(other) {
var newPlayers = removePlayer(players, other);
if(newPlayers !== players && other !== player.name) {
find(newPlayers.slice(1), comb.concat([[player.name, other]]));
}
});
}
find(players, []);
return combinations;
}
function findBest(combinations, players) {
if(combinations.length === 0) throw new Error();
var placeInTable = {};
function score(comb) {
return comb.reduce(function(score, pair) {
return score + placeInTable[pair[0]] * placeInTable[pair[1]];
}, 0);
};
players.forEach(function(p) {
placeInTable[p.name] = p.placeInTable;
});
var best = combinations[0];
combinations.slice(1).forEach(function(comb) {
if(score(comb) > score(best)) best = comb;
});
return best;
}
var p1 = {name: "A", canPlay: ["B", "D", "C"], placeInTable: 1},
p2 = {name: "B", canPlay: ["A", "D"], placeInTable: 2},
p3 = {name: "C", canPlay: ["A", "C", "D"], placeInTable: 3},
p4 = {name: "D", canPlay: ["B", "D", "C"], placeInTable: 4};
var players = [p1, p2, p3, p4],
combinations = findCombinations(players);
console.log("possible combinations");
combinations.forEach(function(comb) {
console.log(comb);
});
console.log("\nbest:");
console.log(findBest(combinations, players));

Related

Tic-tac-Toe regex

I am working on a tic-tac-toe algo and am using regexes to solve for the win conditions.
the 9 squares are given the 0-8 values:
[0][1][2]
[3][4][5]
[6][7][8]
Each time player 1 or 2 clicks a square the value is pushed to an array and after 3 values are collected the regex starts testing to see if a player has won.
the problem.. for example the regex test to see if any order of 012 102 exist but it can't match 03142.
How can I fix my Regex to look for the 3 numbers even if separated by other numbers?
Let regexWin = /(?:^|\W)[012][012][012](?:$|\W)/gm,
You could keep track of the board state, so you don't need to rely on the moves list: define board as an array of length 9, initialised with all 0 (indicating each cell is empty). Then when a move is played set the corresponding slot to either "1" or "2", depending on which player plays that move.
var board = Array(9).fill(0); // initial board
var moves = []; // initial move list
var turn = 1; // first player to move (other player is identified as 2)
// ...
function play(move) { // move is an index in board (0..8)
board[move] = turn; // turn is 1 or 2
moves.push(move); // this is the list you already have
// Use regular expression to detect any 3-in-a-row
let isWin = /^(?:...)*([12])\1\1|^.?.?([12])..\2..\2|^([12])...\3...\3|^..([12]).\4.\4/.test(board.join(""));
console.log("is winning move?", isWin);
turn = 3 - turn; // toggle the player that is to move
}
This way you also can use board to update the display.
For a full implementation, with rendering, and a minimax algorithm for generating a "best" move, see this answer.
Assuming the squares occupied are pushed into the object moves, which contains an array for each player, p1 and p2, just sort the arrays after each push. That way, can guarantee the indices are compared in ascending order.
let moves = {p1: [], p2: []};
function move(player, spaceIndex) {
moves[player].push(spaceIndex);
moves[player].sort();
if (/012|345|678|036|147|258|048|246/.test(moves[player].join('')) {
//win!
}
}
From the details given in your question it doesn't sound like you've realised that you need two arrays, not one, otherwise the win algo won't know which player occupies which space, and will report a win merely for three spaces in a row being occupied, even if they're shared between different players.
I did not find the Regex that worked, so I switched to a different idea.
Based on the article by Alvaro Saburido I learned how to take the winArray and the 1&2 playerArray for an intersection and test for a win.
The article is great and i'll keep searching for a regex solution just for coding fun.
https://medium.com/#alvaro.saburido/set-theory-for-arrays-in-es6-eb2f20a61848
let win = ["012", "345", "678", "036", "147", "258", "048", "246"];
function endGameEvaluation() {
if (joueur1Turn) {
resultMessage.innerHTML = `<div id="resultMessage">Player 1 Wins!! End of the game</div>`;
gameWon = true;
playerTurnMsg.innerHTML = "";
} else if (joueur2Turn) {
resultMessage.innerHTML = `<div id="resultMessage">Player 2 Wins!! End of the game</div>`;
gameWon = true;
playerTurnMsg.innerHTML = "";
}
}
function winner(player) {
for (var i = 0; i < 8; i++) {
let won = win[i]
let inCommon = player.filter(x => won.includes(x));
if (inCommon.length == 3) {
endGameEvaluation();
}
}
}
tdClickArea.forEach(item => {
item.addEventListener('click', e => {
let btnArea = e.target;
let player;
if (btnArea.innerHTML == "X" || btnArea.innerHTML == "O") {
alert("tricheur! Choisi une autre case")
} else {
if (joueur1Turn) {
btnArea.innerHTML = "X";
joueur1Sq.push(btnArea.getAttribute("value"));
player = joueur1Sq;
} else if (joueur2Turn) {
btnArea.innerHTML = "O";
joueur2Sq.push(btnArea.getAttribute("value"));
player = joueur2Sq;
}
}
if (joueur1Sq.length >= 3 || joueur2Sq.length >= 3) {
winner(player);
}
counter++;
changeTurn();
// Here we end the game if nobody won until the last posibble move
if (counter == 9 && gameWon == false) {
resultMessage.innerHTML = `<div id="resultMessage">End of the game</div>`;
}
})
});

discord.js How to fix variables coming back as undefined

I have scanned through the extensive list of questions asking similar things, but none of them have been able to solve this problem in this context.
Essentially, I'm attempting to build a blackjack command for a bot in discord.js, and so far, the flow looks like this: it takes the names and id's of all of the players and then passes them into the function that handles each game. First, three functions are defined. One that finds the value of a hand (the total of the cards) and one that adds a new card. A RichEmbed is created that will be edited many times, and the first time it is created in a game, it will give each person their hand, evaluate it, and then put it in the embed.
The problem is: the variables storing players' hands and hand values come back as undefined during initialization, even though I have tested that they can be output from the same place in the code, and that the functions that give them their data also work. What is causing them to be undefined, and why is it only those two variables? The others work just fine.
My code:
async function bj(players_id, players_names) {
var pc = players_id.length; //player count
var turn; //whose turn is it? based on id
var disp; //text to be shown in embed; game status.
var hands = []; //each player's hand
var handValues = []; //the sum of the cards in a hand
var cards = ["A", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K"]; //all possible cards
var ing = []; //is player in game? / have they busted?
turn = players_id[0];
var disp_dir = "React with �� to hit and ✋ to stand.";
disp = `Currently ${message.member.guild.members.get(turn).displayName}'s turn.\n${disp_dir}`;
function addCard() {return(cards[Math.floor(Math.random() * cards.length)])}; //simply grabs a card from the list of cards
function findHandValue(handValue, currentCards) { //takes two inputs, one is the current hand value, the other is a list of card values. finds the total value of the hand and returns it.
var val = 0;
for (i = 0; i < currentCards.length; i++) {
card = currentCards[i];
if (card == "A") {
if (handValue > 21) {val += 1;} else {val += 11;};
} else if (card == "J" || card == "Q" || card == "K") {
val += 10;
} else {val += card;};
};
return(val);
};
function makeEmbed(first) { //constructs the embed that will be used to show the game. param. first tells whether it is the first time the embed is being constrcuted in a game.
var bjg = new Discord.RichEmbed()
.setTitle("Blackjack Game")
.setDescription(`Initiated by ${players_names[0]}`)
.addField("Status", `${disp}`)
.setThumbnail("https://cdn.discordapp.com/attachments/563578266984775681/657323254813425674/cards.jpg")
.setColor("DC134C")
.setFooter("Valkyrie", client.avatarURL)
.setTimestamp();
if (first == true) {
for (i = 0; i < pc; i++) { //should be creating each player's hand
ing.push(true); //this one works
hands.push([addCard(), addCard()]); //but for some reason, this one returns undefined
handValues.push(findHandValue(0, hands[i])); //and this one
bjg.addField(`${players_names[i]}'s Hand`, `${hands[i]}\n\nValue: ${handValues[i]}`); //spits out undefined in almost every place, including the player_name[i]
var bjs = message.channel.send(bjg);
return(bjs);
};
};
};
var bjs = await makeEmbed(true); //and this stuff works fine
await bjs.react("��");
await bjs.react("✋");
};
if (args[0] == "quick") {
message.reply("You've started a game of solo blackjack against a bot!");
await bj([message.author.id], [message.member.displayName]);
Apologies that that is lengthy, but all of it is necessary to show what it's doing and to help pinpoint the error's origin.
Finally, this is the result
Extra Note
After extremely extensive debugging, I've found that the problem is coming from the line
handValues.push(findHandValue(0, hands[i]));, and the problem is that it changes i by +2, which only raises more questions. A small band-aid fix was to set another variable to i at the start and then reset i to the other one after the line.

Javascript Simon Game, how to check the answer

I am trying to make a simon game with Javascript for school. I currently have the code set up to create an array sequence of colors on it's own and have also successfully saved the users answers into it's own array, which gets cleared upon a new sequence. I am now trying to see if said color sequence matches the users color sequence, but I am unsure how to check this without any loopholes. The best I have gotten is being able to test the userClicks array length to the gamePattern array length and to ensure that the last click was indeed correct, but can't figure out a good way to test if the entire userClicks array is equivalent to the gamePattern array. I will also run into the problem that the array must be filled in an allotted time, I'll probably use the setTimout() function to achieve this. There must be an easier way to test if a given array is equal to another.
/*************VARIABLES*************/
//store colors
var buttonColors = [
"green", //0
"red", //1
"yellow", //2
"blue" //3
]
//Game Pattern Storage
var gamePattern = [ /*Added From nextSequence*/ ];
var userClicks = [ /* Added from userClickHistory*/ ];
var level = 0;
var gameOn = false;
/******************BASIC FUNCTIONS*********************/
/*AWAIT KEYPRESS TO BEGIN GAME*/
//some document listener to look for keypress changing gameOn to `true`
//display the level to user
//activate nextSequence();
//log user clicks after nextSequence has executed, check the userClicks vs gamePattern
$(`.btn`).click(function () {
var buttonClicked = $(this).attr(`id`);
userClicks.push(buttonClicked);
animate(buttonClicked);
playSound(buttonClicked);
checkAnswer(userClicks);
});
function checkAnswer(userClicksArray) {
//display the current level to user
//NOT SURE WHAT TO DO ANYMORE
}
/************* NEXT SEQUENCE TO PROGRESS GAME *********/
function nextSequence() {
userClickPattern = [];
level++;
console.log(level);
randomNumber = Math.floor(Math.random() * 4)
randomChosenColor = buttonColors[randomNumber];
gamePattern.push(randomChosenColor);
animate(randomChosenColor);
playSound(randomChosenColor);
}
/******************** SOUNDS AND ANIMATIONS*************************************/
//buttons animations
function animate(clickedButton) {
$(`#` + clickedButton).fadeOut(100).fadeIn(100);
};
//Play a sound in corellation to randomChosenColor
function playSound(color) {
var sound = new Audio('sounds/' + color + '.mp3');
sound.play();
};
You should start by comparing the lengths and if they are the same, just loop through the arrays and check that the value at each index is the same.
If the array is "flat" (no nested arrays or objects), this works nicely. If you have nested objects, you'll need something like this: How to compare arrays in JavaScript?
function checkAnswer(gamePattern, userClicks) {
const len = gamePattern.length;
if (len !== userClicks.length) {
// The lengths of the arrays don't match
return false;
}
for (let i = 0; i < len; i++) {
if (gamePattern[i] !== userClicks[i]) {
// The values at the same index don't match
return false;
}
}
return true;
}
console.log(checkAnswer(['red', 'blue', 'green'], ['red', 'blue', 'green']));
console.log(checkAnswer(['red', 'blue', 'green'], ['red', 'yellow', 'green']));

How to generate a new random number (that's different from the previous random number)

I'm trying to change the following (that currently returns a random number from an array), so that each random number is different from the last one chosen.
function randomize(arr) {
return arr[Math.floor(Math.random()*arr.length)];
}
oracleImg = [];
for (var i=1;i<=6;i++) {
oracleImg.push(i);
}
randOracleImg = randomize(oracleImg);
I tried the following, but it's not always giving me a number different from the last number.
function randomize(arr) {
var arr = Math.floor(Math.random()*arr.length);
if(arr == this.lastSelected) {
randomize();
}
else {
this.lastSelected = arr;
return arr;
}
}
How can I fix this?
Your existing function's recursive randomize() call doesn't make sense because you don't pass it the arr argument and you don't do anything with its return value. That line should be:
return randomize(arr);
...except that by the time it gets to that line you have reassigned arr so that it no longer refers to the original array. Using an additional variable as in the following version should work.
Note that I've also added a test to make sure that if the array has only one element we return that item immediately because in that case it's not possible to select a different item each time. (The function returns undefined if the array is empty.)
function randomize(arr) {
if (arr.length < 2) return arr[0];
var num = Math.floor(Math.random()*arr.length);
if(num == this.lastSelected) {
return randomize(arr);
} else {
this.lastSelected = num;
return arr[num];
}
}
document.querySelector("button").addEventListener("click", function() {
console.log(randomize(["a","b","c","d"]));
});
<button>Test</button>
Note that your original function seemed to be returning a random array index, but the code shown in my answer returns a random array element.
Note also that the way you are calling your function means that within the function this is window - not sure if that's what you intended; it works, but basically lastSelected is a global variable.
Given that I'm not keen on creating global variables needlessly, here's an alternative implementation with no global variables, and without recursion because in my opinion a simple while loop is a more semantic way to implement the concept of "keep trying until x happens":
var randomize = function () {
var lastSelected, num;
return function randomize(arr) {
if (arr.length < 2) return arr[0];
while (lastSelected === (num = Math.floor(Math.random()*arr.length)));
lastSelected = num;
return arr[num];
};
}();
document.querySelector("button").addEventListener("click", function() {
console.log(randomize(["a","b","c","d"]));
});
<button>Test</button>
Below code is just an example, it will generate 99 numbers and all will be unique and random (Range is 0-1000), logic is simple just add random number in a temporary array and compare new random if it is already generated or not.
var tempArray = [];
var i=0;
while (i != 99) {
var random = Math.floor((Math.random() * 999) + 0);
if (tempArray.indexOf(random)==-1) {
tempArray.push(random);
i++;
} else {
continue;
}
}
console.log(tempArray);
here is a version which will ensure a random number that is always different from the last one. additionally you can control the max and min value of the generated random value. defaults are max: 100 and min: 1
var randomize = (function () {
var last;
return function randomize(min, max) {
max = typeof max != 'number' ? 100 : max;
min = typeof min != 'number' ? 1 : min;
var random = Math.floor(Math.random() * (max - min)) + min;
if (random == last) {
return randomize(min, max);
}
last = random;
return random;
};
})();
If you want to ALWAYS return a different number from an array then don't randomize, shuffle instead!*
The simplest fair (truly random) shuffling algorithm is the Fisher-Yates algorithm. Don't make the same mistake Microsoft did and try to abuse .sort() to implement a shuffle. Just implement Fisher-Yates (otherwise known as the Knuth shuffle):
// Fisher-Yates shuffle:
// Note: This function shuffles in-place, if you don't
// want the original array to change then pass a copy
// using [].slice()
function shuffle (theArray) {
var tmp;
for (var i=0; i<theArray.length;i++) {
// Generate random index into the array:
var j = Math.floor(Math.random()*theArray.length);
// Swap current item with random item:
tmp = theArray[i];
theArray[j] = theArray[i];
theArray[i] = tmp;
}
return theArray;
}
So just do:
shuffledOracleImg = shuffle(oracleImg.slice());
var i=0;
randOracleImg = shuffledOracleImg[i++]; // just get the next image
// to get a random image
How you want to handle running out of images is up to you. Media players like iTunes or the music player on iPhones, iPads and iPods give users the option of stop playing or repeat from beginning. Some card game software will reshuffle and start again.
*note: One of my pet-peeves is music player software that randomize instead of shuffle. Randomize is exactly the wrong thing to do because 1. some implementations don't check if the next song is the same as the current song so you get a song played twice (what you seem to want to avoid) and 2. some songs end up NEVER getting played. Shuffling and playing the shuffled playlist from beginning to end avoids both problems. CD player manufacturers got it right. MP3 player developers tend to get it wrong.

Generating random unique data takes too long and eats 100% CPU

WARNING: CPU Usage goes to 100%, be careful.
Link to the jsFiddle
This script has been written to design a dynamic snake and ladder board. Everytime the page is refreshed a new board is created. Most of the time all of the background images do not appear, and the CPU usage goes up to 100%. But on occasion all of them appear and the CPU usage is normal.
Opera shows some of the background images, Firefox lags and asks me if I wish to stop the script.
I believe that the problem is with these lines of code:
for(var key in origin) // Need to implement check to ensure that two keys do not have the same VALUES!
{
if(origin[key] == random_1 || origin[key] == random_2 || key == random_2) // End points cannot be the same AND starting and end points cannot be the same.
{
valFlag = 1;
}
console.log(key);
}
Your algorithm is very ineffective. When array is almost filled up, you literally do millions of useless iterations until you're in luck and RNG accidentally picks missing number. Rewrite it to:
Generate an array of all possible numbers - from 1 to 99.
When you need a random numbers, generate a random index in current bounds of this array, splice element and this random position, removing it from array and use its value as your desired random number.
If generated numbers don't fit some of your conditions (minDiff?) return them back to array. Do note, that you can still stall in loop forever if everything that is left in array is unable to fit your conditions.
Every value you pull from array in this way is guaranteed to be unique, since you originally filled it with unique numbers and remove them on use.
I've stripped drawing and placed generated numbers into array that you can check in console. Put your drawing back and it should work - numbers are generated instantly now:
var snakes = ['./Images/Snakes/snake1.png','./Images/Snakes/snake2.jpg','./Images/Snakes/snake3.gif','./Images/Snakes/snake4.gif','./Images/Snakes/snake5.gif','./Images/Snakes/snake6.jpg'];
var ladders = ['./Images/Ladders/ladder1.jpg','./Images/Ladders/ladder2.jpg','./Images/Ladders/ladder3.png','./Images/Ladders/ladder4.jpg','./Images/Ladders/ladder5.png'];
function drawTable()
{
// Now generating snakes.
generateRand(snakes,0);
generateRand(ladders,1);
}
var uniqNumbers = []
for(var idx = 1; idx < 100; idx++){ uniqNumbers.push(idx) }
var results = []
function generateRand(arr,flag)
{
var valFlag = 0;
var minDiff = 8; // Minimum difference between start of snake/ladder to its end.
var temp;
for(var i = 0; i< arr.length; ++i) {
var valid = false
// This is the single place it still can hang, through with current size of arrays it is highly unlikely
do {
var random_1 = uniqNumbers.splice(Math.random() * uniqNumbers.length, 1)[0]
var random_2 = uniqNumbers.splice(Math.random() * uniqNumbers.length, 1)[0]
if (Math.abs(random_1 - random_2) < minDiff) {
// return numbers
uniqNumbers.push(random_1)
uniqNumbers.push(random_2)
} else {
valid = true
}
} while (!valid);
if(flag == 0) // Snake
{
if(random_1 < random_2) // Swapping them if the first number is smaller than the second number.
{
var temp = random_1; random_1 = random_2; random_2 = temp
}
}
else // Ladders
{
if(random_1>random_2) // Swapping them if the first number is greater than the second number.
{
var temp = random_1; random_1 = random_2; random_2 = temp
}
}
// Just for debug - look results up on console
results.push([random_1, random_2])
}
}
drawTable()
I had a problem like this using "HighCharts", in a for loop - "browsers" have an in-built functionality to detect dead scripts or infinite loops. So the browsers halts or pop-ups up a message saying not responding. Not sure if you have that symptom!
This was resulted from a "loop" with a large pool of data. I wrote a tutorial on it on CodeProject, you might try it, and it might be your answer.
http://www.codeproject.com/Tips/406739/Preventing-Stop-running-this-script-in-Browsers

Categories