markop
markop

Reputation: 75

Javascript 2D array function

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.

Upvotes: 0

Views: 72

Answers (2)

ymutlu
ymutlu

Reputation: 6715

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))

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386680

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);
}

Upvotes: 4

Related Questions