1

私がやっていることは、方向(上、下、左、右)を入力することで「1」を移動できる3x3グリッド(配列)があるコマンドライン「ゲーム」を作成することです。

例えば:

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

右に移動します:

        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を中央の列から右側の列に移動した後、もう一度移動しようとします。これは、ループする理由により、正しい動きでのみ発生します。

2つの簡単な解決策があります。

  1. いくつかのフラグを使用して、外側のループからも抜け出すようにします。
  2. for実際にチェックする内容に応じて、の境界を変更します。1列#2にあるを移動しない場合はa、0と1の間にループを設定できます。2まで移動する予定がない場合は、2まで移動する必要はありません。同じことが他のすべての動きにも当てはまります-適切な境界をから< 3に変更します< 2
于 2012-07-12T06:23:18.770 に答える
2

問題は、1が右端にないことを確認してから、右にシフトし始めることだと思いますつまり、1が列0にある場合は、列2に移動され、次の最後の反復で列3に移動されます。

また、あなたが降りたときにこれが起こらないと確信していますか? @Keppilが言うように、「行」(関連する)ループから抜け出し、右に進むと、列1から抜け出すため、これは発生しません。これは、意図したものではありません。

また、タグを使用して、必要なループから抜け出すことができます。方法は次のとおりです。

于 2012-07-12T06:38:27.187 に答える
2

問題は、「1」を左から右に移動していることです。最初のを壊すので、2番目のを壊さないので、配列の外側に配置されるまで「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 に答える
1

forループのbreak;内側は、内側のforループのみを中断しているようです。を壊した後for(int b = 0; b < 3; b++){ .. }、外側のループが停止する理由はありません。

ループは1at[1][1]を見つけて、それを右にシフトします。次に、内側のループを壊します。a=2それにもかかわらず、それはあなた1が今いる場所の内側のループを呼び出します。彼は再びシフトしようとします..そして例外を除いて失敗します。

于 2012-07-12T06:40:49.043 に答える
0

右に行くとエラーが発生するはずです。その理由は、1つを右にシフトすると、ブレークしてからaをインクリメントしますが、それが再び範囲外になったことを確認しないためです。'b'ループが終了し、'a'をインクリメントすると、値が1として登録され、もう一度右に移動します。これは、範囲外になるまで続きます。コードを修正する簡単な方法は、ループを逆にして、外側のループが「b」をインクリメントし、内側のループが「a」をインクリメントするようにすることです。

于 2012-07-12T06:55:38.070 に答える