递归程序崩溃了计算机

时间:2014-01-26 19:10:25

标签: javascript html algorithm recursion crash

我正在写一个迷宫发生器,我正在使用Dijkstra算法来查看我的迷宫分成多少部分。

我所做的是找到一个没有“标记”的单元格,并运行“wave”功能。

函数wave(row,column,marknumber):

1)我给这个细胞一个标记。 2)然后,对于没有被墙隔开的每个附近的单元格,我运行“wave”函数。

这个算法应该告诉我我的迷宫分成多少部分,而是我的电脑屏幕变白,开始闪烁,然后电脑关闭。

这是我的HTML:

<!DOCTYPE html>
<html>
    <head>
        <script src="/mazeGenerator.js"></script>
    </head>
    <body>
        <canvas id="field" width="300" height="300"></canvas>
        <script>
            var mark = 1;
            init();
            generateBase();
            var arsenalNum = window.prompt("How many arsenals?");
            for (var i=0;i<arsenalNum;i++) {
                arsenal();    
            }
            var prizeNum = window.prompt("How many prizes?");
            for (var i=0;i<prizeNum;i++) {
                prize(i+1);    
            }
            draw();
            for (var r=0; r<DIM; r++) {
                for (var c=0; c<DIM; c++) {
                    if (maze[r][c].mark === 0) {
                        draw();
                        //alert(" ");
                        wave(r,c,mark);
                        mark++;
                    }
                }
            }
            draw();
            alert("There are " + numberOfMarks() + " marks in this labyrinth.");
        </script>
    </body>
</html>

这是我的Javascript:

var DIM = window.prompt("Please choose a dimension.");
var maze = new Array (DIM);

// init();
// generate();
// draw();

function init() {
    for (var i=0;i<DIM;i++) {
        maze[i] = new Array (DIM);
        for (var j=0;j<DIM;j++) {
            maze[i][j] = {
                "walls":[0,0,0,0],
                "mark":0,
                "hole":-1,
                "arsenal":0,
                "prize":0,
                "blocks_arsenal_entrance":0
            };
        }
    }    
}

function generateBase() {
    for (var r=0;r<DIM;r++) {
        for (var c=0;c<DIM;c++) {
            var ind = Math.floor(Math.random()*4);
            addWall(r,c,ind);
            if (r === 0) {
                maze[r][c].walls[0] = 1;
            }
            if (c === (DIM-1)) {
                maze[r][c].walls[1] = 1;
            }
            if (r === (DIM-1)) {
                maze[r][c].walls[2] = 1;
            }
            if (c === 0) {
                maze[r][c].walls[3] = 1;
            }
        }
    }
}

function draw() {
    var canvas=document.getElementById("field");
    var ctx=canvas.getContext("2d");
    for (var r=0;r<DIM;r++) {
        for (var c=0;c<DIM;c++) {
            drawCell(r,c,ctx);
        }
    }
}

function drawCell(r,c,ctx) {
    var left = c*10;
    var top = r*10;
    var w = maze[r][c].walls;
    if (w[0] === 1) {
        ctx.moveTo(left,top);
        ctx.lineTo((left+10),top);
        ctx.stroke();
    }
    if (w[1] === 1) {
        ctx.moveTo((left+10),top);
        ctx.lineTo((left+10),(top+10));
        ctx.stroke();
    }
    if (w[2] === 1) {
        ctx.moveTo(left,(top+10));
        ctx.lineTo((left+10),(top+10));
        ctx.stroke();
    }
    if (w[3] === 1) {
        ctx.moveTo(left,top);
        ctx.lineTo((left),(top+10));
        ctx.stroke();
    }
    if (maze[r][c].arsenal == 1) {
        ctx.fillStyle = "#FF0000";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].prize !== 0) {
        ctx.fillStyle = "#00FF00";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 1) {
        ctx.fillStyle = "#FF00FF";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 2) {
        ctx.fillStyle = "#FFFF00";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 3) {
        ctx.fillStyle = "#00FFFF";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 4) {
        ctx.fillStyle = "#0080FF";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 5) {
        ctx.fillStyle = "#FF0080";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 6) {
        ctx.fillStyle = "#FFFFFF";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 7) {
        ctx.fillStyle = "#000000";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 8) {
        ctx.fillStyle = "#80FF80";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 9) {
        ctx.fillStyle = "#8080FF";
        ctx.fillRect(left,top,10,10);
    }
    if (maze[r][c].mark === 10) {
        ctx.fillStyle = "#FF8080";
        ctx.fillRect(left,top,10,10);
    }
}

function up(r,c) {
    if (r === 0) {
        return null;
    } else {
        return maze[r-1][c];
    }
}

function down(r,c) {
    if (r == (DIM - 1)) {
        return null;
    } else {
        return maze[r+1][c];
    }
}

function left(r,c) {
    if (c === 0) {
        return null;
    } else {
        return maze[r][c-1];
    }
}

function right(r,c) {
    if (c == (DIM - 1)) {
        return null;
    } else {
        return maze[r][c+1];
    }
}

function neighbor(r,c,dir) {
    if (dir === 0) {
        return up(r,c);
    }
    if (dir === 1) {
        return right(r,c);
    }
    if (dir === 2) {
        return down(r,c);
    }
    if (dir === 3) {
        return left(r,c);
    }
}

function opposite(dir) {
    if (dir === 0) {
        return 2;
    }
    if (dir === 1) {
        return 3;
    }
    if (dir === 2) {
        return 0;
    }
    if (dir === 3) {
        return 1;
    }
}

function arsenal() {
    var done = false;
    while (!done) {
        var r = Math.floor(Math.random()*DIM);
        var c = Math.floor(Math.random()*DIM);
        if (maze[r][c].prize !== 0) {
            continue;
        }

        if (maze[r][c].arsenal !== 0) {
            continue;
        }

        if (maze[r][c].blocks_arsenal_entrance !== 0) {
            continue;
        }

        var entrance = Math.floor(Math.random()*4);

        if ((r === 0) && (entrance === 0)) {
            entrance = opposite(entrance);
        }

        if ((c === (DIM - 1)) && (entrance === 1)) {
            entrance = opposite(entrance);
        }

        if ((r === (DIM - 1)) && (entrance === 2)) {
            entrance = opposite(entrance);
        }

        if ((c === 0) && (entrance === 3)) {
            entrance = opposite(entrance);
        }

        for (var d=0;d<4;d++) {
            removeWall(r,c,d);
        }

        for (d=0;d<4;d++) {
            if (d !== entrance) {
                addWall(r,c,d);
            }
        }
        neighbor(r,c,entrance).blocks_arsenal_entrance = 1;
        maze[r][c].arsenal = 1;
        done = true;

    }
}

function prize(n) {
    var done = false;
    while (!done) {
        var r = Math.floor(Math.random()*DIM);
        var c = Math.floor(Math.random()*DIM);

        if (maze[r][c].prize !== 0) {
            continue;
        }

        if (maze[r][c].arsenal !== 0) {
            continue;
        }

        if (maze[r][c].blocks_arsenal_entrance !== 0) {
            continue;
        }

        for (var d=0;d<4;d++) {
            addWall(r,c,d);
        }

        maze[r][c].prize = n;
        done = true;

    }
}

function addWall(r,c,ind) {
    maze[r][c].walls[ind] = 1;
    if (neighbor(r,c,ind) !== null) {
        neighbor(r,c,ind).walls[opposite(ind)] = 1;
    }
}

function removeWall(r,c,dir) {
    maze[r][c].walls[dir] = 0;
    var neighborCell = neighbor(r,c,dir);
    if (neighborCell !== null) {
        neighborCell.walls[opposite(dir)] = 0;
    }
}

function wave(r,c,mark) {
    //alert("Wave Started with " + r + ", " + c + ".");
    if (maze[r][c].mark === 0) {//Make sure the cell doesn't have a mark
        // alert(r + ", " + c + " does not have a mark.");
        maze[r][c].mark = mark;
        // alert("maze["+r+"]["+c+"].mark is now equal to " + maze[r][c].mark);
        if ((maze[r][c].walls[0] === 0) && (up(r,c).mark === 0)) {
            wave((r-1),c);
        }
        if ((maze[r][c].walls[1] === 0) && (right(r,c).mark === 0)) {
            wave(r,(c+1));
        }
        if ((maze[r][c].walls[2] === 0) && (down(r,c).mark === 0)) {
            wave((r+1),c);
        }
        if ((maze[r][c].walls[3] === 0) && (left(r,c).mark === 0)) {
            wave(r,(c-1));
        }
    } else {

    }
}

function numberOfMarks() {
    var maxMark = 0;
    for (var r=0;r<DIM;r++) {
        for (var c=0;c<DIM;c++) {
            if ((maze[r][c].mark) > maxMark) {
                maxMark = maze[r][c].mark;
            }
        }
    }
    return maxMark;
}

function numberOfPrizes() {
    var maxPrize = 0;
    for (var r=0;r<DIM;r++) {
        for (var c=0;c<DIM;c++) {
            if ((maze[r][c].prize) > maxPrize) {
                maxPrize = maze[r][c].prize;
            }
        }
    }
    return maxPrize;
}

function findMarkBorder() {
    for (var r=0;r<DIM;r++) {
        for (var c=0;c<DIM;c++) {
            if (((maze[r][c].mark) !== up(r,c).mark) && (up(r,c).mark !== null)) {
                document.write("<br> The cell above cell "+r+", "+c+" has a different mark.");
            }
            if (((maze[r][c].mark) !== right(r,c).mark) && (right(r,c).mark !== null)) {
                document.write("<br> The cell to the right of cell "+r+", "+c+" has a different mark.");
            }
            if (((maze[r][c].mark) !== down(r,c).mark) && (down(r,c).mark !== null)) {
                document.write("<br> The cell below cell "+r+", "+c+" has a different mark.");
            }
            if (((maze[r][c].mark) !== left(r,c).mark) && (left(r,c).mark !== null)) {
                document.write("<br> The cell to the left of cell "+r+", "+c+" has a different mark.");
            }
        }
    }   
}

请告诉我我做错了什么!提前谢谢!

1 个答案:

答案 0 :(得分:1)

这个程序不起作用,因为在函数wave中,你没有传递足够的参数 - 你没有传递“标记”。

例如,

    if ((maze[r][c].walls[3] === 0) && (left(r,c).mark === 0)) {
        wave(r,(c-1));
    }

应该是

    if ((maze[r][c].walls[3] === 0) && (left(r,c).mark === 0)) {
        wave(r,(c-1),mark);
    }