2017-12-23 7 views
-3

私は小さな迷路ゲームのための元に戻す機能を取得する方法を理解しようとしています。まず、最後の方向が何だったのかを確認し、反対方向に戻ってこれを行う方法を工夫しました。しかし、私はまた、アイテムのピックアップや隠れた壁などを追跡する必要があったので、このコードはあまりにも長くなっていたテキストベースのJavaの元に戻す関数

コードの背景情報:これは迷路を保存するために私はこれが最も簡単だったので使用します。私はすべての文字列を格納するためにArraylist<String[][]>を使用します。 各ステップの後、プレーヤーはString[][]アレイをarraylistに保存します。プレイヤーがアンドゥと言うとき、私はarraylistの最後のString[][]を見て、String[][]をこれに戻したいと思っています。しかし、currentPosは更新されることはありません。問題がどこにあるのか分かりません。

if (direction.equals("north")) { 
    if (currentPos[i - 1][j].equals("---")) { 
     continue; 
    } else { 
     currentPos[i][j] = " "; 
     currentPos[i - 2][j] = "P"; 

     break; 
    } 
} 
if (direction.equals("undo")) { 
     currentPos = history.get(history.size()-2); 
     history.remove(history.size()-1); 
     break; 
} 
+0

質問がありますか? – Zachary

+0

デバッガでコードをステップ実行しましたか? –

+0

なぜ動作しないのですか?どうすれば動作させることができますか?私の目では、これはcurrentPosが以前のものと同じであることを確認するはずですが、そうではありません。 – Joris

答えて

0

ヒストリの設定方法を理解していないと、私はヒントリストに現在のマップを追加するだけであることを前提にしています。慎重でない場合は、単純に同じオブジェクトを追加し、現在のマップ状態への多重オブジェクト参照をヒストリに取り込みます。これには、最新のマップへの参照のみが含まれているため(実際にはの履歴は保存されていないため)、状態が変化していない状態で観測している効果があります。

オブジェクトから値を取得するには、通常、オブジェクトをクローンする必要があります(clone()メソッドを呼び出す)。しかしながら、2次元配列のクローニングは幾分問題がある。 2次元配列「浅い」でclone()メソッドを呼び出すとオブジェクトがクローン化され、基本的には最初の次元だけが複製され、2番目のオブジェクトは同じオブジェクトへの参照として残ります(理由は、最初の1次元が配列は2番目の1次元への参照を保持します)。浅くコピーされたオブジェクトの値を変更すると元の値が変更されます。その逆もあります。オブジェクトを区別しない場合は、元の値を変更します。

2つの異なるオブジェクトを作成するには、「深い」クローンを実行する必要があります。これは、ヘルパーメソッドで簡単に実装できます。以下のコードは、オブジェクトを履歴リストに保存する前にオブジェクトを完全に複製することの重要性を示しています。

public static void main (String args[]) throws Exception { 
     ArrayList<String[][]> list = new ArrayList<>(); 
     String[][] shallowClonedMap = new String[1][1]; 
     String[][] deepClonedMap = new String[1][1]; 

     shallowClonedMap[0][0] = "Old"; 
     deepClonedMap[0][0] = "Old"; 

     list.add(shallowClonedMap.clone()); 
     list.add(deepClone(deepClonedMap)); 

     shallowClonedMap[0][0] = "New"; 
     deepClonedMap[0][0] = "New"; 

     list.add(shallowClonedMap.clone()); 
     list.add(deepClone(deepClonedMap)); 

     for (String[][] item : list) { 
      System.out.print(item[0][0]); 
     } 
    } 

    public static String[][] deepClone(String[][] arry) { 
     if (arry == null) { 
      return null; 
     } 
     String[][] clone = new String[arry.length][]; 
     for (int i = 0; i < arry.length; i++) { 
      clone[i] = arry[i].clone(); 
     } 
     return clone; 
    } 

このコードを実行するための出力である:NewOldNewNew出力が「OldOldNewNew」である「意図」一方。これにより、クローンされてリストに追加された後でも、shallowClonedMapが「新規」に更新されたことがわかります。

関連する問題