Javascript recursion variable scope - javascript

I have a recursive function(see code), if i start with depth 5
When branch
execute(depth-1,x,y,width/2,height/2);
finishes, depth is not 5 for
execute(depth-1,midX,y,width/2,height/2);
but 1, and it produces mess. You can see algorithm here: http://jsfiddle.net/g4p66/
It supposed to produce something that looks like a maze(a poorly designed maze, hah)
function execute(depth,x,y,width,height){
if(depth > 0){
var midX = (x+width)/2;
var midY = (y+height)/2;
c.save();
c.beginPath();
c.moveTo(midX,midY);
var from = Math.floor(Math.random()*4);
if(from === 0){
c.lineTo(midX,y);
} else if(from === 1){
c.lineTo(x+width,midY);
} else if(from === 2){
c.lineTo(midX,y+height);
} else if(from === 3){
c.lineTo(x,midY);
}
c.stroke();
c.restore();
execute(depth-1,x,y,width/2,height/2);
console.log(depth);
execute(depth-1,midX,y,width/2,height/2);
execute(depth-1,x,midY,width/2,height/2);
execute(depth-1,midX,midY,width/2,height/2);
}
}
EDIT:
I was reading console.log wrongly, so it got me confused.
The main reason is my midX midY calculation was wrong, should be:
var midX = (x+(x+width))/2;
var midY = (y+(y+height))/2;

You don't have a variable scope problem but a problem of logic in interpreting the log.
The first console.log you see isn't the one at the top level of the recursion but the one at the deepest level, because that's the execution order.
Here's what happens :
execute(5)
execute(4)
execute(3)
execute(2)
execute(1)
execute(0) : depth <=0 -> return
console.log(depth) -> logs 1
You can check on your own screeshot that you're deep in the recursion when you get to the log :

Related

How find square root n by computing the next Xi term on javascript

Write the function sqrt(A) for computing square root of positive real numbers using next numerical method xi+1 = (1/2) * (xi +(A/xi)). Where the A - input rial number;
On zero iteration next statements have been taken: x0 = A;
The error should be at least 10^-6
You could take the last value xi-1 and compare it with the new value xi instead of using a loop counter.
function sqrt(a, x = 1) { // take 1 for x(0) as start value for recursion
var y = (x + a / x) / 2; // prepare next value x(i+1)
if (x === y) { // exit condition
return x;
}
return sqrt(a, y); // tail call optimization
} // https://stackoverflow.com/q/310974/1447675
console.log(sqrt(2));
console.log(sqrt(10));
console.log(sqrt(9));
console.log(sqrt(25));
Looks like your requirement is not just finding the square root of a number. If by any chance that is your requirement, use Math.sqrt.
If your requirement is to implement a function to find the square root for educational purpose, what you need is to write a recursive function as below. Modify the code as required to support error at 10^-6
function sqrt(A, i = 0) {
if (i === 0)
return A;
let prev = sqrt(A, i - 1);
return 0.5 * (prev + (A / prev));
}
console.log(sqrt(2,1000));
console.log(sqrt(3,1000));
console.log(sqrt(9,1000));
console.log(sqrt(25,1000));

HTML, JS Logic not working

I am trying to create a js logic function to solve the variables in an equation like this: 2x+5x=16. The problem is that it is supposed to output x=3 y=2, but instead, it outputs x=-11 y=1.
function solver(){
//Get c1, c2, and the answer
var c1=parseInt(prompt("Enter the coefficient of x:", "Example: 2 if you have 2x"));
var c2=parseInt(prompt("Enter the coefficient of y:", "Example: 3 if you have 3y"));
var answer=parseInt(prompt("Enter the answer:", "Example: 2x=4 it would be 4"));
//set other variables
var x;
var y;
var m;
//setup
x=answer/c1;
m=answer%c1;
//loop
while(true){
//if it is not an integer or it is 0
if (isInt(m/c2) === false || m/c2 == 0){
x=x-1;
m=answer%x;
}else if (isInt(m/c2)===true && m/c2 != 0){
x=x;
y=m/c2;
break;
}
}
alert("x="+x+" y="+y);
}
function isInt(n) {
return n % 1 === 0;
}
<h1>EXAMPLE: 2x+5y=16</h1>
<button onclick="solver()">Solve!</button>
Because if
nx+ky=a and x=a/n,
ky=a-(na)/n=0,
but if
x=f, y=(a-nf)/k.
You have infinitely many solutions for linear function with two unknowns.
Are you aware that there are infinite amounts of solutions?
and any given X and y that sastisfy x = 8 - 2.5y will be true?, in fact you can program the algorithm fixing y = 0, and you will get x = 8.
so you can either input two sets of xy solutions or you have infinite answers.
As a thumb rule, you need as much equations as vars
PD: I dont really get what are you doing inside the loop

Game of Life custom algorithm won't work properly

For some reason, my Game of Life algorithm for JavaScript won't work. I tried to test it with a Blinker
but it very quickly did not work
(note, this is an infinite plane so those 2 at the bottom are actually above the top.)
It makes a very interesting design, but it isn't the Game of Life.
My code runs as
var RxC = []; //the array to hold information about the plane
var drawGame = function(first) {
for (var i=0;10000>i;i++) {//for each box
var x = i%100;//gets what x block it is
var y = Math.floor((i-x)/100);//gets what y block it is
var box = canvas.getContext('2d');
if (first) {
if (!RxC[y]) RxC[y] = [];
RxC[y][x] = Math.round(Math.random()) === 1;//random alive or dead
}else {
//get all neighbors
//I am using 99 because the plane is 100 wide and 100 tall, but since arrays count from 0, I have to use 99 instead of 100
var neighbors = 0;
var topY = (y-1 < 0) ? 99 : y-1;
var bottomY = (y+1 > 99) ? 0 : y+1;
var leftX = (x-1 < 0) ? 99 : x-1;
var rightX = (x+1 > 99) ? 0 : x+1;
//N
if (RxC[topY][x]) neighbors++;
//NE
if (RxC[topY][rightX]) neighbors++;
//E
if (RxC[y][rightX]) neighbors++;
//SE
if (RxC[bottomY][rightX]) neighbors++;
//S
if (RxC[bottomY][x]) neighbors++;
//SW
if (RxC[bottomY][leftX]) neighbors++;
//W
if (RxC[y][leftX]) neighbors++;
//NW
if (RxC[topY][leftX]) neighbors++;
if (RxC[y][x]) {//if block is alive
if (neighbors === 0 || neighbors >= 4) //kill block?
RxC[y][x] = false;
}else {//block is dead
if (neighbors === 3) //revive block?
RxC[y][x] = true;
}
}
if (RxC[y][x]) {//block is alive
box.fillStyle = '#000';
}else {//block is dead
box.fillStyle = '#eee';
}
box.fillRect(5*x,5*y,5,5);
box.strokeRect(5*x,5*y,5,5);
}
};
drawGame(true);//run game for first time, this will create the board originally
setInterval(drawGame, 25);
The code will basically
make the board randomly
run the rules
if the block is alive, and it has 0 neighbors or 4 or more neighbors, it will die
if the block is dead, and it has 3 neighbors, it will revive
I got the rules from here, but the rules seem to not work...at all.
I have tried to remove the infinite plane (the shorthand if else statements in the neighbor section), checked my code repeatedly, and I have tried to use Google and Wikipedia etc. to see if the rules I am using is incorrect, but I can't find anything saying different.
So my question is, are the rules I am using correct? If they are correct, is there something obviously incorrect in my code?
your rules are wrong. conways game of life.
if on then if(neighbors >3||neighbors<2) turn off.
if off then if(neighbors==3) turn on.

Javascript error on iterating through two arrays for hit detection

I'm making a small html5 canvas game in pure JS (with the standards of Ecmascript 6).
So far, everything went well, but now I am stuck on a recurring TypeError (Uncaught TypeError: Cannot read property 'position' of undefined).
This happens every so often, when the game checks for collisions between objects inside two arrays (to be more specific: collision detection between Bullets and Enemies).
Mostly, my collision detection function works fine. When I think I've fixed the issue, it just happens again, after a while.
This is my code:
const collisionCheckBulletEnemy = () => {
for(let i = bullets.length -1; i >= 0; i--){
for(let j = enemies.length -1; j >= 0; j--){
if(collisionCheck(bullets[i], enemies[j], 10, 10)){
bullets.splice(i, 1);
enemies.splice(j, 1);
}
}
}
}
This is the collision detection function:
const collisionCheck = (a, b, marginA, marginB) => {
// margins can be added to make things a little easier/harder on the user
if(!marginA){
marginA = 0;
}
if(!marginB){
marginB = 0;
}
return !(
a.position.x - marginA > b.position.x + b.width + marginB ||
a.position.x + a.width + marginA < b.position.x - marginB ||
a.position.y - marginA > b.position.y + b.height + marginB ||
a.position.y + a.height + marginA < b.position.y - marginB
);
}
This is happening because sometimes either the parameter a or b is passed into the function even though it's just an undefined value. Trying to do undefined.position will cause your type error.
The simple, hacky solution is simply putting a condition at the top:
if (!a || !b) {
return 0; // or whatever your default value is supposed to be
};
The real, better solution is figuring out why bullets and enemies contain some undefined values.
After reading your code I think this is the answer:
if this condition passes when i = bullets.length - 1:
if(collisionCheck(bullets[i], enemies[j], 10, 10)) {
bullets.splice(i, 1);
enemies.splice(j, 1);
}
specifically this part bullets.splice(i, 1); you shorten your array by 1, but you never decrement i.
So if bullets[i] was the very last element in your array now bullets[i] is undefined because javascript doesn't throw an error like indexOutOfBounds.
Now you begin to see that the huge flaw in your code is that it doesn't stop looping when a bullet is removed from the array, and that you only noticed when it was the very last index. Even if it isn't the very last index, it will continue to loop for another bullet which doesn't seem like your intention.
Instead you should break out of the loop since if are destroying your bullet when it hits, you shouldn't keep checking collisions for that same bullet:
if(collisionCheck(bullets[i], enemies[j], 10, 10)) {
bullets.splice(i, 1);
enemies.splice(j, 1);
break;
}

If function javascript not working

I'm a total javascript noob and I'm just trying to bludgeon my way through this simple project. Whats supposed to happen is the script is only meant to run while y <= 3. Each time that it runs the second IF statement, it's meant to add one to y's count and if it runs the ELIF, it's meant to subtract one from y's count. The goal is so that you can only have 3 "selected" pictures at any one time. My y does definitely change, but the IF (y <= 3) does not seem to stop the program from running. Thanks in advance, Jack
<SCRIPT type="text/javascript">
var y = 4; //this is a counter
function swapRoast() { //This defines the function
var x=document.images; //this automatically creates an array of all the images in the document starting with image0 and assigns them to variable'x'
if (y <= 3); { //this should check that y <= 3 before running
if (x[0].src.match('Roast_Vegetables.png')) //This tests if the source of image0 in the array matches the script
{
x[0].src=('Roast_Vegetables_Selected.png'); //If the source matches, then it is changed
y ++; //should add 1 to the y count
}
else if (x[0].src.match('Roast_Vegetables_Selected.png')) //If the source doesn't match, then it tests a different source
{
x[0].src=('Roast_Vegetables.png'); //If the different source matches, then the script operates in reverse to the original IF
y --; //should subtract 1 from the y count
}
}
}
function swapVege(obj) {
var x=document.images;
if (y <= 3); {
if (x[1].src.match('Vegetables.png'))
{
x[1].src=('Vegetables_Selected.png');
y ++;
document.getElementById("demo").innerHTML = y;
}
else if (x[1].src.match('Vegetables_Selected.png'))
{
x[1].src=('Vegetables.png');
y --;
document.getElementById("demo").innerHTML = y;
}
}
}
The semicolon is unfortunate and terminates the if block immediately. Change (in both places)
if (y <= 3); {
to something like
if (y <= 3) {
if (y <= 3); {
take out the ";" here

Categories

Resources