【发布时间】:2014-01-08 00:01:31
【问题描述】:
正如我之前的问题here 所述,我正在尝试编写游戏AI。目前,我有一个循环遍历单元格的邻居,生成可能移动的列表。在这个循环中的某个点(它是高度递归的),我声明了一个新的DotMove 对象,它存储了该特定移动的信息。然后,此移动将附加到不断增长的移动列表中。
每一步都有一个有序的点列表,这些点被认为是“路径”。
不幸的是,这些DotMove 对象似乎没有正确保存对路径的引用。具体来说,当我去打印生成的DotMove 对象的路径时,这些路径只返回一个项目。 (路径应该有几个项目,并且随着列表的打印而变化。)
List<Edge> e = getEdgesAt(p, con);
ArrayList<DotMove> moveList = new ArrayList<DotMove>();
for (Edge edge : e) {
if (visited.add(edge)) {
Point next = edge.getNextPoint(p);
path.add(next);
findMovesAtPointHelper(next, path, connected, visited);
moveList.add(new DotMove(path, this));
}
}
path.remove(path.size() - 1);
return moveList;
产生以下输出:
r r b g r g r g
r r b g y r r b
b r b g b r r p
b r b b g r r r
b r b r r r b r
r b b p r p b b
p r y y g g b b
p y r b y p b r
[(0, 0)]
[(0, 1)]
[(1, 0)]
[(1, 1)]
[(1, 2)]
[(1, 2)]
[(1, 2)]
但是,当我将 moveList.add(...) 替换为当时打印路径的语句时,我得到以下(正确)输出:
r r b g r g r g
r r b g y r r b
b r b g b r r p
b r b b g r r r
b r b r r r b r
r b b p r p b b
p r y y g g b b
p y r b y p b r
[(0, 0), (0, 1), (1, 1), (1, 0)]
[(0, 0), (0, 1), (1, 1)]
[(0, 0), (0, 1), (1, 1), (1, 2), (1, 3)]
[(0, 0), (0, 1), (1, 1), (1, 2)]
[(0, 0), (0, 1), (1, 1)]
[(0, 0), (0, 1)]
[(0, 0)]
我相信这种差异是由我的 DotMove 构造函数和它调用的 Path 构造函数引起的。这两个已包含在此处以供参考。
public DotMove(ArrayList<Point> path, BoardModel boardModel) {
this.path = new Path(path);
this.cleared = path;
this.score = path.size();
}
public Path(List<Point> path){
this.path = new ArrayList<Point>(path);
}
Path() 构造函数似乎保留了对整个列表的引用,而不是制作列表的浅表副本。这可以解释为什么DotMove 对象内的列表更短,因为移动查找算法依赖于在遍历棋盘时从列表末尾删除项目。 DotMove 对象旨在存储此列表的“快照”,而不是对列表本身的引用。
如何正确创建此列表的浅表副本?
【问题讨论】:
-
看看
java.util.Collections类的静态方法copy- docs.oracle.com/javase/7/docs/api/java/util/…, java.util.List)。 -
我刚试过这个,它给了我包含零个元素的列表。
-
看来您需要先创建具有 相同大小的
ArrayList。new ArrayList<Point>(path.size); -
这让我感到困惑,为什么您的原始方法不起作用。您确定您找到了要修复的正确位置吗?
-
我确实首先创建了一个适当大小的目标数组,但仍然没有运气。我也很困惑。我目前正在查看其他地方是否存在错误
标签: java list recursion shallow-copy