java中基于文本的撤销功能

java中基于文本的撤销功能,java,arrays,string,arraylist,undo,Java,Arrays,String,Arraylist,Undo,我正试图找出一个小迷宫游戏的撤销功能。首先,我找到了一种方法,通过检查最后一个方向是什么,然后朝相反的方向返回。但这段代码太长了,因为我还必须追踪可能的物品拾取或隐藏墙等 关于代码的背景信息:我使用字符串[][]来存储迷宫,因为这是最简单的。我使用Arraylist存储所有字符串。 在播放器执行每一步后,我将字符串[]【】数组保存到arraylist中。当播放机说undo时,我查看arraylist中最后一个字符串[]【】,希望将字符串[]【】【】设置回该值。但当前的POS似乎从未更新过。我不确

我正试图找出一个小迷宫游戏的撤销功能。首先,我找到了一种方法,通过检查最后一个方向是什么,然后朝相反的方向返回。但这段代码太长了,因为我还必须追踪可能的物品拾取或隐藏墙等

关于代码的背景信息:我使用
字符串[][]
来存储迷宫,因为这是最简单的。我使用
Arraylist
存储所有字符串。 在播放器执行每一步后,我将
字符串[]【】
数组保存到arraylist中。当播放机说undo时,我查看arraylist中最后一个
字符串[]【】
,希望将
字符串[]【】【】
设置回该值。但当前的POS似乎从未更新过。我不确定问题出在哪里

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

在不了解您设置历史的方式的情况下,我根据您的问题假设您只是将当前地图添加到历史列表中。如果不小心,只需添加同一个对象,使用对当前映射状态的多个对象引用填充历史。这将产生在状态不变的情况下观察到的效果,因为历史记录只包含对最新地图的引用(不存储任何实际的历史记录

要从对象获取值,通常需要克隆对象(调用clone()方法)。然而,克隆二维数组有些问题。在二维数组“浅”上调用clone()方法克隆对象,实际上只克隆第一个维度,而将第二个维度作为对同一对象的引用(原因是数组的第一个一维包含对第二个一维的引用)。更改浅复制对象上的值将更改原始对象的值,反之亦然,而不是您希望保持对象不同的值

要创建两个不同的对象,您将需要执行一个“深层”克隆,这可以在助手方法中轻松实现。下面的代码说明了在将对象存储在历史记录列表中之前确保完全克隆该对象的重要性

    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;
    }
publicstaticvoidmain(字符串args[])引发异常{
ArrayList=新建ArrayList();
字符串[][]shallowClonedMap=新字符串[1][1];
字符串[][]deepClonedMap=新字符串[1][1];
shallowClonedMap[0][0]=“旧”;
deepClonedMap[0][0]=“旧”;
添加(shallowClonedMap.clone());
添加(deepClone(deepClonedMap));
shallowClonedMap[0][0]=“新建”;
deepClonedMap[0][0]=“新建”;
添加(shallowClonedMap.clone());
添加(deepClone(deepClonedMap));
对于(字符串[][]项:列表){
系统输出打印(项目[0][0]);
}
}
公共静态字符串[][]deepClone(字符串[][]arry){
if(arry==null){
返回null;
}
字符串[][]克隆=新字符串[arry.length][];
对于(int i=0;i

执行此代码的输出为:newoldnew,而“预期”输出为“oldnew”。由此,您可以看到shallowClonedMap即使在被克隆并添加到列表中后也被更新为“新建”。

您有问题吗?您是否在调试器中逐步完成了代码?为什么它不工作,如何使其工作?在我看来,这应该确保currentPos与以前一样,但事实并非如此。我确实在很多地方添加了打印功能。没有经过真正的调试。这些照片基本上都是一样的。我们几乎不可能为你调试这个:历史是否被正确保存?它是否曾经到达.equals(“undo”)if语句?