abnormal
The meaning of each number in the two-dimensional array is as follows:
Push box game, when you click the right mouse button, you will go back to the previous step.
Right click the mouse button and go back to the previous step. The map data is as follows. It is not the data in the initial state, because we require to go back to the previous step, and this time the data in the previous step is the initial state.
In other words, we didn't retreat successfully, and we drew an extra villain. What's going on?
We go back to the previous step by saving the map data of the previous step into the List set, and then taking the last element in the List set every time to obtain the data of the previous step. In fact, we use the stack to better understand the point, first in and last out, but this is not the focus.
Each stored data occurs before the move, and the code is as follows:
Map is a custom map class, which is used to store map data
public class Map { // The x and y coordinates of the current character int manX = 0, manY = 0; // Current map data byte[][] map; // Current levels int grade; /** * This construction method is used to undo the operation, which only needs the person's position and the current state of the map * * @param manX * @param manY * @param map */ public Map(int manX, int manY, byte[][] map) { this.manX = manX; this.manY = manY; this.map = map; } /** * This construction method is used to save the operation. When restoring the map, you need the person's position, the current state of the map and the number of levels * * @param manX * @param manY * @param map * @param grade */ public Map(int manX, int manY, byte[][] map, int grade) { this(manX, manY, map); this.grade = grade; } public int getManX() { return manX; } public void setManX(int manX) { this.manX = manX; } public int getManY() { return manY; } public void setManY(int manY) { this.manY = manY; } public byte[][] getMap() { return map; } public void setMap(byte[][] map) { this.map = map; } public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } }
In this move, only the data in the above red box changes, so we focus on them, from "9 2 5" to "2 6 9". We check the data changes through the debug mode:
View the map data content of map [] [] before moving
View the contents of map [] [] in the list collection before moving
After moving one step to the left, view the contents of the map [] [] array
After moving one step to the left, view the contents of map [] [] in the list set:
Note: the list set is used to save the map data of the previous step; Map [] [] two-dimensional array is the current map data, which will change with the movement.
Why? The culprit is map The Map(int, int, byte [] []) construct in the Java class, we know this The member variable map is a two-dimensional array, and the passed in formal parameter map is also a two-dimensional array, this Map = map is equivalent to directly passing in a reference. As the content of the formal parameter map changes, this Of course, the map will also change, because this The reference to map points to the passed in formal parameter map. This is a problem that is easy to ignore.
The solution is to traverse the data content of the formal parameter map, re create a temporary two-dimensional array of temp, copy all the data in the formal parameter map into temp, and then assign temp to this Map, which is value passing instead of reference passing. Naturally, the problem of failing back to the previous step will not occur.
/** * This construction method is used to undo the operation, which only needs the person's position and the current state of the map * * @param manX * @param manY * @param map */ public Map(int manX, int manY, byte[][] map) { this.manX = manX; this.manY = manY; // this.map = map;// bug code, do not use // Copy the map data directly to temp and assign it to this map int row = map.length; int column = map[0].length; byte[][] temp = new byte[row][column]; for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { temp[i][j] = map[i][j]; } } this.map = temp; }
Summary: when using an array as a member variable, do not pass a reference when initializing the value of the array in the method, but pass the value. Otherwise, when the content of the external array changes, the member variable array will also change.