Reputation: 21
So, I'm picking up JavaScript since I just seems to enjoy it. I bought an online course, and now facing a challenge in my code. It's a pretty simple one, so hopefully one of the experts out there can help the poor fella (me).
I have the following code, which to my knowledge, should be proper:
var johnAge = 25;
var markAge = 30;
var steveAge = 40;
var johnHeight = 170;
var markHeight = 175;
var steveHeight = 150;
var John, Mark, Steve;
John = johnHeight + 5 * johnAge;
Mark = markHeight + 5 * markAge;
Steve = steveHeight + 5 * steveAge;
console.log('John: ' + John);
console.log('Mark: ' + Mark);
console.log('Steve: ' + Steve);
if (John > Mark && Steve) {
console.log('John wins!');
} else if (Mark > Steve && John) {
console.log('Mark wins!');
} else if (Steve > John && Mark) {
console.log('Steve wins!');
} else {
console.log("it's a draw.");
}
Here is my problem:
John: 295
Mark: 325
Steve: 350
Steve wins!
Now, this game is about having the one with the highest points to win the game. Steve is obviously the winner based on his score.
The problem is with this part right here:
} else if (Mark > Steve && John) {
console.log('Mark wins!');
} else if (Steve > John && Mark) {
console.log('Steve wins!');
It will show that 'Mark' won the game if and when i make the following changes:
} else if (Mark > John && Steve) {
console.log('Mark wins!');
}
I simply just switched locations between 'John' and 'Steve'. If John comes first, it shows that 'Mark won the game', and if Steve comes firs, it moves on and executes the next 'else if' which is 'Steve won the game'.
What I don't understand is why changing positions between my variables causing such huge difference even though I'm using the logical and &&.
This problem doesn't seem to exist when I use binary and &. Though, as far as I've read about this, binary and isn't preferable in coding and doesn't have much real applications where it can be used.
So if possible, I'd like to fix this my using && instead of relying on &.
I really don't understand the changes and their cause.
Thank you in advance for helping and guiding me.
~Cheers
Upvotes: 2
Views: 61
Reputation: 135227
You can do this, you just have to make an improved >
operator that suits your needs. But please stay tuned until the end of this answer. We'll address some other things that we really need to talk about
const gtAll = (x, y, ...ys) =>
ys.length === 0
? x > y
: x > y && gtAll (x, ...ys)
console.log ('5 is greater than 4, 3, and 2', gtAll (5, 4, 3, 2))
// true
console.log ('5 is greater than 4, 3, and 7', gtAll (5, 4, 3, 7))
// false
In your program you could use it like below.
if (gtAll (John, Mark, Steve))
console.log ("John wins")
else if (gtAll (Mark, Steve, John))
console.log ("Mark wins")
else if (gtAll (Steve, John, Mark))
console.log ("Steven wins")
else
console.log ("draw")
But if we zoom out a little bit, there's a bigger problem to solve with your program. Let's look at some of the things that are sticking out.
Have a bunch of vars named fooColor
, fooSize
, fooAdjective
? You're probably looking for an Object.
var johnAge = 25
var johnHeight = 170
var john = { name: 'John', age: 25, height: 170 }
Assigning multiple vars for values of the same kind ie John
, Mark
, Steve
? You're probably looking for an Array.
var John = { ... }
var Mark = { ... }
var Steve = { ... }
const people =
[ { name: 'John', age: 25, height: 170 }
, { name: 'Mark', age: 30, height: 175 }
, { name: 'Steve', age: 40, height: 150 }
]
Does it feel like you're starting to repeat yourself? Use functions to perform repeated tasks
John = johnHeight + 5 * johnAge;
Mark = markHeight + 5 * markAge;
Steve = steveHeight + 5 * steveHeight;
const score = p =>
p.height + 5 * p.age
console.log (score (people [0])) // John
// 295
console.log (score (people [1])) // Mark
// 325
console.log (score (people [2])) // Steve
// 350
console.log (people.map (score))
// [ 295, 325, 350 ]
Here's a rewrite of your program. Most importantly notice that we didn't even end up using gtAll
as because there's a better way to think about the problem now that our people are represented as objects in an array. And remember to use functions where work is repeated!
const people =
[ { name: 'John', age: 25, height: 170 }
, { name: 'Mark', age: 30, height: 175 }
, { name: 'Steve', age: 40, height: 150 }
]
const score = (p) =>
p.height + 5 * p.age
const determineWinner = (contested, challenger) =>
{
if (score (challenger) > score (contested))
return challenger
else if (score (challenger) === score (contested))
return { ...contested, name: "tie" }
else
return contested
}
const winner =
people.reduce (determineWinner)
console.log ("the winner is", winner)
// the winner is { name: 'Steve', age: 40, height: 150 }
console.log ("the winner is", winner.name)
// the winner is Steve
Critically, notice that we can easily add another person to people
and our program doesn't have to change in order to determine a winner. For example, if we added Charlie
var charlieAge = 60
var charlieHeight = 180
var Charlie = charlieHeight + 5 * charlieAge
Then we would have to go and alter all of the if
statements. You can see how this simply does not scale
if (gtAll (John, Mark, Steve))
if (gtAll (John, Mark, Steve, Charlie))
console.log ("John wins")
else if (gtAll (Mark, Steve, John))
else if (gtAll (Mark, Steve, John, Charlie))
console.log ("Mark wins")
else if (gtAll (Steve, John, Mark))
else if (gtAll (Steve, John, Mark))
console.log ("Steven wins")
else if (gtAll (Charlie, John, Mark, Steve))
console.log ("Charlie wins")
else
console.log ("draw")
Compare that to simply adding Charlie to our people
array
const people =
[ { name: 'John', age: 25, height: 170 }
, { name: 'Mark', age: 30, height: 175 }
, { name: 'Steve', age: 40, height: 150 }
, { name: 'Charlie', age: 60, height: 180 }
]
const winner =
people.reduce (determineWinner)
console.log (winner.name)
// Charlie
References for this answer
Upvotes: 3
Reputation: 115950
You want to use comparisons on both sides of the &&
operator:
if(Mark > Steve && Mark > John)
The &&
operator treats its operands as booleans. The expression if(Mark > Steve && John)
means
if both are true:
Mark
is greater thanSteve
, andJohn
has atrue
value whenJohn
is coerced to a boolean (namely, for a number, whenJohn
is nonzero)
This is obviously not what you wanted to test for.
Upvotes: 0
Reputation: 3824
You need to check the player against both of the others like this:
The way you have it now your if statement is Steve > John(true) && Mark(true)
.
var johnAge = 25;
var markAge = 30;
var steveAge = 40;
var johnHeight = 170;
var markHeight = 175;
var steveHeight = 150;
var John, Mark, Steve;
John = johnHeight + 5 * johnAge;
Mark = markHeight + 5 * markAge;
Steve = steveHeight + 5 * steveAge;
console.log('John: ' + John);
console.log('Mark: ' + Mark);
console.log('Steve: ' + Steve);
if (John > Mark && John > Steve ) {
console.log('John wins!');
} else if (Mark > Steve && Mark > John) {
console.log('Mark wins!');
} else if (Steve > John && Steve > Mark) {
console.log('Steve wins!');
} else {
console.log("it's a draw.");
}
Upvotes: 3