Game Of Life 游戏:检查 2D 数组 8 个最近的环境; ArrayIndexOutOfBoundsException 问题

Game Of Life game: Check 2D array 8 closest surroundings; ArrayIndexOutOfBoundsException issue

我遇到过这个问题,但找不到解决方案。有一个二维数组,其中只有 0 和 1(数组的大小并不重要,我使用的是 10x10)。零表示死了,1 表示还活着。我将它加倍循环以检查元素周围环境,当它与其他“单元格”周围环境时,代码可以正常工作。但是当它位于角落或数组的另一边缘时,它会抛出 ArrayIndexOutOfBoundsException。 我的问题是如何在不处理所有可能情况的情况下为此编写代码?

public class Main {

public static void main(String[] args) {
    int[][] grid = {
            {1,1,1,0,1,0,1,0,0,0},
            {1,1,1,0,1,1,0,0,1,0},
            {1,1,0,0,1,0,0,1,0,0},
            {0,1,0,1,0,0,1,0,0,0},
            {0,0,1,0,0,1,0,0,1,0},
            {0,0,0,0,0,0,0,0,1,0},
            {0,0,0,1,0,0,0,1,0,0},
            {0,1,0,0,0,0,0,0,0,0},
            {0,0,0,1,0,0,1,0,0,0},
            {0,1,0,0,0,0,0,0,1,0},
    };

    Simulation sm = new Simulation(grid);
    sm.printOutOriginalGrid();
    sm.gameOfLife();
}

}

public class Simulation {

private int[][] grid;

public Simulation(int[][] grid){
    this.grid = grid;
}
public  void printOutOriginalGrid() {
    System.out.println("Original grid");
    for (int i = 0; i < this.grid.length; i++) {
        for (int j = 0; j < this.grid[i].length; j++) {
            System.out.print(this.grid[i][j] + "  ");
        }
        System.out.println(" ");
    }
}

public int[][] gameOfLife() {
    for (int i = 0; i < this.grid.length; i++) {
        for (int j = 0; j < this.grid.length; j++) {
            int currentCell = this.grid[i][j];
            if(currentCell == 1){
                int currentCellNeighbours = numberOfAliveNeighbours(i,j); 
            }
        }
    }

    return new int[12][12];
}

private int numberOfAliveNeighbours(int i, int j){
    int numberOfAliveNeighbours = 0;

    numberOfAliveNeighbours += this.grid[i-1][j-1];
    numberOfAliveNeighbours += this.grid[i][j-1];
    numberOfAliveNeighbours += this.grid[i+1][j-1];

    numberOfAliveNeighbours += this.grid[i-1][j];
    numberOfAliveNeighbours += this.grid[i+1][j];

    numberOfAliveNeighbours += this.grid[i-1][j+1];
    numberOfAliveNeighbours += this.grid[i][j+1];
    numberOfAliveNeighbours += this.grid[i+1][j+1];

    return numberOfAliveNeighbours;
}

}

numberOfAliveNeighbours 方法中,您必须测试数组索引是否小于零或大于数组大小 - 1。

换句话说,一个 8 长整数数组的索引值是 0 - 7。

您的代码已修复。

public class GameOfLife {

    public static void main(String[] args) {
        int[][] grid = { 
                { 1, 1, 1, 0, 1, 0, 1, 0, 0, 0 }, 
                { 1, 1, 1, 0, 1, 1, 0, 0, 1, 0 },
                { 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, 
                { 0, 1, 0, 1, 0, 0, 1, 0, 0, 0 }, 
                { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
                { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }, 
                { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 }, 
                { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
                { 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 }, 
                { 0, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, };

        Simulation sm = new GameOfLife().new Simulation(grid);
        sm.printOutOriginalGrid();
        sm.gameOfLife();
    }

    public class Simulation {

        private int[][] grid;

        public Simulation(int[][] grid) {
            this.grid = grid;
        }

        public void printOutOriginalGrid() {
            System.out.println("Original grid");
            for (int i = 0; i < this.grid.length; i++) {
                for (int j = 0; j < this.grid[i].length; j++) {
                    System.out.print(this.grid[i][j] + "  ");
                }
                System.out.println(" ");
            }
        }

        public int[][] gameOfLife() {
            for (int i = 0; i < this.grid.length; i++) {
                for (int j = 0; j < this.grid[i].length; j++) {
                    int currentCell = this.grid[i][j];
                    if (currentCell == 1) {
                        int currentCellNeighbours = 
                                numberOfAliveNeighbours(i, j, grid.length);
                    }
                }
            }

            return new int[12][12];
        }

        private int numberOfAliveNeighbours(int i, int j, int limit) {
            int numberOfAliveNeighbours = 0;
            int a = i - 1;
            int b = i + 1;
            int c = j - 1;
            int d = j + 1;

            if (c >= 0) {
                if (a >= 0) {
                    numberOfAliveNeighbours += this.grid[a][c];
                }
                numberOfAliveNeighbours += this.grid[i][c];
                if (b < limit) {                    
                    numberOfAliveNeighbours += this.grid[b][c];
                }
            }

            if (a >= 0) {
                numberOfAliveNeighbours += this.grid[a][j];
            }
            if (b < limit) {
                numberOfAliveNeighbours += this.grid[b][j];
            }

            if (d < limit) {
                if (a >= 0) {
                    numberOfAliveNeighbours += this.grid[a][d];
                }
                numberOfAliveNeighbours += this.grid[i][d];
                if (b < limit) {
                    numberOfAliveNeighbours += this.grid[b][d];
                }
            }

            return numberOfAliveNeighbours;
        }

    }

}

嗯...因为我已经完成了,所以我要post我的答案(我没有@GilberLeBlanc 快)。

如您所知,可以从矩阵中获取 8 个可能的邻居,因此我们需要确保每个定向单元邻居确实在该矩阵的范围内......这是显而易见的。遍历提供的矩阵单元格的每个方向,仅对包含与 ij 最初提供给 numberOfAliveNeighbours() 方法:

这是我的快速总结:

public class Main {

    public static void main(String[] args) {
        int[][] grid = {
            {1,1,1,0,1,0,1,0,0,0},
            {1,1,1,0,1,1,0,0,1,0},
            {1,1,0,0,1,0,0,1,0,0},
            {0,1,0,1,0,0,1,0,0,0},
            {0,0,1,0,0,1,0,0,1,0},
            {0,0,0,0,0,0,0,0,1,0},
            {0,0,0,1,0,0,0,1,0,0},
            {0,1,0,0,0,0,0,0,0,0},
            {0,0,0,1,0,0,1,0,0,0},
            {0,1,0,0,0,0,0,0,1,0},
        };

        Simulation sm = new Simulation(grid);
        sm.printOutOriginalGrid();
        sm.gameOfLife();
    }
}

public class Simulation {

    private int[][] grid;

    public Simulation(int[][] grid) {
        this.grid = grid;
    }

    public void printOutOriginalGrid() {
        System.out.println("Original grid");
        for (int i = 0; i < this.grid.length; i++) {
            for (int j = 0; j < this.grid[i].length; j++) {
                System.out.print(this.grid[i][j] + "  ");
            }
            System.out.println(" ");
        }
    }

    public int[][] gameOfLife() {
        for (int i = 0; i < this.grid.length; i++) {
            for (int j = 0; j < this.grid[i].length; j++) {
                int currentCell = this.grid[i][j];
                if (currentCell == 1) {
                    int currentCellNeighbours = numberOfAliveNeighbours(i, j);
                    // Do what you want with value in currentCellNeighbours.
                    System.out.println("Cell " + i + ", " + j + " has " + 
                                       currentCellNeighbours + " neighbours.");
                }
            }
        }
        
        // return whatever you're preparing to do...
        return new int[12][12];
    }

    private int numberOfAliveNeighbours(int i, int j) {
        /* In a matrix there can be 8 possible neighbours. 
           We need to check if a specific neigbour is actually
           within bounds before checking its value.       */
        int[][] directions = {
            {-1, -1}, // Top/Left
            {0, -1}, // Top
            {1, -1}, // Top/Right
            {-1, 0}, // Left
            {1, 0}, // Right
            {-1, 1}, // Bottom/Left
            {0, 1}, // Bottom
            {1, 1} // Bottom/Right  
        };

        int numberOfAliveNeighbours = 0;  // Start with 0 neighbours

        // Iterate through all the different directions...
        for (int[] d : directions) {
            int dx = d[0];  // Current directional Cell Row
            int dy = d[1];  // Current directional Cell Column
            /* Is the current directional cell within bounds and 
               if it is, does the directional cell element equal 
               the supplied cell element (i, j)?           */
            if ((i + dx) >= 0 && (i + dx) < (grid.length)
                    && (j + dy) >= 0 && (j + dy) < (grid[0].length)
                    && grid[i + dx][j + dy] == grid[i][j]) {
                // Yes it does...increment the neighbour count.
                numberOfAliveNeighbours++;
            }
        }
        // Return the determined neighbour count.
        return numberOfAliveNeighbours;
    }

}