Why is this labeled javaScript continue not working? - javascript

I am using this code to weather some circles are overlapping:
iCantThinkOfAGoodLabelName:
x = genX(radius);
y = genY(radius);
for(i in circles) {
var thisCircle = circles[i];
if(Math.abs(x-thisCircle["x"])+Math.abs(y-thisCircle["y"])>radius*2) { //No overlap
continue;
} else { //Overlap
continue iCantThinkOfAGoodLabelName; //<- Line 256
}
thisCircle = [];
}
But when the continue statement is reached, chrome's developer console gives me this: client.html:256 Uncaught SyntaxError: Undefined label 'iCantThinkOfAGoodLabelName'

The label should come immediately before the loop
x = genX(radius);
y = genY(radius);
iCantThinkOfAGoodLabelName:
for(i in circles) {

Because iCantThinkOfAGoodLabelName: needs to be right before the loop.
iCantThinkOfAGoodLabelName:
for (blah; blah; blah)
..
I think what you want is a function..
function iCantThinkOfAGoodFunctionName() {
var x = genX(radius),
y = genY(radius);
for (i in circles) {
var thisCircle = circles[i];
if(Math.abs(x-thisCircle["x"])+Math.abs(y-thisCircle["y"])>radius*2) { //No overlap
continue;
} else { //Overlap
iCantThinkOfAGoodFunctionName();
}
thisCircle = [];
}
}

There should not be any statement between a label name and associated loop.
x = genX(radius);
y = genY(radius);
iCantThinkOfAGoodLabelName:
for(i in circles) {
fixes it.

I recently had this issue and I resolved it by using all lowercase in the loop's label in version v0.8.x of Node.js.
Using labelname: vs. iCantThinkOfAGoodLabelName: might help you.
Others have correctly corrected you on the location of the label. It should be immediately before the for loop.
The Mozilla Developer Network on labels advises to avoid using labels, and instead prefer calling functions or throwing an error. You might rethink your strategy on using them, if possible.
Example of calling a function depending on result:
var i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
// we want to ignore and continue
} else {
// do work with these variables from inside the doWork function
// (scoped to whatever scope `this` for loop is in)
doWork.call(this, i, j);
}
}
}

Related

Javascript 2d for loop doesn't iterate through the final value of the outer loop

I have a for loop that behaves differently depending on what type of input it has. The logic that changes its behavior can't effect the problem that I am having. Here is my code, then I will explain the problem.
propagateForward(input)
{
for(let i = 0; i < input.length; i++)
{
this.NN[0][i] = input[i];
}
for(let i = 0; i < this.NN.length-1; i++)
{
//The problem occurs between the next two console.logs when the neural network is not
//the Actor agent, but is instead the critic agent. In the console "outside" will print
//and "inside" won't print. Whereas they both should print.
if(i == this.NN.length-2 && !this.isActor) console.log("outside");
for(let j = 0; j < this.NN[i+1].length-1; j++)
{
if(i == this.NN.length-2 && !this.isActor) console.log("inside");
var weightsSum = 0;
for(let r = 0; r < this.NN[i].length; r++)
{
if(r == this.NN[i].length-1 && i != 0)
{
weightsSum += this.NN[i][r];
}
else
{
var NodeVal = this.NN[i][r];
weightsSum += this.weights[i][r][j] * NodeVal;
}
}
if(i == this.NN.length-2)
{
if(!this.isActor) console.log(weightsSum);
this.NN[i+1][j] = weightsSum;
}
else
{
if(this.isActor) this.NN[i+1][j] = tanh(weightsSum);
else
{
this.NN[i+1][j] = ReLU(weightsSum);
}
}
}
}
if(this.isActor)
{
this.NN[this.NN.length-1] = softMax(this.NN[this.NN.length-1]);
}
return this.NN[this.NN.length-1];
}
It is the propagate forward for a neural network. This question is related to my bug with the for loop and not have anything to do with NN. I need to calculate the last layer of the Critic neural network, but 'i' will not loop to i = 2 which is the last possible idx inside of the inner loop. I have console log on the outside. When I run the program it only detects i = 2 on the outside loop, but can't access it on the inside loop. Thus the console of my program reads:
outside
outside
outside
outside
outside
outside
outside
outside
outside
outside
...
I want it to say outside and inside.
The only thing in between the two points where I am printing the same information from and getting different results is the declaration of the inner for loop. It works fine when the boolean this.isActor = true (It calculates the actor network just fine). The boolean this.isActor is the only difference between when it works and doesn't work. Neither of the console.log lines where I am testing are being affected by any if statements.
Given that this.NN.length = 4
Question: Why is the inner for loop not able to access i = 2, but the outer for loop can access i = 2?

Uncaught TypeError: Cannot read property of undefined when trying to receive an object scecific variable form a 2D array

I am using a JavaScript library called "P5.js". It has a setup function, which is executed when everything has loaded, and a draw function, which starts too loop after setup() is executed.
I am trying to code a maze generation algorithm and I am using a multi-dimensional array (an array of arrays) for the grid called x, which only contains Cell objects.
I am creating the array like this:
//Global variable declaration
var x = [];
//What I write in setup()
for(var i = 0; i < nw; i++) {
var y = [];
x.push(y);
}
for(var i = 0; i < nw; i++) {
for(var j = 0; j < nh; j++) {
var c = new Cell(i, j);
x[i].push(c);
}
}
In the draw() loop I display the cells with a function that is also called draw() like this:
for(var i = 0; i < x.length; i++) {
for(var j = 0; j < nh; j++) {
x[i][j].draw();
x[i][j].checkNeighbours();
}
}
The draw() function draws a line on each side of the cell.
Now comes my problem:
I have a function called checkNeighbours() which wants to access the multi-dimensional array from the Cell object like this:
this.checkNeighbours = function() {
if(this.indexY == 0 || x[this.indexX][this.indexY - 1].visited) {
this.neighbours[0] = false;
}
}
Now my browser only draws the first two cells (x[0][0] and x[0][1]) before saying (in the console): "Uncaught TypeError: Cannot read property '0' of undefined".
The issue is not the possible out of bounds exception (as called in java), because it also does say the same thing when I remove the - 1. When I input x[0][0].visited it return false and not undefined.
Does anyone have an idea what causes this problem?
It's not saying "Cannot set property 0 of undefined" so, it can't be the this.neighbors[0] = false line.
x[this.indexX] must be undefined.
Try this:
this.checkNeighbours = function() {
console.log('this.indexX: ', this.indexX);
var xx = x[this.indexX];
console.log('xx: ', xx);
if(this.indexY == 0 || x[this.indexX][this.indexY - 1].visited) {
this.neighbours[0] = false;
}
}
Also, just console.log(x) itself after it has been set up, before the first call to checkNeighbours, and examine it in the console and see if it contains what you're expecting it to.
Another possibility is that the error is not in this code at all, but in the Cell constructor or something.
What code line does the error reference?

Why are my variables "undefined"

I am new to Javascript and I am building my very first simple game "battle ship". Now I have a very frustrating problem.
I declared a variable in the global scope, but I cannot seem to use it in my program. If I do console.log(x); it says the variable is undefined.
When the user clicks a button called "Play" I want the background color of all cells to turn back to lightblue again;
function playGame() {
x.style.backgroundColor = 'lightblue';
}
This is the error message:
Uncaught TypeError: Cannot set property 'backgroundColor' of undefined
Even if I would replace the x with document.getElementsByTagName("td"); it does not work
var tabel = document.getElementById("slagveld");
var x = document.getElementsByTagName("td");
var gekozenVakken = [];
var hit = 0;
var pogingen = 0;
function reset() {
location.reload();
}
function veranderKleur(geklikteCel) {
if (gekozenVakken.length < 3) {
geklikteCel.style.backgroundColor = 'yellow';
gekozenVakken.push(parseInt(geklikteCel.innerHTML));
}
if (gekozenVakken.length === 3) {
alert("guess the position of the ship.");
}
}
function playGame() {
geklikteCel.style.backgroundColor = 'lightblue';
}
for (var i = 0; i < tabel.rows.length; i++) {
for (var j = 0; j < tabel.rows[i].cells.length; j++) {
tabel.rows[i].cells[j].onclick = function() {
veranderKleur(this);
}
};
}
I hope someone could help me out.
GetElementsByTagName() returns an array of objects, even if there is only 1 object with that tag. Since the array itself does not have the property .style, you get an 'undefined' message when accessing sub-members of .style.
You need to select an element from that array to access its properties:
x[0].style.backgroundColor = 'lightblue';
With the [] square braces you can access any element of an array. In my example, we're accessing the first element (at index 0). Which element you need is up for you to determine.
That function returns a list of nodes, even though there's only one
use document.getElementsByTagName("td")[0].style.color= 'lightblue';
function playGame() {
x[0].style.backgroundColor = 'lightblue';
}
fiddle
If the line
var x = document.getElementsByTagName("td");
is before your <table>, that element won't exist when the line is executed.
Ensure you are adding your script at the end of your HTML document or it will return an empty array (please note that the function is called "get elements by tag name", in plural).
I assume you're running this in your browser and this is your entire code.
Problem here: You're trying to read content from the DOM, however, your DOM might not be entirely loaded at the time you try to read from it.
This is easily fixable though:
In your HTML:
<body onload="start();"></body>
And in your JS code:
function reset() {
location.reload();
}
function veranderKleur(geklikteCel) {
if (gekozenVakken.length < 3) {
geklikteCel.style.backgroundColor = 'yellow';
gekozenVakken.push(parseInt(geklikteCel.innerHTML));
}
if (gekozenVakken.length === 3) {
alert("guess the position of the ship.");
}
}
function playGame() {
geklikteCel.style.backgroundColor = 'lightblue';
}
function start() {
var tabel = document.getElementById("slagveld");
var x = document.getElementsByTagName("td");
var gekozenVakken = [];
var hit = 0;
var pogingen = 0;
for (var i = 0; i < tabel.rows.length; i++) {
for (var j = 0; j < tabel.rows[i].cells.length; j++) {
tabel.rows[i].cells[j].onclick = function() {
veranderKleur(this);
}
};
}
}
This will ensure that all your reading/executing will perform when the entire DOM was loaded.
If you're not running code in your browser, please give more details in your question.
I would guess it's because the code for initializing the variables never actually gets called. Try doing it as follows (you need jQuery for it):
$('document').ready(function(){
var tabel = document.getElementById("slagveld");
var x = document.getElementsByTagName("td");
var gekozenVakken = [];
var hit = 0;
var pogingen = 0;
});
This way as soon as your DOM is loaded into the browser the variables will get initialized.
getElementsByTagName return a list of elements with the name "td" and you don't have the property backgroundColor for the list of elements, you must use a function like foreach.
Array.prototype.forEach.call(x, function(el, i){
el.style.backgroundColor = 'yellow';
});
And each element will in "x" will have the background color yellow.
You're looking for document.getElementById

JS crashes sometimes with Timer scramble

My Javascript timer is for people with a rubiks cube with generates a scramble (nevermind all this, but just to tell you I'm generating after each solve a new scramble will be generated) and my scrambles do actually have a while (true) statement. So that does crash my script, but it 95/100 times stops just before the script crashes but I don't wanna have any times.
Let me explain a bit more detailed about the problem.
Problem: javascript crashes because my script takes too long to generate a scramble.
Below you have 3 functions I use.
This function generates a scramble with the Fisher-Yates shuffle.
Timer.prototype.generateScramble = function(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
};
This function validates the input e.g. I receive an array as the following:
Here I only have to check the first character. That's why I use the seconds [ ] notation. I don't want people get an F with an F2 e.g.
var scr = ["F","R","U","B","L","D","F2","R2","U2","B2","L2","D2","F'","R'","U'","B'","L'","D'"]
Timer.prototype.validateScramble2 = function(array) {
var last = array.length-1;
for (var i = 0; i < array.length-1; i++) {
if (array[i][0] == array[i+1][0]) {
return false;
}
}
for (var i = 0; i < array.length-2; i++) {
if (array[i][0] == array[i+2][0]) {
return false;
}
}
if (array[0][0] == [last][0]) {
return false;
}
return true;
};
The above functions are just waiting to be called. Well in the function below I use them.
Timer.prototype.updateScramble2 = function(scrambleArr, len, type) {
var self = this;
var scramble = '', j, updatedArr = [];
while (updatedArr.length < len) {
j = (Math.floor(Math.random() * scrambleArr.length));
updatedArr.push(scrambleArr[j]);
}
while (!self.validateScramble2(updatedArr)) {
updatedArr = self.generateScramble(updatedArr);
}
for (var i = 0; i < updatedArr.length; i++) {
scramble += updatedArr[i] + ' ';
}
scrambleDiv.innerHTML = scramble;
};
I assume you guys understand it but let me explain it briefly.
The first while-loop adds a random value from the given array(scrambleArr) into a new array called updatedArr.
The next while-loop calls the validateScramble2() function if there isn't in an array F next to an F2.
The for-loop adds them into a new variable added with a whitespace and then later we show the scramble in the div: scrambleDiv.innerHTML = scramble;
What do I need know after all this information?
Well I wanna know why my updateScramble2() functions lets my browser crash every time and what I do wrong and how I should do it.
I'm not entirely sure I understand the question, but from the way your code looks, I think you have an infinite loop going on. It appears as if validateScramble2 always returns false which causes your second loop in updateScramble2 to perpetually run.
I suggest you insert a breakpoint in your code and inspect the values. You could also insert debugger; statements in your code, works the same way. Open dev tools prior to doing these.
A suggestion is instead of using loops, use a timer. This breaks up your loop into asynchronous iterations rather than synchronous. This allows the browser breathing space for other operations. Here's an example of a forEachAsync:
function forEachAsync(array, callback){
var i = 0;
var timer = setInterval(function(){
callback.call(null, array[i]);
if(++i >= array.length) clearInterval(timer);
}, 0);
}
forEachAsync([1,2,4], function(item){
console.log(item);
});
You can take this further and use Promises instead of callbacks.

Function is not completely executed

I have this function that causes the other functions to be skipped
I was just wondering what's wrong?
function sToLeftDiagonal(){
alert("sToLeftDiagonal");
var x, y;
var dCtr = 0;
var hLoop = varInit.maxRow;
for(var fifteen = 0; fifteen <= 3; fifteen++){
x = 0;
y = 5 - fifteen;
for(var xy = 0; xy <= hLoop ; xy++){
if (board[y][x] == player){
alert("plus");
dCtr++;
}else{
alert("negative");
dCtr = 0;
}
if (dCtr == varInit.cWins) {
dWinner(player);
}
x++;
y--;
}
hLoop--;
}
alert("end diagonal");
}
I've placed a lot of 'alert' to check whether they are executed or not, apparently
alert("end diagonal");
is not executed thus skips the next function in the main program
i know this is simple, i think i'm just overlooking some things..
thanks
i figured out what was causing the function to stop unexpectedly and not reach the last alert. it's because the values of [y] and [x] are wrong as i tried alerting every array index that the function goes through and variable y had an index of [-2] which wasn't suppose to be there.

Categories