【问题标题】:How to loop through all neighbors of a cell in a board represented by 2-dimensional array?如何遍历二维数组表示的棋盘中单元格的所有邻居?
【发布时间】:2016-12-23 04:12:32
【问题描述】:

在这里构建生命游戏,并使用一个函数循环遍历一个单元格的所有邻居并对分数求和(每个单元格为 0 或 1)。板由二维数组表示。通常一个小区有8个邻居。问题是板角的单元格只有 3 个邻居,而侧面的单元格有 5 个。如果我使用下面的代码循环遍历数组,一些邻居在数组中返回未定义。我想将 undefined 转换为 0 并用它来总结分数,但我得到了错误:

未捕获的类型错误:无法读取未定义的属性“-1”

感谢您的帮助!

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

    }

}

【问题讨论】:

  • array[i-1][j-1] 将在数组中查找第一次迭代中不存在的-1 索引。
  • array[i+1][j+1] 将寻找 10th index,这在上次迭代中也不存在。
  • 谢谢,但是当元素不存在时如何设置分数为0?
  • element doesn't exist 是什么意思?
  • 用 2 个额外的行和列创建数组,然后只使用不在边缘的数组。

标签: javascript arrays algorithm loops conways-game-of-life


【解决方案1】:

只是很多边界检查:

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
];

您还可以创建一个函数作为中介并通过它访问数组:

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

【讨论】:

    【解决方案2】:

    @Matt Timmermans 的提议解决了很多问题。如果您想保留现有结构,请考虑下一种方法:

    描述矩阵中单元格位置的表单代码(我假设布尔值被评估为 0/1):

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

    构建包含所有可能组合(大小为 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(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]];
        }
    

    【讨论】:

      【解决方案3】:

      谢谢大家。在您的帮助下,我解决了如下问题:

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

      在重构我的代码时会尝试其他建议!

      【讨论】:

        猜你喜欢
        • 2021-04-23
        • 1970-01-01
        • 2018-07-03
        • 2014-11-29
        • 2019-03-18
        • 1970-01-01
        • 2021-05-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多