我有一个网格,网格和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个邻居:
此外,还有一个字段循环播放,如下图所示:
所以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
}
这段代码让我哭泣,但我不知道如何做得更好。
你能告诉我什么?
答案 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坐标的网格高度。