-1

私は2つのオブジェクトを持っています。1 つは Cell と呼ばれ、もう 1 つは FinalSolve と呼ばれます。このプログラムの目的は、各セルをループして出口を探して迷路を解くことです。

cell オブジェクトは、迷路のセルを表し、4 つのインスタンス変数、1 つのコンストラクター、および指定されたインスタンス変数を返す 4 つの他のインスタンス メソッドを持ちます。

    //the variables
    private int value;
    private int column;
    private int row;
    private char symbol;
    private int nuValue;




    //the methods
    public value()
    {
    return value
    }

等々。私の迷路オブジェクトには、次の 6 つのインスタンス メソッドが含まれています。

  • 解決する
  • マーク パス
  • 隣人を見つける
  • findCellWithValue
  • setTheValue

それらは非常にわかりやすい名前を持ち、私が期待しているものを正確に返します。

解決する

アルゴリズムを使用し、上記のすべての方法を利用して迷路を解こうとする方法です

public void solve()
{
    Cell[] entrance = findCellWithValue(250);
    Cell[] neighborsOf = findNeighbors(entrance[0]);
    for(Cell neighbor : neighborsOf)
    {
        setTheValue(1, neighbor);
    }
    int moveCount = 1;
    boolean foundExit = false;
            try{
    while(!foundExit && moveCount <= 200)
    {
        Cell[] theCells = findCellWithValue(moveCount);
        for(Cell justOne : theCells)
        {
            if(justOne.symbol() == '!')
            {
                foundExit = true;
                markPath();
                                    break;
            }
            else
            {
                Cell[] moreNeighbors = findNeighbors(justOne);
                for(Cell prostie : moreNeighbors)
                {
                    if(prostie.value() == 0)
                    {
                    setTheValue(moveCount+1, prostie);
                    }
                }
            }

        }
        moveCount++;
    }
            }catch(Exception e)
            {
            System.out.println("" + moveCount);
            System.out.println("" + e.getMessage());
            }


}

マーク パス

このメソッドは、solve メソッドがプログラムを解くと呼び出され、出口から入り口へのパスをマークします。プログラムでエラーが発生したため、このメソッドはまだ進行中であり、「Hello」と出力されるだけです

public void markPath()
{
    System.out.println("Hello");
}

隣人を見つける

迷路内で指定されたセルの隣接セル (空白) を検索し、それらを配列で返します。

    public Cell[] findNeighbors(Cell theCell)
    {
        Cell[] neighborsCell = new Cell[1];
        int neighbors = 0;
        int column = theCell.column();
        int row = theCell.row();
                    if(column - 1 < 0);
                    else
                    {
                        char some = maze[column-1][row].symbol();
                        if(some == ' ')
                        {
                            if(neighbors == neighborsCell.length)
                            {
                                Cell[] biggerArray = new Cell[neighborsCell.length + 1];
                                System.arraycopy(neighborsCell, 0, biggerArray, 0, neighbors - 1);
                                neighborsCell = biggerArray;

                            }
                            neighborsCell[neighbors] = maze[column-1][row];
                        }
                    }
                    if(column + 1 > 20 );
                    else
                    {
                        char someElse = maze[column+1][row].symbol();
                        if(someElse == ' ')
                        {
                            if(neighbors == neighborsCell.length)
                            {
                                Cell[] biggerArray = new Cell[neighborsCell.length + 1];
                                System.arraycopy(neighborsCell, 0, biggerArray, 0, neighbors - 1);
                                neighborsCell = biggerArray;

                            }
                            neighborsCell[neighbors] = maze[column+1][row];

                        }
                    }
                    if(row - 1 < 0);
                    else
                    {
                        char someElse = maze[column][row-1].symbol();
                        if(someElse == ' ')
                        {
                            if(neighbors == neighborsCell.length)
                            {
                                Cell[] biggerArray = new Cell[neighborsCell.length + 1];
                                System.arraycopy(neighborsCell, 0, biggerArray, 0, neighbors - 1);
                                neighborsCell = biggerArray;

                            }
                            neighborsCell[neighbors] = maze[column][row-1];

                        }

                    }
                    if(row + 1 > 10);
                    else
                    {
                        char someElse = maze[column][row+1].symbol();
                        if(someElse == ' ')
                        {
                            if(neighbors == neighborsCell.length)
                            {
                                Cell[] biggerArray = new Cell[neighborsCell.length + 1];
                                System.arraycopy(neighborsCell, 0, biggerArray, 0, neighbors - 1);
                                neighborsCell = biggerArray;

                            }
                            neighborsCell[neighbors] = maze[column][row+1];

                        }

                    }



        return neighborsCell;
    }

デフォルトの toString メソッドをオーバーライドし、ファイルから読み取ったときに迷路をそのまま返します

@Override
    public String toString()
    {
        String result = "";
        for(int row = 0; row < HEIGHT; row++)
        {
            for(int column = 0; column < WIDTH; column++) {
                            switch(maze[column][row].nuValue())
                            {
                            case HEDGE: result += HEDGE_REP; break;
                            case SPACE: result += SPACE_REP; break;
                            case ENTRANCE: result += ENTRANCE_REP; break;
                            case EXIT: result += EXIT_REP; break;

                            }
                        }//switch
                result += NLS;


        }//for
        return result;

    }//toString

findCellWithValue

引数として指定された int を値として持つセルを検索して、迷路全体をループします

    public Cell[] findCellWithValue(int theValue)
{
    int currentNoOfCells = 0;
    Cell[] theCells = new Cell[INITIAL_ARRAY_SIZE];
        for(int row = 0; row < HEIGHT; row++)
        {
            for(int column = 0; column < WIDTH; column++)
            {
                if(maze[column][row].value() == theValue)
                {
                    if(currentNoOfCells == theCells.length)
                    {
                        Cell[] biggerArray = new Cell[theCells.length + ARRAY_RESIZE_FACTOR];
                                            System.arraycopy(theCells, 0, biggerArray, 0, theCells.length);
                        theCells = biggerArray;

                    }
                    theCells[currentNoOfCells] = maze[column][row];
                    currentNoOfCells++;

                }

            }

        }
    return theCells;
}

setTheValue

セルの値を引数として指定された int に設定します

public void setTheValue(int value, Cell someCell)
{
    int column = someCell.column();
    int row = someCell.row();
    char symbol = someCell.symbol();
    maze[column][row] = new Cell(column, row, symbol, value);
}

私の solve メソッドの try および catch ステートメントは、純粋に、エラーが発生した理由と場所を突き止めようとするためのものです。そして、NullPointerException を取得すると、moveCount が 6 と出力されます。

ファイルの迷路は、「#」で表される生け垣で囲まれた 10 x 20 の長方形です。空白は " " で表され、"!" で終了します。と「?」で入場。

また、私のソルブ メソッドが 250 のセル値を見つけることから始まることに気付いたかもしれません。これは、次のような迷路のコンストラクターで指定された入口の値です。

コンストラクタ

        public FinalSolve(Scanner input)
    {

        for(int row = 0; row < HEIGHT; row++)
        {
            String mazeLine = input.nextLine();
            for(int column = 0; column < WIDTH; column++)
            {

                char character = mazeLine.charAt(column);
                switch(character)
                {
                case SPACE_REP:
                if(column == 7 && row == 7) 
                                    {
                maze[column][row] = new Cell(column, row, SPACE_REP, 20);
                                    }else{
                maze[column][row] = new Cell(column, row, SPACE_REP, 0);
                                    }

                break;


                case HEDGE_REP: maze[column][row] = new Cell(column, row, HEDGE_REP, 0);break;
                case ENTRANCE_REP: maze[column][row] = new Cell(column, row, ENTRANCE_REP, 250);break;
                case EXIT_REP: maze[column][row] = new Cell(column, row, EXIT_REP, 0);break;

                }//switch
            }//for
            }//for

        solve();            
        }//constructor

エラー

メソッドsolveの51行目。この行:

 if(justOne.symbol() == '!')
4

1 に答える 1

0

あなたが言及した行に基づく関連コードが原因NullPointerExpectionです。

Cell[] theCells = (moveCount);
for(Cell justOne : theCells)
{
  if(justOne.symbol() == '!')
  ...

これは、それjustOnenull何らかの理由によるものであることを意味します。justOne配列内の値の1つが含まれていますtheCellstheCellsからディレクトリが来findCellWithValue()ます。この配列は、デフォルトのサイズになるように初期化され、一致するものが見つかった場合にのみ割り当てられます。一致するものが見つからない場合、配列内のすべての要素にが含まれますnull

これは、2つのことのいずれかを行う必要があることを意味します。1)配列内の値がnull処理前にあるかどうかを確認します(値を段階的に追加しているため、ループを中断します)。2)null値を返さないでください。

個人的には、メソッドのユーザーに余分な要件を課さないため、2がより良いオプションだと思います。findCellWithValue()必要に応じて配列が大きくなるように記述されています。これはまさにそのようArrayListに設計されたものです。これを使用すると、この種のエラーは発生せず、コードが簡素化されます。拡大するコレクションがある場合、または常に同じサイズであることが保証されていない場合は、通常、を使用することをお勧めしますList

編集:
他の人が指摘しているように、あなたの質問はかなり大きかった。問題を追跡して、バグを見つけるために必要なものがどれだけ少ないかを説明しました。質問するときは、問題を再現するために必要な最小限のコードを含めるようにしてください。例外がある場合は、常にエラーメッセージスタックトレースを含めてください。のようなものが質問に関連していないことは明らかですmarkPath()toString()スタックトレースで言及されていない限り、おそらくのみ)。

于 2013-03-06T20:53:21.780 に答える