出现java.lang.ArrayIndexOutOfBoundsException:-1错误.递归洪水填充



我正在尝试制作一个洪水填充游戏,该游戏将数字打印到控制台窗口中,并允许用户选择一个数字,以便用相同的数字"填充"2D阵列。目标是用你的颜色填充2D阵列。我用一个4路递归的方法来填充这些数字。每当我运行这个程序,并尝试输入"颜色"时,它都会抛出以下错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
     at Board.floodFill(Board.java:57)
     at Board.floodFill(Board.java:68)
     at Board.move(Board.java:47)
     at FloodIt.main(FloodIt.java:30)

这是我的代码:

class FloodIt {
    public static void main(String args[]) {
        Scanner scan=new Scanner(System.in);
        System.out.println("Welcome to the Flood-It Game.");
        System.out.println("*****************************");
        System.out.println("How large of a board would you like?");
        System.out.println("I would suggest sizes between 3x3 and 20x20.");
        System.out.println("And colors between 3 and 6.");
        String again="";
        do {
            System.out.print("Enter the one digit number of the board width (3-20): ");
            int size=Integer.parseInt(scan.nextLine());
            System.out.print("Enter the number of colors (3-6): ");
            int numColors=Integer.parseInt(scan.nextLine());
            Board board=new Board(size,numColors);
            while(!board.finished()) {
                System.out.print(board);
                System.out.print("What color do you choose? ");
                int color=Integer.parseInt(scan.nextLine());
                board.move(color);
            }
            System.out.println("Nice job, you finished in "+board.numMoves());
            System.out.print("Would you like to play again (Y/N)? ");
            again=scan.nextLine();
        } while (again.equalsIgnoreCase("Y"));
    }
}
import java.util.Random;
/**The board class for the Flood-It game.  This class implements a NxN board filled with numColors colors.
 * The class implements several methods to allow the playing of the game.
 */
class Board {
    private int moves;
    private int[][] board;//a 2D array
    Random rand = new Random();
    /**Constructs a new sizeXsize board filled where each element on the board is a random number between 0
     * and numcolors.  Also initializes the number of moves to zero.
     * @param size the size of the board
     * @param numColors the number of possible entries on the board
     */
    public Board(int size,int numColors) {
        moves=0;
        board = new int[size][size];
        for(int row=0;row<board.length;row++){
            for(int col = 0;col<board[row].length;col++){
                board[row][col]=rand.nextInt(numColors);
            }
        }
    }

    /**Updates the board to fill (from the top left corner) with a specificed color.  
     * Filling stops when any other color is hit besides the one in the top left corner.
     * Play the game at http://floodit.cs.bris.ac.uk/About.aspx to get a better understanding of what
     * this method should do.  You will probably also want to take a look at the algorithm described
     * at http://en.wikipedia.org/wiki/Flood_fill which describes what this method should do.
     * You are free to have this method call other methods (I would recommend creating a private method that
     * this method calls.).
     * @param color the new color to flood the board with.
     */
    public void move(int color) {
        floodFill(0,0,board[0][0],color);
        moves++;
    }
    private void floodFill(int row, int col, int origColor,int newColor){
        //base case
        if(origColor==newColor){
            return;
        }
        if(board[row][col]!=origColor){
            return;
        }
        if(row<0||col<0){
            //do nothing
            return;
        }

        board[row][col]=newColor;
        floodFill(row,col-1,origColor,newColor);
        floodFill(row,col+1,origColor,newColor);
        floodFill(row-1,col,origColor,newColor);
        floodFill(row+1,col,origColor,newColor);    
    }

    /**returns true if the board is not completely filled with a single color.
     * Otherwise it returns false.
     * @return true if board is all one color
     */
    public boolean finished() {
        //TODO finish this method
        return false;
    }

    /**returns how many times the move() method has been called.
     * @return the number of times the move() method has been called.
     */
    public int numMoves() {
        return moves;
    }

    /**Returns a string representation of the board.  Use tabs between elements of the board.
     * And have every row of the board be a seperated by a newline character.
     * Example:
     * "1t0t3tn2t0t2tn1t0t1tn"
     * @return a String representation of the board
     */
    public String toString() {
        String result = "";
        for(int row=0;row<board.length;row++){
            for(int col = 0;col<board[row].length;col++){
                result += board[row][col]+"t";
            }
            result+="n";
        }return result; 
    }
}

floodFill方法中,在调用board[row][col]=newColor之前,不检查rowcol是否在边界内。

您的代码:

if(row<0||col<0){
        //do nothing
        return;
}

应该放在函数中更高的位置,以便在CCD_ 5之前进行检查。它还需要检查它是否大于数组的宽度和高度。

正确代码:

if(row<0||col<0||row>=board.length||col>=board[0].length)
{
   return;
}

检查

if(row<0||col<0)

因此CCD_ 6和CCD_。

然后你有

    floodFill(row,col-1,origColor,newColor);
    floodFill(row,col+1,origColor,newColor);
    floodFill(row-1,col,origColor,newColor);
    floodFill(row+1,col,origColor,newColor);  

所以两者中的任何一个都可以成为CCD_ 8。

您的代码具有以下验证序列:

   if(board[row][col]!=origColor){
        return;
    }
    if(row<0||col<0){
        //do nothing
        return;
    }

在第一个if中,可以使用[-1]。如果你换掉两个if,那就不可能了。

最新更新