簡體   English   中英

查找鄰居索引的更快方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM