0

var enemies = [
 {
  nick: "Bob1",
  x: 12,
  y: 21
 },
 {
  nick: "Bob2",
  x: 20,
  y: 21
 },
 {
  nick: "Bob3",
  x: 12,
  y: 21
 }
]
var me = {
 x: 19,
 y: 20
}

for (var x in enemies) {
   var enemy = enemies[x];
   if ((Math.abs(me.x - enemy.x) <= 1 && Math.abs(me.y - enemy.y) <= 1)) { 
      console.log("Enemy In range");
   } else {
      console.log("Enemies not in range");
   }
}

Hello everyone. I have an array of enemies, and i am checking if some enemy is 1 field away from my x or y position. And i want to log only once if it is or it's not. As you can see now, it check for every enemy and it logs for every enemy. Which is is not what i want. I just want to simply check if there is any enemy 1 field away of my x or y position or not, and get simple response yes, or no. Im totally newbie, but if you have any hint for me, that would be awesome!

Suttero
  • 91
  • 7

5 Answers5

4

Have a boolean such as found that starts off as false. When you find it, set it to true and break. Then after the loop have if (found) ... else .... This moves the printing out of the loop, ensuring you only get it once.

Furthermore, you can compress this a lot by using the new some method, which internally does basically the same thing (just faster):

let found = enemies.some(enemy => enemyIsClose(enemy, me));

If you actually need to find which enemy is close, find instead of some will return the first one, and filter will return all of them.

Amadan
  • 191,408
  • 23
  • 240
  • 301
2

You can use Array#find instead to early return from the loop if a matching element is found.

var enemies = [{
    nick: "Bob1",
    x: 12,
    y: 21
  },
  {
    nick: "Bob2",
    x: 20,
    y: 21
  },
  {
    nick: "Bob3",
    x: 12,
    y: 21
  }
]

var me = {
  x: 19,
  y: 20
}

var enemy = enemies.find(enemy => (Math.abs(me.x - enemy.x) <= 1 && Math.abs(me.y - enemy.y) <= 1));

if (typeof enemy !== undefined) {
  console.log("Enemy In range");
} else {
  console.log("Enemies not in range");
}
31piy
  • 23,323
  • 6
  • 47
  • 67
1

In order for your code to check if an enemy is nearby, it would need to iterate through all of their positions, there's no way around this but if you only want to reduce the amount of console logs you can use this code:

var isEnemyFound = true;
for (let x of enemies) {
   var enemy = enemies[x];
   if ((Math.abs(me.x - enemy.x) <= 1 && Math.abs(me.y - enemy.y) <= 1)) { 
      console.log("Enemy In range");
      break;
   } else {
      isEnemyFound = false;
   }
}

if(!isEnemyFound){
console.log("Enemies not in range");
}
Raphael Estrada
  • 1,109
  • 11
  • 18
1

You can simply filter the object using Array.filter and find your collection.

var enemies = [
 {
  nick: "Bob1",
  x: 12,
  y: 21
 },
 {
  nick: "Bob2",
  x: 20,
  y: 21
 },
 {
  nick: "Bob3",
  x: 12,
  y: 21
 }
]
var me = {
 x: 19,
 y: 20
}
var enemy=enemies.filter(item=>{
  return me.x-item.x<=1
})[0];
console.log(enemy);
ferhado
  • 2,363
  • 2
  • 12
  • 35
1

Here is a better soultion, overall. The previous one I did on the fly. Try playing around with it and see if this is what you need. I truly hope it is :)

If you change your (me - values) to '13' it's still going to be the same result, but try changing it to '14' for example, and see the how the logic plays out. This is a overkill, but if you want to advance your game, it's a great solution, because you can create as many variations and possibilities as you want, on the fly, just calling next(); in order to create the next value. Just a suggestion. Good luck!

let enemies = [
 {nick: "Bob1", x: 12, y: 21},
 {nick: "Bob2", x: 12, y: 21},
 {nick: "Bob3", x: 12, y: 21}
  ];

let me = {
 x: 12,
 y: 21
}

function* range() {

for (let x in enemies) {
   let enemy = enemies[x];

while(Math.abs(me.x - enemy.x) <=1 && Math.abs(me.y - enemy.y) <= 1) {
    yield "Enemy is in range";
    break; // closes iterator, triggers return
  }  
    yield "Enemy is NOT in range";
    break;
  }
}

var gen = range(); // Creating a generator

console.log(gen.next().value); // Then we use it to get the next value
Dženis H.
  • 7,284
  • 3
  • 25
  • 44