【问题标题】:text based undo function in javajava中基于文本的撤消功能
【发布时间】:2018-06-06 00:31:07
【问题描述】:

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

代码的背景信息:我使用String[][] 来存储迷宫,因为这是最简单的。我使用Arraylist<String[][]> 来存储所有字符串。 在玩家执行每一步后,我将String[][] 数组保存到数组列表中。当玩家说撤消时,我查看数组列表中倒数第二个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;
}

【问题讨论】:

  • 您有问题吗?
  • 您是否在调试器中单步执行了代码?
  • 为什么它不起作用,我该如何让它起作用?在我看来,这应该确保 currentPos 又是以前的样子,但事实并非如此。
  • 我确实在很多地方添加了打印功能。没有通过真正的调试器。印刷品基本上是一样的。
  • 我们几乎不可能为您调试此问题:历史记录是否正确保存?它是否曾经到达 .equals("undo") if 语句?

标签: java arrays string arraylist undo


【解决方案1】:

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

要从对象中获取值,您通常需要克隆对象(调用 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;
    }

执行此代码的输出是:NewOldNewNew,而“预期”输出是“OldOldNewNew”。从这里你可以看到即使在被克隆并添加到列表之后, shallowClonedMap 也被更新为“New”。

【讨论】:

    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 2013-10-03
    • 2011-08-07
    • 2012-07-30
    • 2021-08-05
    相关资源
    最近更新 更多