java中基于文本的撤销功能

问题描述 投票:-3回答:1

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

关于代码的背景信息:我使用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;
}
java arrays string arraylist undo
1个回答
0
投票

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

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

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

    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也已更新为“新建”。

© www.soinside.com 2019 - 2024. All rights reserved.