添加单元邻居的最佳方法是什么

时间:2016-05-23 12:33:54

标签: java algorithm

我有一个网格,网格和Cell对象的2维数组。

public class Cell
{
  int x;
  int y;
  ArrayList<Cell> nighbors=new ArrayList<Cell>();

  public void addNeighbor(Cell cell)
  {
    this.neighbors.add(cell);
  }
}

每个小区都有8个邻居:

enter image description here

此外,还有一个字段循环播放,如下图所示:

enter image description here

所以Cell(0,1)的邻居也是单元格(5,0),(5,1),(5,2)。

现在我填写这样的小门:

public void addNeigbors(int x, int y)
{
  Cell curentCell=grid[x][y];
  if(x==0)
  {
    if(y==0)
    {
            curentCell.addNiegbor(this.cells[this.width-1][this.height-1]);
            curentCell.addNiegbor(this.cells[x][this.height-1]);
            curentCell.addNiegbor(this.cells[x+1][this.height-1]);
            curentCell.addNiegbor(this.cells[x+1][y]);
            curentCell.addNiegbor(this.cells[x+1][y+1]);
            curentCell.addNiegbor(this.cells[x][y+1]);
            curentCell.addNiegbor(this.cells[this.width-1][y+1]);
            curentCell.addNiegbor(this.cells[this.width-1][y]);
    }
    else if(y==this.height-1)
    {
       // similar code
    }
    else
    {
      // and so on
    }
  }
  // and so on 
}        

这段代码让我哭泣,但我不知道如何做得更好。

你能告诉我什么?

5 个答案:

答案 0 :(得分:2)

在Cell中存储对每个邻居的引用是一种浪费。 IF信元需要访问它们的邻居,然后在每个信元中引用grid数组,并在必要时让信元动态计算其邻居索引。

您可以添加如下方法:

Cell getNeighbor(int dx, int dy)
{
    int w = grid.length;
    int h = grid[x].length;
    return grid[(x+w+dx)%w][(y+h+dy)%h];
}

如果一个单元格需要遍历所有邻居,你可以这样做:

for (int dy=-1;dy<=1;++dy) {
   for(int dx=-1;dx<=1;++dx) {
       if (dx!=0 || dy!=0) {
           processNeighbor(getNeighbor(dx,dy));
       }
   }
}

答案 1 :(得分:1)

创建一个(静态)数组,该数组具有所有8个邻居的x / y delta,因此您可以循环遍历它,将增量添加到单元格x / y坐标以获取邻居坐标并使用mod -> %处理边界:

public class Cell {
  int x;
  int y;
  private static int delta[][] = {{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1}};

  ArrayList < Cell > neighbors = new ArrayList < Cell > ();

  public void addNeighbors() {
    for (int i = 0; i < delta.length; i++) {
      this.neighbors.add(this.cells
        [Math.floorMod(this.x + delta[i][0], width)]
        [Math.floorMod(this.y + delta[i][1], height)]
      );
    } 
  }
}

答案 2 :(得分:1)

这样的事情:

public void addNeigbors(int x, int y)
{
  Cell curentCell=grid[x][y];
  int xp1 = (x+1)%width;
  int xm1 = (x-1+width)%width;
  int yp1 = (y+1)%height;
  int ym1 = (y-1+height)%height;
  curentCell.addNiegbor(this.cells[xp1][y]);
  curentCell.addNiegbor(this.cells[xp1][yp1]);
  curentCell.addNiegbor(this.cells[xp1][ym1]);
  curentCell.addNiegbor(this.cells[x][yp1]);
  curentCell.addNiegbor(this.cells[x][ym1]);
  curentCell.addNiegbor(this.cells[xm1][y]);
  curentCell.addNiegbor(this.cells[xm1][yp1]);
  curentCell.addNiegbor(this.cells[xm1][ym1]);
}        

答案 3 :(得分:0)

循环x(dx)和y(dy)上的可能变体,避免特殊情况dx = dy = 0并使用mod环绕网格。

public void addNeigbors(int x, int y) {
  for(int dx = -1; dx <= 1; dx++) {
    for(int dy = -1; dy <= 1; dy++) {
      if(dx != 0 || dy != 0) {
        int nx = Math.floorMod(x + dx, this.width);
        int ny = Math.floorMod(y + dy, this.height);
        this.cells[x][y].addNeighbors(this.cells[nx][ny]);
      }
    }
  }
}   

答案 4 :(得分:-1)

您应该使用模运算符。

X坐标的网格宽度和Y坐标的网格高度。