1

我正在做的是创建一个命令行“游戏”,其中有一个 3x3 网格(阵列),您可以通过输入方向(上、下、左、右)在其中移动“1”。

例如:

0 0 0

0 1 0

0 0 0

我已经做到了,所以如果 1 在数组的边缘,则不允许它移出边界(阅读:导致超出索引错误)。

我完全迷失了,因为每当我尝试向右移动时,我都会收到以下信息:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Logic.setMove(Logic.java:87)
at Logic.getMove(Logic.java:10)
at GridGameMain.main(GridGameMain.java:13)

这是我的代码:

public class GridGameMain {
static int[][] board = new int[3][3];
public static void main(String[] args){

    board[(int) (Math.random() * 2.5)][(int) (Math.random() * 2.5)] = 1;
    for (int i =0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
        System.out.print(" " + board[j][i]);
        }
        System.out.println("");
        }
    Logic l = new Logic();
    l.getMove();

}

}


import java.util.Scanner;

public class Logic extends GridGameMain{
void getMove(){     //takes user input then calls setMove

    String direction;  //string to hold the direction
    Scanner user_input = new Scanner(System.in);   
    direction = user_input.next();    
    Logic l = new Logic();      
    l.setMove(direction);        

}
void setMove(String direction){ //called when user presses enter upon typing a move
    Logic l = new Logic();

    if(direction.equals("up")){

        if(board[0][0] == 1 || board[1][0] == 1 || board[2][0] == 1 ){

            System.out.println("Invalid move!");

            l.getMove();

        }else{
        for(int a = 0; a < 3; a++){
            for(int b = 0; b < 3; b++){
                if(board[a][b] == 1){
                    board[a][b-1] = 1;
                    board[a][b] = 0;
                    break;
                }
            }
        }
        l.printBoard();
        System.out.println("you moved up");
        l.getMove();
        }
    }

    if(direction.equals("down")){           
        if(board[0][2] == 1 || board[1][2] == 1 || board[2][2] == 1 ){
            System.out.println("Invalid move!");
            l.getMove();
        }else{
            for(int a = 0; a < 3; a++){
                for(int b = 0; b < 3; b++){
                    if(board[a][b] == 1){
                        board[a][b+1] = 1;
                        board[a][b] = 0;
                        break;
                    }
                }
            }
            l.printBoard();
        System.out.println("you moved down");
        l.getMove();
        }
    }
    if(direction.equals("left")){
        if(board[0][0] == 1 || board[0][1] == 1 || board[0][2] == 1 ){
            System.out.println("Invalid move!");
            l.getMove();
        }else{
            for(int a = 0; a < 3; a++){
                for(int b = 0; b < 3; b++){
                    if(board[a][b] == 1){
                        board[a-1][b] = 1;
                        board[a][b] = 0;
                        break;
                    }
                }
            }
            l.printBoard();

        System.out.println("you moved left");
        l.getMove();
        }
    }
    if(direction.equals("right")){
        if(board[2][0] == 1 || board[2][1] == 1 || board[2][2] == 1 ){
            System.out.println("Invalid move!");
            l.getMove();
        }else{
            for(int a = 0; a < 3; a++){
                for(int b = 0; b < 3; b++){
                    if(board[a][b] == 1){
                        board[a+1][b] = 1;
                        board[a][b] = 0;
                        break;
                    }
                }
            }

        l.printBoard();
        System.out.println("you moved right");
        l.getMove();
        }
    }
}
void printBoard(){
    for (int i =0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
        System.out.print(" " + board[j][i]);
        }
        System.out.println("");
        }
}
}

我只是不确定为什么当我可以向上、向下和向左移动时我不能向右移动。请告诉我我没疯!

4

5 回答 5

2

问题是您将“1”从左向右移动,因此由于您打破了第一个,因此您不会打破第二个,所以它会继续移动“1”,直到它被放在数组之外( ArrayIndexOutOfBoundsException)。

解决它的一个例子:

            boolean found = false;
            for(int a = 0; a < 3; a++){                 
                for(int b = 0; b < 3; b++){                     
                    if(board[a][b] == 1){                         
                        board[a+1][b] = 1;                         
                        board[a][b] = 0;
                        found = true;
                        break;                     
                    }
                    if(found){
                        break;
                    }
                }             
            }
于 2012-07-12T06:40:44.053 回答
2

在您向右移动:

        for(int a = 0; a < 3; a++){
            for(int b = 0; b < 3; b++){
                if(board[a][b] == 1){
                    board[a+1][b] = 1;  // what if a is 2??
                    board[a][b] = 0;
                    break;
                }
            }

当 a 为 2 时,访问 board[a+1][b] 就是访问 board[3][b]。在 3*3 板上,这超出了界限。

编辑:问题是由于移动 1 后,您继续循环 - 但没有初始边界检查。因此,在 1 从中央列移动到右侧之后,您尝试再次移动它。由于您循环的原因,这只发生在正确的移动中。

有两个简单的解决方案:

  1. 使用一些标志来确保你也打破了外循环,或者更好 -
  2. for根据您实际要检查的内容更改 s 的边界。如果您不打算移动1第 2 列上的 a,则可以a在 0 和 1 之间进行循环。如果您永远不会使其从该点移动,则没有理由上升到 2。所有其他动作也是如此 - 将适当的界限从 更改< 3< 2
于 2012-07-12T06:23:18.770 回答
2

我认为问题在于,您检查以确保 1 不在最右边,然后您开始向右移动。这意味着,如果您的 1 在第 0 列上,则将其移至第 2 列,然后在下一次也是最后一次迭代时,将其移至第 3 列。

另外,你确定你下山时不会发生这种情况吗? 这不会发生下降,因为正如@Keppil 所说,你打破了“行”(相关)循环,而向右走,你打破了第一列,这不是你想要的。

此外,您可以使用标签来打破您想要的任何循环。方法如下

于 2012-07-12T06:38:27.187 回答
1

你的break;for 循环内部似乎只中断了内部 for 循环。打破 后for(int b = 0; b < 3; b++){ .. },外部循环没有理由停止。

您的循环找到1[1][1] 并将其向右移动。然后它打破了内部循环。尽管如此,它还是调用了内部循环 for a=2,即您1现在所在的位置。他试图再次转移......但异常失败。

于 2012-07-12T06:40:49.043 回答
0

我相信当你向右走时你应该得到一个错误。原因是当你向右移动一个时,你打破了然后你增加了一个,但你没有检查它是否再次越界。一旦“b”循环完成,然后增加“a”,它就会将其注册为值为 1 并再次向右移动。这种情况一直持续到超出范围为止。更正代码的一种简单方法是反转循环,使外循环递增“b”,而内循环递增“a”。

于 2012-07-12T06:55:38.070 回答