递归方法在某些分支上过早停止

时间:2014-01-30 21:31:07

标签: java recursion

我有以下递归方法在高度映射中创建一个山:

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);
    recursiveUpdate(heightMapping, traversed, x, z, startHeight, positive);
}

private void recursiveUpdate(final float[][] heightMapping, final boolean[][] traversed, final int x, final int z, final float startHeight, final boolean positive) {
    if (x < 0 || x >= width || z < 0 || z >= depth) {
        return;
    }
    if (traversed[x][z]) {
        return;
    }
    if ((positive && startHeight <= 0f) || (!positive && startHeight >= 0f)) {
        heightMapping[x][z] = 0f;
        return;
    }
    traversed[x][z] = true;
    heightMapping[x][z] = startHeight;
    recursiveUpdate(heightMapping, traversed, x - 1, z - 1, calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x - 1, z + 1, calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z - 1, calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z + 1, calculateNewStartHeight(startHeight, positive), positive);
}

private float calculateNewStartHeight(final float startHeight, final boolean positive) {
    float delta = random.nextFloat() * maxHeight / maxDecayFactor;
    return (positive) ? startHeight - delta : startHeight + delta;
}

这个想法是它从(x, z)开始,然后递归地降低周围单元格的值(左下/右下/左上/右上),看起来好像是跳过单元格,如以下输出所示:

0.0  0.5  0.0  0.5  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.5  0.0  0.9  0.0  0.3  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.1  0.0  0.0  0.0  0.3  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
1.8  0.0  0.9  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  2.4  0.0  0.8  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
3.6  0.0  0.8  0.0  0.9  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  4.4  0.0  1.2  0.0  0.7  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
3.5  0.0  2.3  0.0  0.7  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  2.5  0.0  1.1  0.0  0.6  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
1.4  0.0  0.4  0.0  0.4  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.2  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0    
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  

在左侧,略高于中间,您可以看到4.4,问题本身似乎非常明显,它没有为顶部/向下/向左/向右元素设置任何值,但我认为我的递归已经抓住了这个问题。

任何线索?

1 个答案:

答案 0 :(得分:1)

您没有计算顶部,底部,左侧和右侧的递归高度。你只计算角落。你只需要添加“非角落”,即。 (x,y)的递归方法的顶部,底部,左侧和右侧标记。

private void recursiveUpdate(final float[][] heightMapping, final boolean[][] traversed,
    final int x, final int z, final float startHeight, final boolean positive) {
    if (x < 0 || x >= width || z < 0 || z >= depth) {
        return;
    }
    if (traversed[x][z]) {
        return;
    }
    if ((positive && startHeight <= 0f) || (!positive && startHeight >= 0f)) {
        heightMapping[x][z] = 0f;
        return;
    }

    traversed[x][z] = true;
    heightMapping[x][z] = startHeight;
    //This will only calculate the corners of the (x,y point)
    recursiveUpdate(heightMapping, traversed, x - 1, z - 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x - 1, z + 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z - 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    recursiveUpdate(heightMapping, traversed, x + 1, z + 1, 
                    calculateNewStartHeight(startHeight, positive), positive);

    //Add top, bottom, left and right indicies for (x,y)
    //bottom
    recursiveUpdate(heightMapping, traversed, x, z - 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    //top
    recursiveUpdate(heightMapping, traversed, x, z + 1, 
                    calculateNewStartHeight(startHeight, positive), positive);
    //right
    recursiveUpdate(heightMapping, traversed, x + 1, z, 
                    calculateNewStartHeight(startHeight, positive), positive);
    //left
    recursiveUpdate(heightMapping, traversed, x - 1, z, 
                    calculateNewStartHeight(startHeight, positive), positive);
}