Javascript conditional statement not executing - javascript

I'm attempting to make a function that builds a checker board however I can't get my second conditional statement to execute and create a new line.
function grid(size) {
var board = "";
for (i = 0; i <= (size * size); i++) {
if (i % 2 === 0) {
board += ' ';
} else if (i % size === 0) {
board += "\n";
} else {
board += '#';
}
}
console.log(board);
}
grid(8);
It appears the else if statement is not executing because I've tried changing the '\n' and condition to other things but nothing is printed. This question is from Eloquent Javascript and the given solution is this:
var size = 8;
var board = "";
for (var y = 0; y < size; y++) {
for (var x = 0; x < size; x++) {
if ((x + y) % 2 == 0)
board += " ";
else
board += "#";
}
board += "\n";
}
console.log(board);
I'm not sure why the second one works but mine doesn't.

Let´s analyse your code:
if(i % size === 0)
This means, when i is equal to 0 or is a multiple of size. In your case, size is 8.
So for your if to trigger, i should be 0,8,16,32....
In all this cases, it will never fire because when i is 0,8,16,32... i % 2 is 0, so it will run the first if instead and never the second one. You should inverse the order of the ifs or run both

i % 2 will always execute instead of i % (8 * 8). You should swap their order or remove the else from the second if.

Related

How to stop falling objects from appearing in mid-air on HTML5 canvas

[ETA] for better clarification:
I'm currently learning to code a HTML canvas game (items catching and dodging) using Javascript for a class project and I'm having problem with getting the objects falling down from top of the canvas.
The problem I'm having currently is occasionally (one might need to reload the game several times to notice this phenomenon) an object 'jumps' out of a random point inside the canvas where it should be thrown back up to the negative y coordinate area (aka. out of sight) and fall down again from there after collision detection.
So for example, when a giftbox is caught or disappears off the bottom edge, it should be thrown back up to the top of the canvas. However, sometimes it pops out of a random point in the middle, or near the bottom edge of the canvas instead, which is not at all what I intended.
I figure there must be a logical error with the code I write, but I have been trying several fixes and looking up answers for the past few days without any success.
I guess the problem must lie in the part of the code where I do collision detection:
function fallAgain() {
for (i = 0; i < 3; i++) {
let r = Math.floor(Math.random() * objectArray.length);
if (objectArray[i].y > canvas.height) {
[objectArray[i], objectArray[r]] = [objectArray[r], objectArray[i]];
objectArray[r].y = randomY();
objectArray[r].x = randomX();
// this loop is to check if two randomly generated items overlap
for (let idx = 1; idx < 3; idx++) {
if (Math.abs(objectArray[idx].x - objectArray[idx-1].x) <= 10
&& Math.abs(objectArray[idx].y - objectArray[idx-1].y) <=10) {
objectArray[idx].y += 30;
objectArray[idx].x += 20;
}
}
if (objectArray[r].status == 1
|| objectArray[r].status == 3
|| objectArray[r].status == 4) {
lives--;
}
}
}
}
function hitOrMissed() {
for (i = 0; i < 3; i++) {
let r = Math.floor(Math.random() * objectArray.length);
if (objectArray[i].x + objectArray[i].w > kid.x + 3
&& objectArray[i].x + 3 < kid.x + kid.w
&& objectArray[i].y + objectArray[i].h > kid.y
&& objectArray[i].y < kid.y + kid.h - 3) {
[objectArray[i], objectArray[r]] = [objectArray[r], objectArray[i]];
objectArray[r].y = randomY();
objectArray[r].x = randomX();
for (let idx = 1; idx < 3; idx++) {
if (Math.abs(objectArray[idx].x - objectArray[idx-1].x) <= 10
&& Math.abs(objectArray[idx].y - objectArray[idx-1].y) <=10) {
objectArray[idx].y += 30;
objectArray[idx].x += 20;
}
}
if (objectArray[r].status == 1) {
score++;
} else if (objectArray[r].status == 0) {
lives--;
} else if (objectArray[r].status == 4) {
if (lives < 2) {
lives++;
} else {
lives += 0;
score += 2;
}
} else if (objectArray[r].status == 3) {
score += 5;
}
}
}
}
So far I've tried merging the fallAgain and hitOrMissed functions, but the problem persists
And here's my Codepen with the full code:
Codepen demo
If someone could please help me identify where I've made it wrong and a pointer or guideline as to what I should do to fix the problem I'd really appreciate it. I'm not sure if this piece of information is of any help, but I'm just a beginner at Javascript with no prior coding experience and I've only learned the basics (I haven't touched constructor and Object-oriented Programming yet).
Thank you so much in advance for your help!

Assign array element to a variable, then modify array element by modify variable but don't work

So I want to do expression on variable instead of directly array element because I think
The compiler will re-calculate to find the array element
Naming variable is easy to understand than arr[idx]
But when I attempt to swap 2 element in the array using variable, it don't work (see the code below).
I can't think of the keyword to this situation. Google results are all deep/shallow copy array.
Any explanation?
for (let i = 0, j = 1; i < numsClone.length && j < numsClone.length;) {
let numHasEvenIdx = numsClone[i];
let numHasOddIdx = numsClone[j];
if (numHasEvenIdx % 2 === 1 && numHasOddIdx % 2 === 0) {
[numsClone[i], numsClone[j]] = [numsClone[j], numsClone[i]];
// I want this to be [numHasEvenIdx, numHasOddIdx] = [numHasOddIdx, numHasEvenIdx]
i += 2;
j += 2;
}
else if (numHasEvenIdx % 2 === 0) i += 2;
else j += 2; //(numHasOddIdx % 2 === 1)
}

vertical output and horizontal output to console.log

I'm new to programming and am curious so I thought I'd reach out.
I have tested myself with 2 outputs to the console, one being FizzBuzz and the other being a chessboard.
My question is why does my chessboard naturally (without "\n") print horizontally and FizzBuzz print out vertically even though they both use the same for loops?
Thanks, Luke.
FizzBuzz,
for(let i= 1; i<= 100; i++){
let message= "";
if(i %3 === 0 && i%5 === 0){
message= "FizzBuzz"
}else if(i % 3 === 0){
message = "Fizz";
}else if(i % 5 === 0){
message = "Buzz"
}
console.log(message || i);
};
Chessboard
let size= 8;
let board= '';
for (let x = 0; x < size; x++){
for (let y= 0; y < size; y++){
if((x+y) %2 == 0){
board += '#';
}else{
board += " ";
}
}
board += "\n"
}
console.log(board);
I think I have the answer.
(A) The code,
console.log("Fizz");
console.log("Buzz");
gives output
"Fizz"
"Buzz"
(B) But,
console.log("Fizz " + "Buzz");
gives output
"Fizz Buzz"
What you are doing with the FizzBuzz is similar to case (A) and in chessboard is similar to case (B). You are logging in every iteration of the for loop in case (A), but only once for every row in case (B).
Since you are new to programming, remember that each console.log("whatever"); logs "whatever" in a new line every time it is run.

Is it possible to run a loop in segments? - JavaScript

Since I am still fairly new to js I thought it couldn't hurt to ask more experienced coders about ways to improve my coding habits and to learn efficient basics.
So im wondering if I could run, say 2 lines of code in a loop x amount of times and then x amount of times on the rest of the block.
So instead of this:
for (let i = 0; i <= 10; i++) {
this.shapes[i].x -= 1;
this.shapes[i].draw(this.ctx);
}
for (let i = 0; i <= 10; i++) {
this.shapes[i].x += 1;
this.shapes[i].draw(this.ctx);
}
Does something like this exist?
for (let i = 0; i <= 10; i++) {
//run this section i amount of times
this.shapes[i].x -= 1;
this.shapes[i].draw(this.ctx);
//then run this i amount of times
this.shapes[i].x += 1;
this.shapes[i].draw(this.ctx);
}
The only difference between the two loops' bodies seems to be one statement.
You can use some math to determine the index and some logical statements to determine if that value should be incremented or decremented, here is an example:
for (let i = 0; i <= 21; i++) {
const index = i % 11;
this.shapes[index].x += (i > 10) ? 1 : -1;
this.shapes[index].draw(this.ctx);
}
If it's exactly the same code you can refactor it like this:
for (let delta of [-1, +1]) {
for (let i = 0; i <= 10; i++) {
this.shapes[i].x += delta;
this.shapes[i].draw(this.ctx);
}
}
Another option is to use a function using delta as a parameter
changeShapeByDelta = (delta) => {
for (let i = 0; i <= 10; i++) {
this.shapes[i].x += delta;
this.shapes[i].draw(this.ctx);
}
}
changeShapeByDelta(-1);
changeShapeByDelta(+1);
Another option is to deep copy your initial shapes and restore it after the first draw.
You could ofc. define more variables then i:
for (let i = 0, j=0; i <= 10; i++, j+= 2) {
console.log(i, j);
}
Or use another var in the parent scope:
let j = 0;
for (let i = 0, j=0; i <= 10; i++, j+= 2) {
j += 2
console.log(i, j);
}
Or just use plain old if,else and break statements. Code does not have to look nice all the time.
You can loop 20 times instead of 10 times and then run first code if i<10 else run second. Below is example with simple logging.
for(let i = 0;i<22;i++){
if(i<11) console.log('first')
else console.log('second')
}

How can I optimize (or improve) this Fizz Buzz script?

//Script to find numbers that are the power of 3 and 5 from 1 to 100 using % Modulus operator - when it finds a number that can be the power of 3 or 5 it outupts FizzBuzz... example hosted on my blog http://chadcollins.com/find-numbers-that-are-the-power-of-3-and-5-from-1-to-100/
// this was an interview question, and I want to know how to optimize or improve this with "pure javascript".
<div id=out_put></div>
//from a list of 1 to 100 numbers, find the 3's and 5's using modulus
function findPowerOf(numList) {
//setup the variables
var myModMatch1 = 3; //find numbers that have the power of 3
var myModMatch2 = 5; //find numbers that have the power of 5
var tempCheck1 = ""; //stores true or false based on myModMatch1
var tempCheck2 = ""; //stores true or false based on myModMatch2
var stringOut = ""; //concat string for output
var numListStart = 1; //starting number list index
var numListFinish = 100; //ending list index
var numberList = []; //create the list of numbers
for (var i = numListStart; i <= numListFinish; i++) {
numberList.push(i);
}
for (i = 0; i < numberList.length; i++) { //loop on each number and check the modulus params
console.log(numberList[i]);
if ((numberList[i] % myModMatch1) === 0) { //check first modulus param
console.log('houston, we have a match on a number modulus 3');
tempCheck1 = "Fizz";
}
if ((numberList[i] % myModMatch2) === 0) {
console.log('houston, we have a match on a number modulus 5');
tempCheck2 = "Buzz";
}
if (tempCheck1 === "" && tempCheck2 === "") { //no modulus matches
console.log("no modulus matches");
stringOut += numberList[i] + "\n";
}
stringOut += tempCheck1 + tempCheck2 + "\n";
tempCheck1 = ""; //clear both variables
tempCheck2 = "";
}
//dynamically make a div
var outDiv = document.createElement("div");
outDiv.innerHTML = stringOut; //output the final loop values all at once
document.getElementById('out_put').appendChild(outDiv); //update the view
}
findPowerOf(); // call our function
You can remove pretty much all the variables and the function parameter (especially since you're not using the parameter at all). That will also remove one redundant loop.
You can optimize those three parallel ifs by doing one nested if-else.
With all that, you could reduce the code to about 30% of its current size.
Let me give it a shot:
My optimized version:
var div = document.getElementById('out_put');
for (var i = 1; i <= 100; i++) {
if (i % 3 == 0 || i % 5 == 0) {
if (i % 3 == 0) {
div.innerHTML += "Fizz";
}
if (i % 5 == 0) {
div.innerHTML += "Buzz";
}
} else {
div.innerHTML += i;
}
div.innerHTML += '<br>';
}
<div id=out_put></div>
I've used one variable for the div element because selecting it on every iteration is a waste of resources.
Shorter/less readable version:
Here's an even shorter, commented and slighly less-readable version:
var div = document.getElementById('out_put');
for (var i = 1; i <= 100; i++) {
if (i % 3 == 0 || i % 5 == 0) { // see if there's ANY match
if (i % 3 == 0) // check for 3
div.innerHTML += "Fizz";
if (i % 5 == 0) // check for 5
div.innerHTML += "Buzz";
} else // otherwise just output the number
div.innerHTML += i;
div.innerHTML += '<br>'; // add a new line after each
}
<div id=out_put></div>
Insane version - one-liner:
(just for fun - don't ever do this!)
And if you really REALLY want to go crazy with this, you can do a few nested ternary conditionals inside the loop. Technically, a loop with a single line inside - but pretty much unreadable and will perform worse because I removed the DOM element reference variable, so it will do the element query on every iteration. :)
for (var i = 1; i <= 100; i++)
document.getElementById('out_put').innerHTML += ( (i % 3 == 0 || i % 5 == 0) ? ( ((i % 3 == 0) ? "Fizz" : "") + ((i % 5 == 0) ? "Buzz" : "") ) : i) + '<br>';
<div id=out_put></div>

Categories

Resources