java中基于文本的撤销功能

时间:2017-12-23 23:51:30

标签: java arrays string arraylist undo

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

关于代码的背景信息:我使用String[][]存储迷宫,因为这是最简单的。我使用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;
}

1 个答案:

答案 0 :(得分:0)

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

要从Object获取值,通常需要克隆该对象(调用clone()方法)。然而,克隆二维阵列有些问题。在二维数组上调用clone()方法&#34;浅&#34;克隆对象,基本上只克隆第一个维度,同时将第二个维度作为对同一对象的引用(原因是数组的第一个1维持有对第二个维度的引用)。更改浅复制对象上的值将更改原始值,反之亦然,而不是您想要保持对象不同的所需值。

要创建两个不同的对象,您需要执行&#34; deep&#34; clone,可以在helper方法中轻松实现。下面的代码说明了在将对象存储到历史记录列表之前确保完全克隆对象的重要性。

    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而#34;意图&#34;输出是&#34; OldOldNewNew&#34;。从中您可以看到shallowClonedMap已更新为&#34; New&#34;即使在被克隆并添加到列表中之后。