What is wrong with my Factorial Function logic? - javascript

I'm trying to get a factorial number in the JS console in Chrome.
Obviously, there is something wrong with my understanding of the for loop, and I'd like to know what part of it is not logical to me.
Thank you very much for answers <3
var newX
function factorial(x) {
if(x > 0){
for(i = 1;i <= x;i++){
var newX = x * i ;
} return newX;
};
};

Where you said var newX = x * i;, that declares a new variable. Remove var.
x * i will return the square of x because lastly i is x.
function factorial(x) {
var newX = 1;
if(x > 0){
for(var i = 1;i <= x;i++){
newX = newX * i;
}
return newX;
} else {
return 1;
}
};
console.log(factorial(5));
console.log(factorial(4));
console.log(factorial(0));

You have to remove var inside the for loop. Also, you should move the declaration of newX inside the function. And there's some other errors too.
function factorial(x) {
var newX = 1
if(x > 0){
for(i = 1;i <= x;i++){
newX = newX * i ;
}
return newX;
}
}
Also, for completeness, you should return 1 when x is 0 and NaN when x is negative or not an integer.
You could rewrite it as a recursive function:
function factorial(x) {
if(x == 0) return 1;
return x*factorial(x-1);
}
Looks way cleaner.

writing var newX in loop means making new variable every time till loop is executing and another thing is you are multiplying x*i but it should be newX *= i to satisfy the condition of factorial (i.e every time you have to multiply the result with next number ).
var newX=1;
function factorial(x) { if(x > 0){
for(i = 1;i <= x;i++){ newX *= i ;
} return newX; }; };

Related

I am coding gravity but its stuttering

I am making a 2d platformer and am working on gravity and collision but when I actually get the collision working my gravity became very stuttery, is there a way to fix this? here is code:
gravity(){
if(this.y <= 400 - this.scale){
let gc = get(this.x, this.y + 20);
print(gc);
if(gc[0] == 0 && gc[1] == 0 && gc[2] == 255 && gc[3] == 255){
return;
}
else{
this.y += 2;
}
}
}
edit: I have heard this should be working so I will provide more code to see if it helps. here is the function that runs everything:
var groundArray = [];
groundArray[0] = [0];
groundArray[1] = [0];
groundArray[2] = [0];
groundArray[3] = [0];
groundArray[4] = [0];
groundArray[5] = [0];
groundArray[6] = [0];
groundArray[7] = [0];
groundArray[8] = [1];
groundArray[9] = [1, 1];
function setup() {
noStroke();
createCanvas(400, 400);
for(let y = 0; y < groundArray.length; y++){
for(let x = 0; x < groundArray[y].length; x++){
if(groundArray[y][x] != 0){
groundArray[y][x] = new ground(x * 40, y * 40);
}
}
}
}
var play = new player(35, 0, 20);
function draw() {
background(255);
for(let y = 0; y < groundArray.length; y++){
for(let x = 0; x < groundArray[y].length; x++){
if(groundArray[y][x] != 0){
groundArray[y][x].draw();
}
}
}
play.draw();
play.gravity();
}
Normally a function named draw() is called every frame, is that what's happening here? It looks like it. In which case, do you really want to be calling new ground(x * 40, y * 40) every frame, wouldn't this object creation be better placed in setup()?
I suspect it's unnecessary and possibly doing expensive initialization work every frame, but without seeing the full source code one can't be sure.

if condition in javascript using variables

The problem with this code is when I'm executing the if condition. The condition only works if i am using if (pixel.getx() <=100) but does not work for a var x = pixel.getX() & if (x <= 100). Can someone tell me why?
var image = new SimpleImage (200,200);
print (image);
for (var pixel of image.values())
var x = pixel.getX();
var y = pixel.getY()
if (x <= 100 && y <= 100)
{
pixel.setRed(255);
pixel.setBlue(0);
pixel.setGreen(0);
}
else if (x > 100)
{
pixel.setBlue(255);
pixel.setGreen(0);
pixel.setRed(0);
}
print (image);
your for loop is missing {}.
all it does the way you have it in your example is
executing var x = pixel.getX(); as many times as there are image.values()
if you need to repeat a multi line block of code within a for loop it needs to be inside {}
if you are repeating one statement - you don't need {} - that's why it worked when you had if (pixel.getX() <= 100) {...}
Your for loop is missing the braces { } and that's why its not working.
Modified code,
var image = new SimpleImage (200,200);
print (image);
for (var pixel of image.values()) {
var x = pixel.getX();
var y = pixel.getY()
if (x <= 100 && y <= 100) {
pixel.setRed(255);
pixel.setBlue(0);
pixel.setGreen(0);
} else if (x > 100) {
pixel.setBlue(255);
pixel.setGreen(0);
pixel.setRed(0);
}
print (image);
}

When using x as index no. to show array location in a funtion, the array returns undefined

Hi guys so my function is returning undefined when I am using x to represent the index number of an array in the below code, why is this happening?
It would be very much appreciated if somebody could answer my question
Code:
var a = 0;
var b = 0;
var z = 0;
var x = 0;
function findOutlier(integers){
//your code here
while(x < integers.length){
if(integers[x]%2 === 0){
a = x;
z = z + 1;
}
else{
b = x;
}
x = x + 1
}
if(z === 1){return integers[a]}
else{return integers[b]}
}
findOutlier([2,6,8,10,3]);
x <= integers.length The array goes from 0 to length-1, so looping from 0 to length means you are going one off the end of the array.
Replace with while(x < integers.length).

Javascript loop with dynamic start and end variables

This seems pretty basic, but I can't find the best method to do this... I'm trying to set up a function that loops between a user selected start and end variables. This is what I ended up with but I'm sure there is a better way to do it (demo).
Note: the x & y variables are indexed to one, not zero.
getWidths1 = function(x, y) {
var start = (x < y) ? x : y,
end = (x < y) ? y : x,
total = 0;
for (; start < end; start++) {
total += values[start - 1] || 0;
}
return total;
};
I tried this function, but the results are one result off when y > x:
getWidths2 = function(x, y) {
var total = 0,
diff = (x < y) ? 1 : -1;
while (x !== y) {
total += values[x - 1] || 0;
x += diff;
}
return w;
};
So, is the first function the best, or does someone have a better method?
The first isn't bad. I think this is slightly more traditional:
for (var i = start; i < end; i++){
}
Only real difference is that it doesn't affect start and end.
I'd make a few changes:
Use Math.min and Math.max - much more readable.
Don't subtract one from start if the first value you want is values[start].
var getWidths1 = function(x, y) {
var start = Math.min(x,y), end = Math.max(x,y);
var total = 0;
for (; start < end; start++) {
total += values[start] || 0;
}
return(total);
}
I agree with #kingjiv with the added caveat that if you want to include the item at y then you need:
for (var i = start; i <= end; i++){
...
}
As it is your code (both versions) will total the values from x inclusive to y exclusive.

Colliding Shapes and making them bounce away from one another

I was starting to teach myself how to work with HTML5 Canvas and decided to learn by making a short game/demo.
I wanted to make a simple blocks bounce around the screen, bounce off the walls, and bounce off each other.
I'm stuck on getting them to bounce off each other. It seems like code that makes it bounce away is making it bounce back immediately after. I see where the code fails but I don't know how to fix it :( Can anyone help?
(Side question: I know I'm not working as clean/efficiently/professionally as possible in this example but if I wanted to improve with feedback and opinions about the 'best' method for this type of example, like a code review or something, is it ok to ask a question on stackoverflow?)
jsfiddle:
http://jsfiddle.net/vdcSv/
HTML:
<canvas id="canvas" Width="400" Height="300"></canvas>
Javscript:
function CheckBallCollision(BallsArray, index) {
for (var i = 0; i < BallsArray.length; i++) {
if (index != i) {
if (BallsArray[index].Xdir == 1) {
if ((BallsArray[index].Xmax >= BallsArray[i].Xmin)) {
if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
BallsArray[index].Xdir = -BallsArray[index].Xdir;
}
}
} else if (BallsArray[index].Xdir == -1) {
if ((BallsArray[index].Xmin <= BallsArray[i].Xmax)) {
if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
BallsArray[index].Xdir = -BallsArray[index].Xdir;
}
}
}
}
}
}
Ball Object:
function Ball() {
this.Xmin = 0;//top left X coord
this.Ymin = 0;//top left y coord
this.Height = 25;
this.Width = 25;
this.Xmax = this.Xmin + this.Width;
this.Ymax = this.Ymin + this.Height;
this.Xdir = 0; // 0 not moving, 1 moving right, -1 moving left
this.Ydir = 0;
this.Red = 0;
this.Green = 0;
this.Blue = 200;
this.Opacity = 1;
this.Speed = 1;
}
Got it working by changing the <= to ==
It's messy and things often miss the necessary bounce off a block :( I'm sure part of the reason is falling back on the == instead of <=. If anyone has a better solution - I'm all ears :)
http://jsfiddle.net/vdcSv/1/
function CheckBallCollision(BallsArray, index) {
for (var i = 0; i < BallsArray.length; i++) {
if (index != i) {
if (BallsArray[index].Xdir == 1) {
if ((BallsArray[index].Xmax == BallsArray[i].Xmin)) {
if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
BallsArray[index].Xdir = -BallsArray[index].Xdir;
}
}
} else if (BallsArray[index].Xdir == -1) {
if ((BallsArray[index].Xmin == BallsArray[i].Xmax)) {
if ((BallsArray[index].Ymin <= BallsArray[i].Ymin) && (BallsArray[index].Ymax >= BallsArray[i].Ymin) ||
((BallsArray[index].Ymax >= BallsArray[i].Ymax) && (BallsArray[index].Ymin <= BallsArray[i].Ymax))) {
BallsArray[index].Xdir = -BallsArray[index].Xdir;
}
}
}
}
}
}
Here are a couple hit detection snippets you might want to look into:
ball.hitTestCircle = function(obj) {
var dx = this.x - obj.x;
var dy = this.y - obj.y;
var distance = (dx * dx) + (dy * dy);
var area = (this.radius + obj.radius)*(this.radius + obj.radius);
return (area / distance);
};
if the call returns 1 or greater your colliding, and you can even use that info to fix the difference.
Here is basic rect hit detections script:
ball.hitTestRect = function(b) {
var difference = {};
difference.x = this.x - b.x - b.width;
difference.y = this.y - b.y - b.height;
difference.height = this.height + b.height;
difference.width = this.width + b.width;
if (difference.x < 0 && difference.y <= 0 && difference.height + difference.y >= 0 && difference.width + difference.x >= 0) return true;
return false;
};
I would call either of these with something like :
for(var i=0;i!=balls.length;i++){
for(var j=0;j!=balls.length;j++){
if(j!=i){
if(balls[i].hitTestRect(balls[j])){
// all your reversing motion code
}
}
}
}
It looks like you forgot to check if
BallsArray[index].Xmin <= BallsArray[i].Xmax)
If you add this in it works. It's also worth noting that you don't need different code for the two different X directions as this behaviour is symmetrical. Regardless of which way it is travelling to begin with you have it reversing direction. It's also symmetrical in the Y direction so if you just add:
BallsArray[index].Ydir = -BallsArray[index].Ydir;
to the 'then' part of the if you'll only need one if to take care of all four kinds of collisions.
You may also want to add a break statement so that if a ball happens to collide with two other balls at the same time it will only reverse direction once.
For a more realistic simulation you can multiply by a negative number in the (0, 1) interval, however if you don't do something else your system will slowly settle into a steady state until the rounding errors kick in and it freaks out.

Categories

Resources