Часто (если не всегда) приходится жертвовать скоростью или памятью; Некоторое время назад мне пришлось реализовать решатель судоку на Java, и было быстрее назначить каждой ячейке список групп ячеек. Поэтому вместо того, чтобы каждый раз проверять границы, мне просто приходилось выполнять итерации по каждой группе, а затем по каждой ячейке в каждой группе. Проверка была сделана один раз для создания групп.
Что-то вроде:
class Neighbors {
ArrayList<Point> pList = new ArrayList<Point>();
}
...
int[][] grid = new int[10][10];
Neighbors[][] n = new Neighbors[10][10];
for (int x=0; x<10; x++) {
for (int y=0; y<10; y++) {
grid[x][y] = (y*10)+x; // 0..99
n[x][y] = new Neighbors();
for (int nx=x-1; nx<=x+1; nx++) {
for (int ny=y-1; ny<=y+1; ny++) {
if (!(x==nx && y==ny) && nx>=0 && ny>=0 && nx<10 && ny<10) {
n[x][y].pList.add(new Point(nx,ny)); // add valid neighbor
}
}
}
}
}
тогда для любой заданной точки: х, у
for (Point p : n[x][y].pList) {
// grid[p.x][p.y] is a neighbor of grid[x][y]
}
Ну, мое решение было немного более сложным, но принцип тот же. Если ваша сетка представляет собой двумерный массив объектов, соседями на самом деле могут быть объекты в grid[nx][ny]
вместо точек для прямого доступа к объектам.
В конечном итоге вам нужно будет проверить x>=0
, y>=0
, x<SIZE_W
и y<SIZE_H
, но это решение выполняет проверку только один раз, поэтому, на мой взгляд, оно весьма эффективно, когда часто запрашивает соседей для каждого ячейка сетки. Если вам нужно часто менять размер сетки, то это решение нужно будет адаптировать.
Другим подходом будет заполнение массива в каждом направлении значением флага ignored
(например, ноль, -1 и т. Д.) И просто выполнить обычную проверку, игнорируя такие ячейки:
int pad_size = 1; // how many neighbors around x,y
int size_w = 10+(pad_size*2);
int size_h = 10+(pad_size*2);
int[][] grid = new int[size_w][size_h];
for (int x=0; x<size_w; x++) {
for (int y=0; y<size_h; y++) {
if (x<pad_size || x>=size_w-pad_size || y<pad_size || y>=size_h-pad_size) {
grid[x][y] = -1; // ignore
} else {
grid[x][y] = ((y-pad_size)*10)+(x-pad-size); // 0..99
}
}
}
тогда для любой заданной точки: х, у
for (int nx=x-pad_size; nx<=x+pad_size; nx++) {
for (int ny=y-pad_size; ny<=y+pad_size; ny++) {
if (-1!=grid[nx][ny] && !(nx==x && ny==y)) {
// grid[p.x][p.y] is a neighbor of grid[x][y]
}
}
}