0

I have a 2D array, which contains either true or false. I made a function that returns the number of neighbors (in all 8 directions) in that array, which are true. But for some unknown reason, it does not work corectly (returns wrong number of neighbors). (Yes, I'm making Conway's Game of Life.)

function neighbors(seq, x, y) {
   var cnt = 0;
   try {
    if (seq[y-1][x]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y][x-1]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y][x+1]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y+1][x]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y-1][x+1]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y-1][x-1]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y+1][x-1]){
        cnt++;
    }
   }
   catch(err) {

   }
   try {
    if (seq[y+1][x+1]){
        cnt++;
    }
   }
   catch(err) {

   }        
   return cnt;
}

This code was basically translated from my Python code, that works.

8
  • what is the value of seq? What does "does not work" mean? Commented Jun 4, 2018 at 11:01
  • 2
    Please avoid all this try..catch Commented Jun 4, 2018 at 11:02
  • @Michael What if i get out of index? Commented Jun 4, 2018 at 11:02
  • 1
    Replace try...catch with normal execution flow seq[y-1] && seq[y-1][x+1]. Js doesn't throw when array index is out of bound. Commented Jun 4, 2018 at 11:03
  • 1
    Which one is the ninth direction? Commented Jun 4, 2018 at 11:09

2 Answers 2

4

You could take an object with all needed directions for counting.

Then check if the index is a key of the array and check the nested level. Add all and return that value.

function neighbors(seq, i, j) {
    var directions = [{ x: 0, y: -1 }, { x: -1, y: -1 }, { x: -1, y: 0 }, { x: -1, y: 1 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: 0 }, { x: 1, y: -1 }];

    return directions.reduce((r, { x, y }) => {
            x += i;
            y += j;
            return r + (x in seq && seq[x][y] || 0);
        }, 0);
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can simplify function like below.

var seq = [[false,false,false,false],
           [false,true,false,false],
           [false,true,false,false],
           [false,true,false,false]]
function neighbors(seq, x, y) {
   var cnt = 0;
   var controls = [{x:0,y:1},{x:0,y:-1},
                    {x:1,y:0},{x:1,y:1},{x:1,y:-1},
                    {x:-1,y:0},{x:-1,y:1},{x:-1,y:-1}]
   for (var index in controls) {
      var newX = x+controls[index].x;
      var newY = y+controls[index].y;
      if(newX >= 0 && newY >= 0 && newX < seq.length && newY < seq[newX].length
        && seq[newX][newY]) {
        cnt++;
      }
   }       
   return cnt;
}

console.log(neighbors(seq, 0,1))
console.log(neighbors(seq, 1,0))
console.log(neighbors(seq, 2,2))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.