Sean
Sean

Reputation: 33

Javascript: elements are not being deleted from the array

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

Answers (5)

Matt Way
Matt Way

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

muecas
muecas

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

Rohith Murali
Rohith Murali

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

elyalvarado
elyalvarado

Reputation: 1296

You have some errors in your script that prevent it to fully execute:

  1. there is no element with id colorvalue in your fiddle. But I assume that is because you pasted incomplete code.

  2. 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.

  3. 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

bluelovers
bluelovers

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

Related Questions