javascript递归函数落入无限循环

时间:2016-06-03 19:45:54

标签: javascript recursion

我有以下递归函数,它应该调用自身,除非坐标超出DOM表,或者除非起始点和当前递归点之间的距离大于用户给出的距离。然而,功能在几个点之间无限循环无限循环切换,我无法弄清楚我做错了什么。

function fillSquare(a,b,dist){
    var xStart = parseInt(a);
    var yStart = parseInt(b);
    var distance = dist;

    function fill(c,d){
        var x = parseInt(c);
        var y = parseInt(d);

        if(x<0 || y<0 || x>boardWidth-1 || y>boardHeight-1){
            return;
        }else if(getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(x,y)]) > dist){
            return;
        }else{
            cells[getFieldId(x,y)].hasWall = false;
            document.getElementById(x+'x'+y).backgroundColor = 'gray';
            console.log(x+' '+y);

            fill(x-1,y);
            fill(x+1,y);
            fill(x,y-1);
            fill(x,y+1);
        }
    }

    fill(xStart,yStart);
}

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

问题是递归调用将返回相同的元素。例如,当您执行fill(4, 5)时,会调用fill(x-1, y),即fill(3, 5)。然后调用fill(x+1, y),后者返回fill(4, 5)。它会在它们之间保持循环。

你需要检查你是否已经填充了一个元素,而不是重复它。

function fill(c,d){
    var x = parseInt(c);
    var y = parseInt(d);

    if(cells[getFieldId(x, y)].hasWall === false || x<0 || y<0 || x>boardWidth-1 || y>boardHeight-1){
        return;
    }else if(getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(x,y)]) > dist){
        return;
    }else{
        cells[getFieldId(x,y)].hasWall = false;
        document.getElementById(x+'x'+y).backgroundColor = 'gray';
        console.log(x+' '+y);

        fill(x-1,y);
        fill(x+1,y);
        fill(x,y-1);
        fill(x,y+1);
    }
}

答案 1 :(得分:0)

由于我没有其他代码,因此控制台的输出是什么:

// for debugging
var i = 0;

// helper function to parse into integers
function fillSquare(xStart, yStart, distance)
{
    // kick it off
    // on the first run the current is the start
    fill(parseInt(xStart), parseInt(yStart), parseInt(xStart), parseInt(yStart), distance);
}

function fill(xCurrent, yCurrent, xStart, yStart, distance)
{
    // the next two lines are temporary just for debugging purposes
    ++i;
    if(i > 100) return;

    // log where we are so we can see progress
    console.log({ "xCurrent" : xCurrent, "yCurrent" : yCurrent, "xStart" : xStart, "yStart" : yStart, "distance" : distance, "getDistance" : getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(xCurrent, yCurrent)]) });

    // no need to parse since you did that on the initial run and the recursive calls are all basic math

    if(xCurrent < 0 || yCurrent < 0 || xCurrent > boardWidth - 1 || yCurrent > boardHeight - 1)
    {
        return;
    }
    else if(getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(xCurrent, yCurrent)]) > distance)
    {
        return;
    }
    else
    {
        cells[getFieldId(xCurrent,yCurrent)].hasWall = false;
        document.getElementById(xCurrent + 'x' + yCurrent).backgroundColor = 'gray';

        fill(xCurrent - 1, yCurrent, xStart, yStart, distance)
        fill(xCurrent + 1, yCurrent, xStart, yStart, distance)
        fill(xCurrent, yCurrent - 1, xStart, yStart, distance)
        fill(xCurrent, yCurrent + 1, xStart, yStart, distance)
    }
}