Java 被这段代码卡住了

Java 被这段代码卡住了,java,Java,我正在做的是创建一个命令行游戏,其中有一个3x3网格阵列,您可以通过键入上、下、左、右方向来移动1 例如: 0 0 0 0110 0 0 0 我已经这样做了,如果1位于数组的边缘,则不允许它移出读取的边界:导致索引外错误 我完全迷失了方向,因为每当我尝试向右移动时,我都会收到以下信息: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at Logic.setMove(Logic.java:87) at

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

例如:

0 0 0

0110

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("");
        }
}
}
我只是不知道为什么我不能向右移动,当我可以向上、向下和向左移动都很好的时候。请告诉我我没有疯

向右移动时:

        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时,访问板[a+1][b]即访问板[3][b]。在一个3*3的板上,这是超越界限的

编辑:问题是因为在移动1后,继续执行外部循环,但没有初始边界检查。因此,在将1从中心柱移动到右侧柱后,再次尝试移动它。由于“为什么要循环”,这只会在向右移动时发生

有两种简单的解决方案:

使用一些标志,以确保您也打破了外部循环,或者更好- 根据实际要检查的内容更改fors的边界。如果不移动列2上的1,则可以在0和1之间创建一个循环。没有理由上升到2,如果你永远不会让它从那一点移动。所有其他移动也一样-将适当的边界从<3更改为<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时,访问板[a+1][b]即访问板[3][b]。在一个3*3的板上,这是超越界限的

编辑:问题是因为在移动1后,继续执行外部循环,但没有初始边界检查。因此,在将1从中心柱移动到右侧柱后,再次尝试移动它。由于“为什么要循环”,这只会在向右移动时发生

有两种简单的解决方案:

使用一些标志,以确保您也打破了外部循环,或者更好- 根据实际要检查的内容更改fors的边界。如果不移动列2上的1,则可以在0和1之间创建一个循环。没有理由上升到2,如果你永远不会让它从那一点移动。所有其他移动也一样-将适当的边界从<3更改为<2。
我认为问题在于,你检查以确保1不在最右边,然后你开始把东西移到右边。这意味着,如果1位于列0上,它将移动到列2,然后在下一次也是最后一次迭代中,它将移动到列3

还有,你确定你下楼时不会发生这种情况吗? 向下时不会发生这种情况,因为正如@Keppil所说,您打破了行相关循环,而向右时,您打破了列1,这不是您想要的


此外,您还可以使用标记打破任何循环

我想问题是,你检查一下,确保1不在最右边,然后你就开始把东西移对了。这意味着,如果1位于列0上,它将移动到列2,然后在下一次也是最后一次迭代中,它将移动到列3

还有,你确定你下楼时不会发生这种情况吗? 向下时不会发生这种情况,因为正如@Keppil所说,您打破了行相关循环,而向右时,您打破了列1,这不是您想要的


此外,您还可以使用标记打破任何循环

问题在于,您将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;
                    }
                }             
            }

问题是,您正在将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;
                    }
                }             
            }
休息;在for循环内部,似乎只中断内部for循环。在破坏forint b=0后;b<3;b++{..},外部循环没有理由停止

循环在[1][1]处找到1并将其向右移动。然后它打破了内部循环。尽管如此,它还是调用a=2的内部循环,其中现在是1。他又试着换衣服。。并且异常失败。

中断;在for循环内部,似乎只中断内部for循环。在破坏forint b=0后;b<3;b++{..},外部循环没有理由停止


循环在[1][1]处找到1并将其向右移动。然后它打破了内部循环。尽管如此,它还是调用a=2的内部循环,其中现在是1。他又试着换衣服。。并且异常地失败。

我认为当你向右移动时,应该会出现错误。原因是当你向右移动一个时,你会断开,然后增加

但是你没有检查它是否再次出界。一旦“b”循环完成,然后递增“a”,则它将注册为值为1,并再次向右移动。这会一直持续到它出界为止。纠正代码的一个简单方法是反转循环,使外循环递增“b”,内循环递增“a”。

我认为当你向右移动时,应该会出现错误。原因是当你向右移动一个时,你打破了,然后增加了一个,但是你没有检查它是否再次超出了界限。一旦“b”循环完成,然后递增“a”,则它将注册为值为1,并再次向右移动。这会一直持续到它出界为止。纠正代码的一个简单方法是反转循环,使外循环递增“b”,内循环递增“a”。

如果您查看稍高于for语句,您可以看到我有一个If语句检查,以查看右边缘上的任何内容是否等于1。我没有任何其他方向的问题。是的,这很有效,谢谢!我完全忽略了那一部分=/若你们稍微看一下for语句,你们可以看到我有一个If语句检查,看看右边的任何东西是否等于1。我没有任何其他方向的问题。是的,这很有效,谢谢!我完全忽略了那一部分=/顺便问一下,为什么逻辑要扩展GridGameMain?我会因为这么说而大吃一惊,但这是我刚刚想到的一件非常快的事情,我扩展了它以访问板数组值。除了你的例外,你每次递归调用setMove都会创建一个新的逻辑对象。在类中使用this.getMove和this.setMove时,您应该只创建一个逻辑对象。为什么您仍然要创建新的逻辑实例,而不是调用this.getMove;您正在获得特定问题的答案。现在,附带一个话题,仅仅作为一个建议:如果你设计这个,这样你就可以存储1的位置,并在需要的时候简单地画一块板,你可能会有一个更轻松的时间。在处理更大的电路板时,它也会更有效。顺便问一下,为什么逻辑要扩展GridGameMain?我会因为这么说而感到厌烦,但这是我刚刚想到的一件非常快的事情,我扩展了它以访问电路板数组值。除了你的例外,您正在使用setMove的每次递归调用创建一个新的逻辑对象。在类中使用this.getMove和this.setMove时,您应该只创建一个逻辑对象。为什么您仍然要创建新的逻辑实例,而不是调用this.getMove;您正在获得特定问题的答案。现在,附带一个话题,仅仅作为一个建议:如果你设计这个,这样你就可以存储1的位置,并在需要的时候简单地画一块板,你可能会有一个更轻松的时间。在处理较大的电路板时,它也会更有效。OP在内部循环上执行中断,因此这只能在外部循环变量递增时发生,例如向右。@Keppil啊,是的,你是对的。所以,这只会发生在正确的情况下,因为您碰巧选择了先循环列,然后再循环Rowsah Miquel,非常感谢这个链接。我刚刚完成了Head First Java,从未遇到过标记系统,因此这将派上用场!:D@EnviousNoob我已经用Java编程多年了,几个月前我才发现这个链接;OP在内部循环上执行一个中断,因此只有当外部循环变量递增时才会发生这种情况,例如向右运行。@Keppil啊,是的,你是对的。所以,这只会发生在正确的情况下,因为您碰巧选择了先循环列,然后再循环Rowsah Miquel,非常感谢这个链接。我刚刚完成了Head First Java,从未遇到过标记系统,因此这将派上用场!:D@EnviousNoob我已经用Java编程多年了,几个月前我才发现这个链接;这个修好了,谢谢!如此少的一点代码会有很大的帮助!这个修好了,谢谢!如此少的一点代码会有很大的帮助!