[英]Faster way to find neighbors indexes
我正在創建一個掃雷游戲,我真的需要一種快速有效的方法來計算地雷的鄰居。實際上,我將自己的圖塊存儲在一個Arraylist中,以便可以在gridview中使用它們,因此位置是線性的,但是渲染將是一個矩陣n * n。 我有辦法做到,但我認為有人可以有一種更有效的辦法。
我要實現的目標:
0 1 1 1
0 1 * 1
0 1 1 1
0 0 0 0
因此,鑒於矩陣在線性列表中具有索引,其位置應為以下位置:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
因此,我需要一種有效的方法來獲取給出索引7的2、3、4、6、8、10、11、12。
生成炸彈的代碼:
public void plantMines(){
Random rand = new Random();
//Used set so we dont get duplicates
Set<Integer> mineCoords = new LinkedHashSet<>(mDifficulty.mines);
//First we randomly select all coordenates
while (mineCoords.size() < mDifficulty.mines){
Integer coord = rand.nextInt(mListCap) + 1;
mineCoords.add(coord);
}
//Now we can set the mines accordingly
for (Integer coord: mineCoords){
mTiles.get(coord).setMine(true);
}
}
查找鄰居的實際代碼:
for (int row = 0; row < ROW_SIZE; row++) {
for (int col = 0; col < COL_SIZE; col++) {
int neighbourBombSize = 0;
// TOP ROW
if ((row-1) >= 0 && (col-1) >= 0) {
if (getTile(row-1, col-1).hasBomb()) {
neighbourBombSize++;
}
}
if ((row-1) >= 0) {
if (getTile(row-1, col).hasBomb()) {
neighbourBombSize++;
}
}
if ((row-1) >= 0 && (col+1) < COL_SIZE) {
if (getTile(row-1, col+1).hasBomb()) {
neighbourBombSize++;
}
}
// SAME ROW
if ((col-1) >= 0) {
if (getTile(row, col-1).hasBomb()) {
neighbourBombSize++;
}
}
if ((col+1) < COL_SIZE) {
if (getTile(row, col+1).hasBomb()) {
neighbourBombSize++;
}
}
// BOTTOM ROW
if ((row+1) < ROW_SIZE && (col-1) >= 0) {
if (getTile(row+1, col-1).hasBomb()) {
neighbourBombSize++;
}
}
if ((row+1) < ROW_SIZE) {
if (getTile(row+1, col).hasBomb()) {
neighbourBombSize++;
}
}
if ((row+1) < ROW_SIZE && (col+1) < COL_SIZE) {
if (getTile(row+1, col+1).hasBomb()) {
neighbourBombSize++;
}
}
getTile(row, col).setNeighbourBombSize(neighbourBombSize);
}
}
幫助將不勝感激,謝謝。
警告 :我以您的代碼為起點,但是您的索引以1開始,但是在Java數組中索引從0開始,因此它可能無法正常工作。
我會做這樣的事情:
int neighbourBombSize = 0;
// Compute currentCell row / col
int currentCellCol = ((currentCellIndex - 1) % COL_SIZE) + 1;
int currentCellRow = ((currentCellIndex - 1) / COL_SIZE) + 1;
System.out.println("Neighbors of " + currentCellIndex + " (" + currentCellRow + ", " + currentCellCol + ")");
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
if (x == 0 && y == 0) {
continue; // Current cell index
}
int neighborCol = currentCellCol + y;
int neighborRow = currentCellRow + x;
if (neighborCol > 0 && neighborRow > 0 && neighborCol <= COL_SIZE && neighborRow <= ROW_SIZE ) {
int computedNeighborIndex = neighborCol + ((neighborRow - 1) * COL_SIZE);
if (getTile(neighborRow , neighborCol ).hasBomb()) {
neighbourBombSize++;
}
}
}
}
您可以在此處看到一個運行示例(針對所有情況計算鄰居索引): 運行示例
您是否打算使用基於1的線性索引來編寫整個游戲,以引用單元格? 如果是這樣,您將需要隔離與坐標之間的轉換。 否則,您最終將陷入困境。
嘗試這樣的事情:
class Board {
final int rows;
final int cols;
Board(int cols, int rows) {
this.rows = rows;
this.cols = cols;
}
int col(int index) {
assert index > 0 && index <= rows * cols;
return (index - 1) % cols; // -1 because you are using 1-based indexing.
}
int row(int index) {
assert index > 0 && index <= rows * cols;
return (index - 1) / cols;
}
int index(int x, int y) {
assert x >= 0 && x < cols && y >= 0 && y < rows;
return y * cols + x + 1;
}
int[] neighbors(int point) {
int x = col(point);
int y = row(point);
int[] result = new int[8];
int cnt = 0;
// go over possible neighbors and collect valid ones
for (int ny = max(y - 1, 0); ny < min(y + 2, rows); ny++) {
for (int nx = max(x - 1, 0); nx < min(x + 2, cols); nx++) {
if (nx != x || ny != y) {
result[cnt++] = index(nx, ny);
}
}
}
return Arrays.copyOf(result, cnt);
}
}
Board brd = new Board(4, 4);
int colOf7 = brd.col(7); // 2 (0-based from left)
int rowOf7 = brd.row(7); // 1 (0-based from top)
int[] neighborsOf7 = brd.neighbors(7); // [2, 3, 4, 6, 8, 10, 11, 12]
int index = brd.index(2,1); // 7 (1-based linear index)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.