我有以下递归函数,它应该调用自身,除非坐标超出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);
}
非常感谢任何帮助。
答案 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)
}
}