我正在尝试制作一个洪水填充游戏,将数字打印到控制台窗口,并允许用户选择一个数字,以便填充"具有相同编号的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:
* "1\t0\t3\t\n2\t0\t2\t\n1\t0\t1\t\n"
* @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;
}
}
答案 0 :(得分:1)
在floodFill
方法中,在致电row
之前,您不会检查col
或board[row][col]=newColor
是否在界限范围内。
您的代码:
if(row<0||col<0){
//do nothing
return;
}
应放在函数的较高位置,以便在board[row][col]=newColor
之前进行检查。它还需要检查它是否大于数组的宽度和高度。
正确的代码:
if(row<0||col<0||row>=board.length||col>=board[0].length)
{
return;
}
答案 1 :(得分:0)
您检查
if(row<0||col<0)
因此row
和col
都可以 0 。
然后你有
floodFill(row,col-1,origColor,newColor);
floodFill(row,col+1,origColor,newColor);
floodFill(row-1,col,origColor,newColor);
floodFill(row+1,col,origColor,newColor);
因此,两者中的任何一个都可能成为-1
。
您的代码具有以下验证顺序:
if(board[row][col]!=origColor){
return;
}
if(row<0||col<0){
//do nothing
return;
}
在第一个if
中,您可以拥有[-1]
。如果你交换两个if
,它就不可能。