Anmar Jihad
Anmar Jihad

Reputation: 21

JavaScript: Different Results with && and &, with numbers

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

Answers (3)

Mulan
Mulan

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

apsillers
apsillers

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 than Steve, and
  • John has a true value when John is coerced to a boolean (namely, for a number, when John is nonzero)

This is obviously not what you wanted to test for.

Upvotes: 0

Scath
Scath

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

Related Questions