简体   繁体   English

如何在二维阵列所代表的板上循环通过一个单元的所有邻居?

[英]How to loop through all neighbors of a cell in a board represented by 2-dimensional array?

Building Game of Life here and working on a function to loop through all the neighbors of a cell and sum up the scores (each cell is 0 or 1). 在此处构建生活游戏,并研究一个功能,以遍历一个单元的所有邻居并汇总分数(每个单元为0或1)。 Board is represented by a 2-dimensional array. 木板由二维数组表示。 Normally a cell has 8 neighbours. 通常一个小区有8个邻居。 The problem is that cells in the corner of the board have only 3 neighbors and cells on the side have 5. If I loop through the array using the code below, some neighbors return undefined in the array. 问题在于,板角落的单元只有3个邻居,而侧面的单元只有5个邻居。如果我使用下面的代码遍历该数组,则某些邻居会在该数组中返回undefined。 I want to convert undefined to 0 and use that to sum up the scores, but i get the error: 我想将undefined转换为0并用它来汇总分数,但是我得到了错误:

Uncaught TypeError: Cannot read property '-1' of undefined 未捕获的TypeError:无法读取未定义的属性“ -1”

Thanks for your help! 谢谢你的帮助!

var array = [
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1],
    [0,0,1,0,1,0,1,0,1,1]
]

for(var i=0; i < array.length; i++){
    for(var j=0; j < array[i].length; j++){

    var totalScore = 0;        
    var scores = [
        //i = row in loop
        //j = column nested loop  
        array[i-1][j-1],
        //upper left corner
        array[i-1][j],
        //top side
        array[i-1][j+1],
        //upper right corner
        array[i][j-1],
        //left side
        array[i][j+1],
        //right side
        array[i+1][j-1],
        //bottom left corner
        array[i+1][j],
        //bottom side
        array[i+1][j+1]
        //bottom right corner
        ];

        scores.forEach(function(item){

              var score = item;
              if(score === "undefined"){

                score = 0;

              }

              totalScore += score;

            })

            console.log(totalScore);    

    }

}

Just a lot of bounds checking: 只是很多范围检查:

var scores = [
  i > 0 && j > 0 ? array[i-1][j-1] : 0,
  i > 0 ? array[i-1][j] : 0,
  i > 0 && j < array[i].length-1 ? array[i-1][j+1] : 0,
  j > 0 ? array[i][j-1] : 0,
  j < array[i].length-1 ? array[i][j+1] : 0,
  i < array.length-1 && j > 0 ? array[i+1][j-1] : 0,
  i < array.length-1 ? array[i+1][j] : 0,
  i < array.length-1 && j < array[i].legnth-1 ? array[i+1][j+1] : 0
];

You could also create a function to act as an intermediary and access the array through that: 您还可以创建一个充当中介的函数,并通过该函数访问数组:

function getCell(x,y) {
  if(y < 0 || y >= array.length || x < 0 || x >= array[0].length) {
    return 0;
  }
  return array[y][x];
}

@Matt Timmermans proposition solves a lot of problems. @Matt Timmermans的命题解决了很多问题。 If you want to keep existing structure, consider next approach: 如果要保留现有结构,请考虑以下方法:

Form code describing cell position in the matrix (I assume boolean is evaluated as 0/1): 描述矩阵中单元格位置的形式代码(我假设布尔值的计算值为0/1):

dxdy_code = (y==0) + (x==0)<<1 + (y==height-1)<<2 + (x==width-1)<<3;

Build array containing all possible combinations (size 16, binary 0b0000..0b1111 ) of neighbour shifts: 构建数组,其中包含邻居移位的所有可能组合(大小16,二进制0b0000..0b1111 ):

var dxdy = [
[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]],  //all
[[0,-1],[0,1],[1,-1],[1,0],[1,1]],  //y=0
[[-1,0],[-1,1],[0,1],[1,0],[1,1]],  //x=0
[[0,1],[1,0],[1,1]],  //y=0,x=0
[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1]],  //y=max
[[0,-1],[0,1]],  //one row
[[-1,0],[-1,1],[0,1]],  //y=max,x=0
..
[]  //one row, one column 
]

For every cell calculate code and use corresponding array of shifts 为每个单元格计算代码并使用相应的班次数组

for(var i=0; i < array.length; i++){
    for(var j=0; j < array[i].length; j++){
    var totalScore = 0;
    code =  dxdy_code(i, j);
    sh = dxdy[code];
    for (var k=0; k < sh.length; k++){
        totalscore += array[i+sh[k][0]][j+sh[k][1]];
    }

Thanks everyone. 感谢大家。 With your help I solved it as below: 在您的帮助下,我解决了以下问题:

var array = [

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1],

  [0, 0, 1, 0, 1, 0, 1, 0, 1, 1]

]

for (var i = 0; i < array.length; i++) {

  for (var j = 0; j < array[i].length; j++) {

    var scores = [
      i > 0 && j > 0 ? array[i - 1][j - 1] : 0,
      i > 0 ? array[i - 1][j] : 0,
      i > 0 && j < array[i].length - 1 ? array[i - 1][j + 1] : 0,
      j > 0 ? array[i][j - 1] : 0,
      j < array[i].length - 1 ? array[i][j + 1] : 0,
      i < array.length - 1 && j > 0 ? array[i + 1][j - 1] : 0,
      i < array.length - 1 ? array[i + 1][j] : 0,
      i < array.length - 1 && j < array[i].length - 1 ? array[i + 1][j + 1] : 0
    ]

    var totalScore = scores.reduce(function(total, currentValue) {

      return total += currentValue;

    })

    console.log(totalScore);

  }

}

Will try the other suggestions when refactoring my code! 重构我的代码时,将尝试其他建议!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM