我创建了一个类,它生成一个充当网格的二维整数数组。此网格包含一个名为getNeighbors()
的方法。这个方法应该得到所有八个周围的邻居,它确实如此,但我需要删除溢出的邻居。想象一下国际象棋中的女王。她可以向各个方向移动:垂直,水平和对角线。
Queen has 8 moves: Queen has 6 moves
+---+---+---+ +---+---+---+
| y | y | y | | Q | y | y |
+---+---+---+ +---+---+---+
| y | Q | y | | y | y | n |
+---+---+---+ +---+---+---+
| y | y | y | | y | n | y |
+---+---+---+ +---+---+---+
3x3网格布局:
+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
| 3 | 4 | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+
现在,我想知道我是否可以检测一个细胞是否与物理上相邻而不是理论上(溢出包裹)。有没有一个解决方案不影响搜索neigbors的性能,特别是在更大的网格上?
Neighbors for (0): [8, 6, 7, 2, 1, 5, 3, 4]
Neighbors for (1): [6, 7, 8, 0, 2, 3, 4, 5]
Neighbors for (2): [7, 8, 6, 1, 0, 4, 5, 3]
Neighbors for (3): [2, 0, 1, 5, 4, 8, 6, 7]
Neighbors for (4): [0, 1, 2, 3, 5, 6, 7, 8]
Neighbors for (5): [1, 2, 0, 4, 3, 7, 8, 6]
Neighbors for (6): [5, 3, 4, 8, 7, 2, 0, 1]
Neighbors for (7): [3, 4, 5, 6, 8, 0, 1, 2]
Neighbors for (8): [4, 5, 3, 7, 6, 1, 2, 0]
Neighbors for (0): [8, 6, -, 2, 1, -, 3, 4]
Neighbors for (1): [-, 7, -, 0, 2, 3, 4, 5]
Neighbors for (2): [-, 8, 6, 1, 0, 4, 5, -]
Neighbors for (3): [-, 0, 1, 5, 4, -, 6, 7]
Neighbors for (4): [0, 1, 2, 3, 5, 6, 7, 8]
Neighbors for (5): [1, 2, -, 4, 3, 7, 8, -]
Neighbors for (6): [-, 3, 4, 8, 7, 2, 0, -]
Neighbors for (7): [3, 4, 5, 6, 8, -, 1, -]
Neighbors for (8): [4, 5, -, 7, 6, -, 2, 0]
public class Calculate {
public static void main(String[] args) {
Board b = new Board(5);
System.out.println(b);
for (int i = 0; i < b.getCellCount(); i++) {
System.out.println(b.getNeighborsAsString(i));
}
}
}
public class Board extends AbstractGrid {
public Board(int size) {
super(size);
}
public int[] getNeighbors(int currRow, int currCol) {
int prevCol = (currCol - 1 + size) % size;
int nextCol = (currCol + 1) % size;
int prevRow = (currRow - 1 + size) % size;
int nextRow = (currRow + 1) % size;
return new int[] {
cells[prevRow][prevCol], // North-West
cells[prevRow][currCol], // North
cells[prevRow][nextCol], // North-East
cells[currRow][prevCol], // West
cells[currRow][nextCol], // East
cells[nextRow][prevCol], // South-West
cells[nextRow][currCol], // South
cells[nextRow][nextCol] // South-East
};
}
public String getNeighborsAsString(int index) {
return getNeighborsAsString(index / size, index % size);
}
public String getNeighborsAsString(int row, int col) {
StringBuffer buff = new StringBuffer();
int[] neighbors = getNeighbors(row, col);
int index = row * size + col;
buff.append(String.format("Neighbors for (%s): [", frmtInt(index)));
for (int i = 0; i < neighbors.length; i++) {
buff.append(frmtInt(neighbors[i]));
if (i < neighbors.length - 1) {
buff.append(", ");
}
}
return buff.append("]").toString();
}
}
public abstract class AbstractGrid {
protected int[][] cells;
protected int size;
public static final String LF = System.getProperty("line.separator");
private int base = 16;
private int cellWidth;
private String zeroPad;
private String padding;
private boolean showBorder = true;
public AbstractGrid(int size) {
if (size % 2 == 0 || (size < 3 && size > 25)) {
throw new IllegalArgumentException(
"Board size must be an odd number between 3 and 25 (inclusive)");
}
this.size = size;
this.cellWidth = Integer.toString(size * size - 1, base).length();
this.zeroPad = String.format(String.format("%%0%dd", cellWidth), 0);
this.padding = String.format("%%%ds", cellWidth);
this.cells = new int[size][size];
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
cells[row][col] = row * size + col;
}
}
}
public String frmtInt(int value) {
StringBuffer buff = new StringBuffer(zeroPad).append(Integer.toString(
value, base).toUpperCase());
return buff.substring(buff.length() - zeroPad.length());
}
public String frmtStr(String value) {
return String.format(padding, value);
}
private StringBuffer generateHorizontalLine(StringBuffer buff) {
if (showBorder) {
buff.append('+');
}
for (int col = 0; col < size; col++) {
for (int i = 0; i <= cellWidth + 1; i++) {
buff.append('-');
}
if (col < size - 1) {
buff.append('+');
}
}
if (showBorder) {
buff.append('+');
}
return buff.append(LF);
}
private StringBuffer generateHorizontalRow(StringBuffer buff, int row) {
if (showBorder) {
buff.append('|');
}
buff.append(" ");
for (int col = 0; col < size; col++) {
buff.append(frmtInt(cells[row][col]));
if (showBorder || col < size - 1) {
buff.append(" | ");
}
}
buff.append(LF);
if (row < size - 1) {
return generateHorizontalLine(buff);
}
return buff;
}
public int getCell(int index) {
return cells[index / size][index % size];
}
public int getCell(int row, int col) {
return cells[row][col];
}
public int getCellCount() {
return size * size;
}
public int getSize() {
return size;
}
@Override
public String toString() {
StringBuffer buff = new StringBuffer();
if (cells != null) {
if (showBorder) {
generateHorizontalLine(buff);
}
for (int row = 0; row < size; row++) {
generateHorizontalRow(buff, row);
}
if (showBorder) {
generateHorizontalLine(buff);
}
}
return buff.toString();
}
}