-3

I'm trying to figure out how to get a undo function for a small maze game. First I worked out a way to do this by checking what the last direction was and just going back in the opposite direction. But this code was getting way too long since I also had to track back possible item pickups or hidden walls etc.

Background info on the code: I use a String[][] to store the maze as this was the easiest. I use an Arraylist<String[][]> to store all the strings. After each step the player takes I save the String[][] array to the arraylist. When the player say undo I look at the second last String[][] in the arraylist and want to set the String[][] back to this. But the currentPos never seems to get updated. I'm not sure where the problem lies.

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;
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Joris
  • 1
  • 4
  • Do you have a question? – Zachary Dec 24 '17 at 00:02
  • Did you step through the code in the debugger? – Jim Garrison Dec 24 '17 at 00:04
  • Why doesn't it work, how do I get it to work? In my eyes this should make sure currentPos is again what it was before, but it isn't. – Joris Dec 24 '17 at 00:04
  • I did add print functions in a lot of places. Didn't go through a real debugger. The prints basically did the same. – Joris Dec 24 '17 at 00:05
  • It's next to impossible for us to debug this for you: Is history ever saved correctly? Does it ever reach the .equals("undo") if statement? – Zachary Dec 24 '17 at 00:22
  • history is saved correctly it does reach the equals statement. That's why i'm able to print it. But even the prints of history always show the latest array – Joris Dec 24 '17 at 00:43
  • I've posted an answer which may help. It's a guess but it may help. – Zachary Dec 24 '17 at 00:44

1 Answers1

0

Without understanding the way you are setting history, I've made the assumption from your question that you are simply adding the current map to the history list. If you aren't careful, you will be simply adding the same Object, populating the history with multiply Object references to the current map state. This would have the effect you are observing with the state not changing, because you the history only contains a reference to the most recent map (Not storing any actual history).

To obtain the value from an Object, you typically need to clone the object (invoking the clone() method). However, cloning a 2-dimensional array is somewhat problematic. Invoking the clone() method on a 2-dimensional array "shallow" clones the object, essentially only cloning the first dimension while leaving the second as a reference to the same object (The reason for this is that the first 1-dimension of the array holds a reference to the second 1-dimension). Changing the value on a shallow copied object will change the value of the original and vice-versa, not what you want if you want to keep the Objects distinct.

To create two distinct objects, you will need to perform a "deep" clone, which can be easily implemented in a helper method. The below code illustrates the importance of ensuring you fully clone the object before storing it in the history list.

    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;
    }

The output for executing this code is : NewOldNewNew whereas the "intended" output is "OldOldNewNew". From this you can see the shallowClonedMap was updated to "New" even after being cloned and added to the list.

Zachary
  • 1,693
  • 1
  • 9
  • 13