所以我想解决上一篇文章中描述的问题:Terrain/Mountain algorithm not working as intended。问题的副本如下:
我想创建一个山上的地形,使用一个非常基本的原理,由这个高度映射显示:
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 2 1 0 0 0 0
0 0 0 1 2 3 2 1 0 0 0
0 0 1 2 3 4 3 2 1 0 0
0 0 0 1 2 3 2 1 0 0 0
0 0 0 0 1 2 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
它从height = 4
随机点开始,然后逐渐减少邻居。
递归的想法很简单,我开始一点,用height - 1
(在这个例子中)递归到上/下/左/右,并且只有在没有遇到的情况下,我才设置它们的值。
所以我继续用BFS实现它:
private void createMountain(final float[][] heightMapping, final float startHeight) {
boolean[][] traversed = new boolean[width][depth];
boolean positive = (startHeight >= 0f);
int x = random.nextInt(width);
int z = random.nextInt(depth);
PriorityQueue<QueueElement> priorityQueue = new PriorityQueue<>((o1, o2) -> (int)Math.signum(o1.height - o2.height));
priorityQueue.offer(new QueueElement(x, z, startHeight));
while (!priorityQueue.isEmpty()) {
QueueElement current = priorityQueue.poll();
if (current.x < 0 || current.x >= width || current.z < 0 || current.z >= depth) {
continue;
}
if (traversed[current.x][current.z]) {
continue;
}
if ((positive && current.height <= 0f) || (!positive && current.height >= 0f)) {
continue;
}
heightMapping[x][z] = current.height;
priorityQueue.offer(new QueueElement(x, z - 1, calculateNewHeight(current.height, positive)));
priorityQueue.offer(new QueueElement(x, z + 1, calculateNewHeight(current.height, positive)));
priorityQueue.offer(new QueueElement(x - 1, z, calculateNewHeight(current.height, positive)));
priorityQueue.offer(new QueueElement(x + 1, z, calculateNewHeight(current.height, positive)));
}
}
private class QueueElement {
public int x, z;
public float height;
public QueueElement(final int x, final int z, final float height) {
this.x = x;
this.z = z;
this.height = height;
}
}
private float calculateNewHeight(final float startHeight, final boolean positive) {
float delta = startHeight / maxDecayFactor;
return (positive) ? startHeight - delta : startHeight + delta;
}
现在代码永远不会停止,我尝试了几次调试,但要么没有有用的结果,要么是完全平坦的地形。
我目前唯一真正的线索是priorityQueue.size()
一直在增加3
有没有人知道发生了什么?
更新:即使在修复后,它仍然没有按预期工作。
0.6 0.5 0.4 0.3 0.3 0.2 0.2 0.1 0.1 0.1 0.1 0.1 0.0 0.0 0.0 0.0
0.8 1.0 1.2 1.6 1.9 2.4 3.0 3.8 4.7 5.9 7.4 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
可能出现什么问题? PriorityQueue
现在搞砸了吗?
答案 0 :(得分:4)
您在轮询新元素时忘记设置traversed[x][z] = true;
。
确保在查询if (traversed[current.x][current.z]) ...
另外,作为旁注,对于您的实施 - 我认为Queue
会更好。 (当我写一个PriorityQueue会更好我心中有多个峰值 - 对你来说似乎不是这样,我认为一个简单的队列将是最好的。)