JavaScript迷宫求解算法
HTMLJavaScript迷宫求解算法,javascript,html,maze,Javascript,Html,Maze,HTML <div id="labirinth"> <form style="text-align:center" name="forma1" autocomplete="on"> <table style="margin:0 auto;"> <tr> <td style="float:right;">Height:</td>
<div id="labirinth">
<form style="text-align:center" name="forma1" autocomplete="on">
<table style="margin:0 auto;">
<tr>
<td style="float:right;">Height:</td>
<td><input type="text" id="height" name="height" autofocus="autofocus" maxlength="2" size="6" /></td>
</tr>
<tr>
<td style="float:right;">Width:</td>
<td><input type="text" id="width" name="width" maxlength="2" size="6" /></td>
</tr>
</table>
</form>
<input type="button" alt="submit" onClick="datas();" value="New" style="margin-top:10px;" />
</div>
<pre id="out"></pre>
高度:
宽度:
JavaScript
function datas() {
var height = parseInt(document.getElementById("height").value);
var width = parseInt(document.getElementById("width").value);
document.getElementById('out').innerHTML = display(maze(height,width));
}
function maze(x,y) {
var n=x*y-1;
if (n<0) {alert("Bad numbers!");return;}
var horiz=[];
for (var j= 0; j<x+1; j++) horiz[j]= [];
var verti=[];
for (var j= 0; j<y+1; j++) verti[j]= [];
var here= [Math.floor(Math.random()*x), Math.floor(Math.random()*y)];
var path= [here];
var unvisited= [];
for (var j= 0; j<x+2; j++) {
unvisited[j]= [];
for (var k= 0; k<y+1; k++)
unvisited[j].push(j>0 && j<x+1 && k>0 && (j != here[0]+1 || k != here[1]+1));
}
while (0<n) {
var potential= [[here[0]+1, here[1]], [here[0],here[1]+1],
[here[0]-1, here[1]], [here[0],here[1]-1]];
var neighbors= [];
for (var j= 0; j < 4; j++)
if (unvisited[potential[j][0]+1][potential[j][1]+1])
neighbors.push(potential[j]);
if (neighbors.length) {
n= n-1;
next= neighbors[Math.floor(Math.random()*neighbors.length)];
unvisited[next[0]+1][next[1]+1]= false;
if (next[0] == here[0])
horiz[next[0]][(next[1]+here[1]-1)/2]= true;
else
verti[(next[0]+here[0]-1)/2][next[1]]= true;
path.push(here= next);
} else
here= path.pop();
}
return ({x: x, y: y, horiz: horiz, verti: verti});
}
function display(m) {
var text= [];
for (var j= 0; j<m.x*2+1; j++) {
var line= [];
if (0 == j%2)
for (var k=0; k<m.y*4+1; k++)
if (0 == k%4)
line[k]= 'X';
else
if (j>0 && m.verti[j/2-1][Math.floor(k/4)])
line[k]= ' ';
else
line[k]= 'X';
else
for (var k=0; k<m.y*4+1; k++)
if (0 == k%4)
if (k>0 && m.horiz[(j-1)/2][k/4-1])
line[k]= ' ';
else
line[k]= 'X';
else
line[k]= ' ';
if (0 == j) line[1]=line[3]=' ',line[2]= '1';
if (m.x*2-1 == j) line[4*m.y]= '2';
text.push(line.join('')+'\r\n');
}
return text.join('');
}
函数数据(){
var height=parseInt(document.getElementById(“height”).value);
var width=parseInt(document.getElementById(“width”).value);
document.getElementById('out').innerHTML=display(迷宫(高度、宽度));
}
功能迷宫(x,y){
var n=x*y-1;
如果(n我建议使用Dijkstra算法来解决您正在生成的迷宫。虽然我不确定horiz和verti参数如何定义迷宫结构,但Dijkstra的算法将在您的情况下工作,从“1”旁边的单元格开始,从那里开始构建
其操作方式是在每个单元和起始单元之间标记单元数量。对于3x3迷宫,第一个单元应为:
x 1 xxxxxxxxx
x 1 x
x xxxxxxxxx
x x
x xxxxxxxxx
x 2
xxxxxxxxxxxxx
从标记的单元格开始工作检查是否有空的相邻单元格(未被墙阻挡的单元格),将单元格值增加1。对所有空单元格重复此过程:
x 1 xxxxxxxxx
x 1 2 3 x
x xxxxxxxxx
x 2 3 4 x
x xxxxxxxxx
x 3 4 5 2
xxxxxxxxxxxxx
现在,从“2”端附近的单元格向后操作。这表明解决方案的路径长度为5步,因此从5开始,找到相邻的4步,然后找到3步,以此类推,返回到1
注意:我建议使用队列来标记单元格的递归解决方案:
1-用“1”标记第一个单元格,并将其放入队列中
2-从队列中提取单元格:
-检查合法邻居(未被墙阻挡的邻居)是否未标记。
-如果相邻单元格未标记,则使用当前单元格+1标记它。
-将相邻单元格添加到队列中。
-对所有4个潜在邻居重复上述步骤
3-重复步骤1和2,直到不再有未标记的单元格
编辑:下面是使用我建议的解算器的示例,它与问题中的迷宫生成器无关,因此除非有人问,否则我不会详细介绍它的操作方式(有点粗糙,但它的实现应该很容易理解)。如果它是一个完美的迷宫(任何两个单元格之间只有一条路径)然后你只需要一个递归的墙跟随器。从第一个单元格开始,按照给定的顺序检查周围的所有单元格,通常是顺时针或逆时针。如果可以输入单元格,则输入。如果是结束,则完成。如果不是,则递归。当你检查了所有3条其他路径,但没有一条路径是结束时,只需返回。当你到达e您的调用堆栈有解决方案:)我通常会为“我没有在这里找到解决方案”返回“false”,为“这就是解决方案”返回“true”
您可以在github上看到我如何在迷宫算法中求解:
如果查看jsmaze2.html,函数“find_depth”实际上是一个解算器
jsmaze4.html要复杂得多,但它实际上是在使用递归算法构建迷宫时构建解决方案的。它通过跟踪在构建过程中“进入”单元格时撞倒的墙来实现这一点。由于还有其他算法,我还包括了“查找深度”(find_depth),它为任何迷宫设置入口墙
这就足够让你开始了。非递归的方法可以帮你解决这个迷宫。使用递归(回溯算法),你可能会走运
请参阅本文件:-
如果这个问题将开放到周末。我会发布一个编码的答案
谢谢你能把它做成一个JS fiddle让我们看看这里发生了什么吗?完成了,JS fiddle指的是网站jsfiddle:-Psorry,但我不知道为什么它在jsfiddle上不起作用,但在jsbin上是的。你正在寻找一个。我链接的wiki可能会帮助你开始。看起来很有趣!祝你好运!很棒的答案。悬赏是为了实现但是我已经用这个建议走了很长一段路,所以如果没有其他人在到期前插话,我会把奖金奖励给你。非常感谢。@elzi我不能完全理解horzi和verti参数定义迷宫结构的复杂方式,否则我会提供一个实现。不过,如果有兴趣,我仍然可以迷宫结构将在一个2D数组中定义。老实说,我会举任何javascript迷宫解决的例子。不必对这个迷宫生成器(我不特别喜欢,更喜欢画布)有特殊要求。要么我的google fu很糟糕,要么没有完整的例子。@elzi Simple solver补充道,如果你需要任何解释,请告诉我。