i have been try to solve the sudoku with Blacktracking algo, everything is good, canvar is called and i able to see the number but the things is number are not moving i.e the logic is not exectuing
current.i === 0; is where i'm get the error! even i have declared a sperate variable for the num also the problem is not sloved. only if i remove the .num current == 0 than its not showing any error but still the number is not moving
enter image description here
var cell = [];
var stack = [];
var sudoku = [2,3,0,9,4,0,6,7,0,
8,0,0,3,2,5,9,1,4,
9,0,0,7,6,0,3,2,0,
1,0,0,0,0,0,7,9,2,
5,0,3,2,1,0,4,8,6,
4,0,0,6,8,0,5,3,1,
7,0,0,1,0,0,0,0,9,
6,5,9,8,7,2,1,4,3,
3,0,0,0,9,0,0,0,7];
var current;
var number = 1;
function setup(){
createCanvas(450,450);
var a=0;
var b=0;
for(var i=0;i<81;i++){
if(a%9==0 && i!=0){
b = b+50;
a = 0;
}
each[i] = new each(a,b,i,sudoku[i]);
a = a+50;
}
current = cell[0];
}
function draw(){
background(10);
for(var i=0;i<81;i++){
each[i].show();
}
if(current.num === 0){ //the error is typeerror can't read the property of num
if(! sameColumn(current.i,number) && ! sameRow(current.i,number) && ! sameSquare(current.i,number) && number<(10)){
current.num = number;
stack.push(current);
number = 0;
current.each[current.i+1];
}
else {
if(number > 8){
current.num = 0;
current = stack.pop();
number = current.num;
current.num = 0;
}
}
}
else{
current = each[current+1];
number = 0;
}
number++;
}
function each(a,b,i,num){
this.a = a;
this.b = b;
this.i = i;
this.num = num;
this.show = function(){
noFill();
stroke(255);
rect(this.a,this.b,50,50);
textSize(32);
text(this.num,a+12,b+40);
}
}
The error is pretty much straight forward. current = cell[0]; becomes undefined since you defined cell as an empty array and didn't manipulated it after that.
From what I have observed so far, many parts of your code logically does not work, for example,
same Column(current.i,number) && ! sameRow(current.i,number) && ! sameSquare(current.i,number)
will definitely throw you an error is it is executed (it is not since the execution does not reach to that line), unless you have a separate js file that contains these functions.
Another one is
current = cell[current+1];
if the current variable is to store the cell object, it does not make sense to add 1 to it, and vice versa.
Now I believe this is how setup function was meant to look like:
function setup(){
createCanvas(450,450);
var a=0;
var b=0;
for(var i=0;i<81;i++){
if(a%9==0 && i!=0){
b = b+50;
a = 0;
}
cell[i] = new Cell(a,b,i,sudoku[i]); //changed each[i] to cell[i], also renamed the 'each' class
a = a+50;
}
current = cell[0];
}
If possible, please edit in a little more information about what exactly does your code do. Cheers :)
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?
My Requirement:
I want to get the list of values using for loops. In for loop one iteration completed one time then the callback will send that list of values(array).
Once the first iteration completed second time loop value should be get incremented value.
For example : 5 values
after 5th iteration then loop is over. then second time loop should start with '0' but here it's starting with last incremented value. please help me to achieve this.
Below code is working fine for the first time.
Callback function:
$inventoryManagement.getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId(objectId,attributeId, function(objectAttributeBlockElement) {
//$scope.val = myOwnJ;
console.log(objectAttributeBlockElement);
});
Function:
var myOwnJ = 0;
// Getting ObjectId And AttributeId Using CellId For Normal Controls
var getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId = function(objectId,attributeId, callback) {
var objectAttributeBlockElement = [];// one array
try {
// iterate over the objectAttributes
for (var i = 0; i < pageObject.objects.length; i++) {
if (pageObject.objects[i].id == objectId) {
var name = "";
var labelName = "";
var dataTypeId = "";
for (;myOwnJ < pageObject.objects[i].objectAttribute.length;) {
name = pageObject.objects[i].objectAttribute[myOwnJ].name;// got the current label name
labelName = pageObject.objects[i].objectAttribute[myOwnJ].labelName;// got the current name
dataTypeId = pageObject.objects[i].objectAttribute[myOwnJ].dataTypeId;// got the current dataTypeId
objectAttributeBlockElement.push(name,labelName,dataTypeId);
callback(objectAttributeBlockElement, myOwnJ++);
return;
}
}
}
throw {
message: "objectId not found: " + objectId
};
} catch (e) {
console.log(e.message + " in getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId");
}
};
You could pass j as an additional function parameter, such as
var getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId = function(objectId, attributeId, j, callback) {
so it won't be a local variable. Then, instead of declaring it locally, use the following:
for (j = ((j === null) ? 0 : j); j < pageObject.objects[i].objectAttribute.length; j++) {
That way, if you call your function with j, you'll get it incremented after each call.
Another approach, which I won't recommend, would be making j a global variable by declaring it ouside your function instead of passing it as a parameter. That way you don't have to modify your function declaration at all. If you're up to that, I strongly suggest modifying the variable name cause j would be too generic for a global scope variable and it will cause trouble sooner or later: use something like myOwnJ and you'll be fine.
EDIT: Full source code (as requested by the OP):
var myOwnJ = 0;
// Getting ObjectId And AttributeId Using CellId For Normal Controls
var getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId = function(objectId,attributeId, callback) {
var objectAttributeBlockElement = [];// one array
try {
// iterate over the objectAttributes
for (var i = 0; i < pageObject.objects.length; i++) {
if (pageObject.objects[i].id == objectId) {
var name = "";
var labelName = "";
var dataTypeId = "";
if(myOwnJ < pageObject.objects[i].objectAttribute.length) {
name = pageObject.objects[i].objectAttribute[myOwnJ].name;// got the current label name
labelName = pageObject.objects[i].objectAttribute[myOwnJ].labelName;// got the current name
dataTypeId = pageObject.objects[i].objectAttribute[myOwnJ].dataTypeId;// got the current dataTypeId
objectAttributeBlockElement.push(name,labelName,dataTypeId);
callback(objectAttributeBlockElement, myOwnJ++);
return;
}
else {
myOwnJ = 0;
}
}
}
throw {
message: "objectId not found: " + objectId
};
} catch (e) {
console.log(e.message + " in getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId");
}
};
What you are looking for is a global variable for 'j'. Although this is discouraged to be used.
var j=0;
var getObjectNameAndAttributeAndDataTypeIdUsingObjectAndAttributeId =
function(objectId, attributeId, callback) {
//do your stuff
//increment j
j++;
}
Quick bit about my background:
-been learning for about 3 months;
-work in tech support for a small software company. 2 years exp.
-a lot of knowledge is secondhand and I am still learning the basics
I am trying to create an object every second. The object is created directly to the last position of an array that remembers a set quantity of objects created before the most recent one
function Fruit(name, position) {
this.name = name;
this.position = position;
}
var showXMostRecentFruits = 20;
var fruitCounter = 0;
function generateName() {
var name = 'Experimental Fruit' + fruitCounter;
return name;
}
var fruitsArray = [];
function shiftFruits() {
for (i = 0; i < showXMostRecentFruits; i++) {
fruitsArray[i] = fruitsArray[i + 1];
}
function updateFruitPositions() {
for (i = 0; i < showXMostRecentFruits; i++) {
fruitsArray[i].position = i;
}
}
var fruitTimer; //used for setting and clearing setTimeout
function createNewFruit() {
shiftFruits();
fruitsArray[showXMostRecentFruits - 1] = new Fruit(generateName());
updateFruitPositions();
fruitCounter += 1;
fruitTimer = setTimeout(function() {
createNewFruit();
}, 1000);
}
Say the function createNewFruit() is run once
createNewFruit();
Then I try to pull some meaning from the array
console.log(fruitsArray[19];
All I get is:
Fruit {}
undefined
This issue is when I want to run a loop (see updateFruitPositions()) that updates a propery of each object in the array, an error is returned that the objects are undefined. I get that they are undefined because they are not assigned to unique variables (at least not that I'm aware of). How can I identify the objects or how can I create unique containers for them so I access them in the array?
You need to test whether a given element is set to something before attempting to write to one of its properties.
Instead of this...
for (i = 0; i < showXMostRecentFruits; i++) {
fruitsArray[i].position = i;
}
Use this:
for (i = 0; i < showXMostRecentFruits; i++) {
if (fruitsArray[i])
fruitsArray[i].position = i;
}
You fill the array from the end, staring with element 20. Without the if (fruitsArray[i]), you're attempting to set undefined.position = i for the first 19 elements.
You could replace the showFruits function with something much more efficient:
function shiftFruits() {
if (fruitsArray.length > showXMostRecentFruits) {
fruitsArray.shift();
}
}
and updateFruitPositions only needs to update members that exist, the length is controlled by shiftFruits:
function updateFruitPositions() {
for (i = 0; i < fruitsArray.length; i++) {
fruitsArray[i].position = i;
}
}
or where forEach is supported:
function updateFruitPositions() {
fruitsArray.forEach(function(fruit, i){fruit.position = i});
}
so it only visits members that exist. And the createNewFruit has:
fruitsArray.push(new Fruit(generateName());
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);
}
}
}