我正在尝试使用javascript(深度优先搜索算法)生成迷宫。我已经阅读了很多有关DFS算法的内容。但是我在生成迷宫方面遇到了困难。生成的迷宫看起来根本不像迷宫。我试图遵循非常基本的使用堆栈来保持记录的路径,以创建一个迷宫。我有两个文件maze.js
和另一个index.html
来显示迷宫的输出。
以下是maze.js
function Cell(center) {
this.center_cell = center;
this.neighbours = null;
this.visited = false;
// top, right, bottom, left neighbours, 1
// means the wall in between has been
// removed
this.walls = [ 0, 0, 0, 0 ];
this.last_selected_neigh = null;
this.calc_neighbours = function() {
var n_top = [ this.center_cell[0], this.center_cell[1] - 1 ];
var n_right = [ this.center_cell[0] + 1, this.center_cell[1] ];
var n_bottom = [ this.center_cell[0], this.center_cell[1] + 1 ];
var n_left = [ this.center_cell[0] - 1, this.center_cell[1] ];
this.neighbours = new Array(n_top, n_right, n_bottom, n_left);
// console.log(this.neighbours);
return this.neighbours;
};
this.set_visited = function() {
this.visited = true;
};
this.get_visited = function() {
return this.visited;
};
this.get_neighbours = function() {
return this.calc_neighbours();
};
this.get_random_neighbour = function() {
this.calc_neighbours();
var rand_neigh = Math.floor(Math.random() * 4);
this.last_selected_neigh = rand_neigh;
// break the walls that is in-between this cell and other neighbour
// this.walls[rand_neigh] = 1;
return this.neighbours[rand_neigh];
};
this.get_walls = function() {
return this.walls;
};
this.remove_wall = function() {
this.walls[this.last_selected_neigh] = 1;
};
};
var maze = {
width : null,
height : null,
cells : [],
build : function(width, height) {
this.width = width;
this.height = height;
return this;
},
get_width : function() {
return this.width;
},
get_height : function() {
return this.height;
},
put_cell : function(x, y, item) {
this.cells[x][y] = item;
},
pop_cell : function() {
this.cells.pop();
},
init : function() {
for ( var y = 0; y < this.get_height(); y++) {
// cell_pos = new Array();
for ( var x = 0; x < this.get_width(); x++) {
this.cells[x] = new Array();
this.cells[x][y] = new Array();
}
}
return this;
},
begin : function() {
// initialize the empty cells
this.init();
var randomCell = [ Math.floor(Math.random() * this.get_height()),
Math.floor(Math.random() * this.get_width()) ];
var cell = new Cell(randomCell);
var total_cells = this.width * this.height;
var total_visits = 1;
var stack = [];
cell.set_visited();
stack.push(cell);
while (total_visits <= total_cells) {
var random_pos = cell.get_random_neighbour();
var r_x = random_pos[0];
var r_y = random_pos[1];
var random_neighbour = new Cell(random_pos);
// get all neighbours
random_neighbour.calc_neighbours();
if (random_neighbour.get_visited() == false) {
// this.cells.push(cell);
if (r_x > -1 && r_x < this.get_width() && r_y > -1
&& r_y < this.get_height()) {
stack.push(random_neighbour);
random_neighbour.set_visited();
cell.remove_wall();
this.put_cell(r_x, r_y, cell);
cell = random_neighbour;
}
// Set the currently selected random neighbour as current cell
} else {
cell = stack.pop();
}
// Update the visit counter
total_visits++;
}
// console.log(this.get_all_cells());
},
get_cell : function(x, y) {
return this.cells[x][y];
},
get_all_cells : function() {
return this.cells;
},
draw : function() {
$table = $('<tbody></tbody>');
for ( var y = 0; y < this.height; y++) {
$tr = $('<tr></tr>');
$table.append($tr);
for ( var x = 0; x < this.width; x++) {
$td = $('<td> </td>');
$tr.append($td);
if (this.get_cell(x, y) != undefined) {
var cur_cell = this.get_cell(x, y);
// console.log(cur_cell.center_cell);
if (typeof cur_cell == "object") {
if (cur_cell.visited
&& cur_cell.center_cell[0] < this.get_width()
&& cur_cell.center_cell[0] > -1
&& cur_cell.center_cell[1] > -1
&& cur_cell.center_cell[1] < this.get_height()) {
var walls = cur_cell.get_walls();
// console.log(cur_cell);
// / console.log(walls);
if (walls[0] == 0) {
$td.css({
'border-top' : '2px solid #000'
});
}
if (walls[1] == 0) {
$td.css('border-right', '2px solid #000');
}
if (walls[2] == 0) {
$td.css('border-bottom', '2px solid #000');
}
if (walls[3] == 0) {
$td.css('border-left', '2px solid #000');
}
// console.log(walls_bound);
}
}
}
}
}
$("#maze").html($table);
}
}
以下是index.html
的代码:
<html>
<head>
<title>Maze</title>
<script src="lib/jquery.js"></script>
<script src="src/maze.js"></script>
<style type="text/css">
#maze {
border:2px solid #000;
border-spacing:0;
border-collapse:collapse;
}
#maze td {
/* border:2px solid #000; */
width: 20px;
height: 20px;
}
#maze tr {
height:20px;
}
</style>
</head>
<body>
<table id="maze" cellspacing="1" cellpadding="1">
</table>
<script>
var m = maze.build(4,4);
m.begin();
m.draw();
</script>
</body>
</html>
我得到的输出非常不同,甚至看起来都不像迷宫。这被认为是非常基本的算法。
我的问题:
cell=stack.pop
中保留断点,似乎它永远不会到达那里。提前谢谢。
答案 0 :(得分:0)
@Phpdna:谢谢你的努力。
我现在对代码进行了细微的修改
this.calc_neighbours = function() {
var pot = [[ this.center_cell[0] + 1, this.center_cell[1] ],
[ this.center_cell[0], this.center_cell[1] + 1 ],
[ this.center_cell[0] - 1, this.center_cell[1]],
[ this.center_cell[0], this.center_cell[1] - 1 ]];
for(var l=0;l<4;l++) {
if (pot[l][0] > -1
&& pot[l][0] < maze.height
&& pot[l][1] > -1
&& pot[l][1] < maze.width) {
//this.neighbours = new Array(n_top, n_right, n_bottom, n_left);
this.neighbours.push(pot[l]);
}
}
// Inline function to reset the indexes
function startFromZero(arr) {
var newArr = [];
var count = 0;
for (var i in arr) {
newArr[count++] = arr[i];
}
return newArr;
}
this.neighbours = startFromZero(this.neighbours);
console.log(this.neighbours);
//if(n_top > -1 && n_bottom < maze.height-1 && n_left>-1 && n_right < maze.width-1 && this.visited==false){
// this.neighbours = new Array(n_top, n_right, n_bottom, n_left);
// }
// console.log(this.neighbours);
return this.neighbours;
}
我现在有以下输出:
正如您在图片中看到的那样,生成的输出非常奇怪,看起来根本不像迷宫。 :(