Reputation: 33
I'm trying to make a 4x4 grid of squares randomly change color every 1/4 of a second. If the grid changes colors it has a cooldown of 2 seconds before it can change again. I'm trying to accomplish this by removing the element from the array and then when 8 more changes happens it gets added back. My issue is that it doesn't seem like elements are actually getting deleted from the array and I'm not sure why.
You can see my code here
http://jsfiddle.net/jb60r6dx/1/
var eligable = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
var deleted;
var count = 0;
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
setInterval(function() {
//re-add the element
//8 cycles == 2 seconds
if (count % 8 == 0 && count != 0) {
eligable.push(deleted.shift());
}
//find random element
var rand = Math.floor(Math.random() * eligable.length);
var element = document.getElementById(eligable[rand]);
//get random color
var r = getRandomInt(0, 255);
var g = getRandomInt(0, 255);
var b = getRandomInt(0, 255);
//change color
element.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
document.getElementById("colorvalue").innerHTML = r + " " + g + " " + b;
//remove changed grid
removeEle(eligable[rand]);
//count cycle
count += 1;
}, 250);
//Removes the selected element and push to deleted array
function removeEle(ele) {
deleted.push(ele);
var index = eligable.indexOf(ele);
if (index > -1) {
eligable.splice(index, 1);
}
}
Upvotes: 0
Views: 79
Reputation: 33179
So a better way to achieve what you want, in my opinion is to use a shuffle over two arrays (eligible and deleted).
Basically you use a single array, and select a random index from 0 to the number of leftovers, and swap the selection with the last one in the remaining list. This means the first part of your array are the available items, and the last part of your array is always the deleted items.
// here is an example of what your array could look
// like at a certain time using a shuffle
[1, 3, 5, 2, 11, 12, 15, 8, 4, 7, 10, 9, 6, 13, 14]
<------------ eligible ---------------^--deleted-->
For example:
var set = [...Array(16).keys()]
var lastAvailable = set.length - 1
const getRandItemShuffle = () => {
// if 8 have been selected reset
if(lastAvailable < 8){ lastAvailable = set.length - 1 }
// get a random item from the leftovers
var rIndex = getRandomInt(0, lastAvailable)
var item = set[rIndex]
// swap the selected with the last available
set[rIndex] = set[lastAvailable]
set[lastAvailable] = item
// reduce the size of the available
lastAvailable--
return item
}
setInterval(() => {
var rand = getRandItemShuffle()
var element = document.getElementById(rand)
//get random color
var r = getRandomInt(0, 255)
var g = getRandomInt(0, 255)
var b = getRandomInt(0, 255)
//change color
element.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")"
document.getElementById("colorvalue").innerHTML = r + " " + g + " " + b
}, 250)
I have updated your fiddle with a working version here: http://jsfiddle.net/56a1o2qb/2/
EDIT: I realised that you want the search to reset after 2 seconds (not 4 seconds if you rotate all of them). I have updated the code and fiddle to reflect the change, but all you need to do is change the reset line in the shuffle function to be 8 instead of 0
Upvotes: 0
Reputation: 4335
The problem (beside several script errors: deleted
wasn't an array so you can't push
or shift
elements, there queried elements by id that the html doesn't contain) is that 8 elements are removed from eligable
while you only add one. The script will run fluid initially (after fixing the errors), until the eligable
array is empty (then the scripts failed to select the next element, the selection failed cause you tried to select an elemet from an empty array).
Check my working example:
var eligable = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var deleted = [];
var count = 0;
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
setInterval(function() {
//re-add the element
//8 cycles == 2 seconds
if (count % 8 == 0 && count != 0) {
eligable.push(deleted.shift());
}
// If there are no more eligable elements
if(eligable.length == 0) {
count++; // keep counting
return;
}
//find random element
var rand = Math.floor(Math.random() * eligable.length);
var element = document.getElementById(eligable[rand]);
//get random color
var r = getRandomInt(0, 255);
var g = getRandomInt(0, 255);
var b = getRandomInt(0, 255);
//change color
element.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
document.getElementById("colorvalue").innerHTML = r + " " + g + " " + b;
//remove changed grid
removeEle(eligable[rand]);
//count cycle
count ++;
}, 250);
//Removes the selected element and push to deleted array
function removeEle(ele) {
deleted.push(ele);
var index = eligable.indexOf(ele);
if (index > -1) {
eligable.splice(index, 1);
}
}
html,
body {
margin: 0;
}
.w {
overflow: hidden;
}
section div {
background: #000;
float: left;
height: 24vw;
margin: 1%;
width: 23%;
}
section {
margin: -1%;
padding: 20px;
}
<div id="colorvalue"></div>
<div class="w">
<section>
<div id="0"></div>
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
<div id="5"></div>
<div id="6"></div>
<div id="7"></div>
<div id="8"></div>
<div id="9"></div>
<div id="10"></div>
<div id="11"></div>
<div id="12"></div>
<div id="13"></div>
<div id="14"></div>
<div id="15"></div>
</section>
</div>
Upvotes: 0
Reputation: 5669
I have changed the js code to the following. Trythis, its working
var eligable = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
var deleted=[];
var count = 0;
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
setInterval(function() {
//re-add the element
//8 cycles == 2 seconds
if (count % 8 == 0 && count != 0) {
eligable.push(deleted.shift());
}
//find random element
var rand = Math.floor(Math.random() * eligable.length);
var element = document.getElementById(eligable[rand]);
if(element){
}
if(element){
//get random color
var r = getRandomInt(0, 255);
var g = getRandomInt(0, 255);
var b = getRandomInt(0, 255);
//change color
element.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
}
var colorVal = document.getElementById("colorvalue")
if(colorVal)
colorVal.innerHTML = r + " " + g + " " + b;
//remove changed grid
removeEle(eligable[rand]);
console.log(eligable);
//count cycle
count += 1;
}, 250);
//Removes the selected element and push to deleted array
function removeEle(ele) {
deleted.push(ele);
var index = eligable.indexOf(ele);
if (index > -1) {
eligable.splice(index, 1);
}
}
Upvotes: 1
Reputation: 1296
You have some errors in your script that prevent it to fully execute:
there is no element with id colorvalue
in your fiddle. But I assume that is because you pasted incomplete code.
You have to initialize deleted
to be an empty array, otherwise you would get an error when you try to push to it on the removeEle
function.
You have to stop removing elements and trying to color them when the array is already empty. Wrap your code between //find random element
and //remove changed grid
in an if(eligable.length)
Like this fiddle
Upvotes: 0
Reputation: 1255
looks like u miss document.getElementById("colorvalue")
this elem in html
so the founction always stop on document.getElementById("colorvalue").innerHTML
Upvotes: 0