기사 디렉토리
사진 발표
인터페이스가 정말 추합니다
입력 형식 미로 : 통로, 0 벽, 숫자 사이에 공백으로 구분, 각 행 -
간격
암호
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body,
html {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 0;
}
div#content {
display: inline-block;
border: 1px solid black;
position: relative;
}
div#content .child {
box-sizing: border-box;
display: inline-block;
width: 100px;
height: 100px;
border: 1px solid black;
}
div.wall {
background-color: #362E3D;
}
div#position {
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
background: #362E3D;
left: 40px;
top: 40px;
}
</style>
</head>
<body>
<div id="content">
<div id="position" style="left: 40px;top: 40px;"></div>
</div>
<script>
let map = reLoad(), // 地图录入
re = [], // 标记
road = [], // 路径
count = 0;
let m = map[0].length, //列
n = map.length; // 行
for (let i = 0; i < n; i++) {
let newarr = [];
for (let j = 0; j < m; j++) {
newarr.push(0);
}
re.push(newarr);
}
document.getElementById('content').style.width = m * 100 + "px";
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
let div = document.createElement('div');
div.className = 'child';
if (map[i][j] == 0)
div.className += ' wall';
document.getElementById('content').appendChild(div);
}
}
function dfs(x, y) {
if (x < 0 || x > n - 1 || y < 0 || y > m - 1 || re[x][y] == 1 || map[x][y] == 0) return 0; //走出界外或之前走过或遇到障碍
count++;
if (arguments[2])
road.push(arguments[2]);
if (x == n - 1 && y == m - 1) {
recallMark(arguments[2]);
return 1; //走到终点
}
re[x][y] = 1; //该点标记为走过
dfs(x - 1, y, 'top'); //向上走
dfs(x, y + 1, 'right'); //向右走
dfs(x + 1, y, 'down'); //向下走
dfs(x, y - 1, 'left'); //向左走
if (!(x == 0 && y == 0)) // 最后一次回溯在起点不记录
recallMark(arguments[2]); // 记录回溯路径
re[x][y] = 0; //该点还原为没有走过
}
function recallMark(act) {
switch (act) {
case 'top':
act = 'down';
break;
case 'right':
act = 'left';
break;
case 'down':
act = 'top';
break;
case 'left':
act = 'right';
break;
}
road.push(act);
}
function reLoad() {
let str = prompt("输入地图 用-间隔");
let arr = str.split('-');
let map = [];
for (let i = 0; i < arr.length; i++) {
map.push(arr[i].trim().split(' ').map(Number));
}
return map; // 返回二维数组
}
function draw() {
let div = document.getElementsByClassName('child');
let pos = document.getElementById('position');
let i = 0,
flag = 1;
let timer = setInterval(() => {
if (road[i] == 'right') {
pos.style.left = parseInt(pos.style.left) + 100 + 'px';
}
if (road[i] == 'down') {
pos.style.top = parseInt(pos.style.top) + 100 + 'px';
}
if (road[i] == 'left') {
pos.style.left = parseInt(pos.style.left) - 100 + 'px';
}
if (road[i] == 'top') {
pos.style.top = parseInt(pos.style.top) - 100 + 'px';
}
i++;
if (i == road.length + 1) {
clearInterval(timer);
}
}, 500, i, pos);
}
dfs(0, 0);
draw();
</script>
</body>
</html>
부분 설명
1. dfs () 검색 경로
알고리즘 코어 : 미로 검색을위한 심층 검색
function dfs(x, y) {
if (x < 0 || x > n - 1 || y < 0 || y > m - 1 || re[x][y] == 1 || map[x][y] == 0) return 0; //走出界外或之前走过或遇到障碍
if (arguments[2])// 排除从头开始,第一次没有第三个参数
road.push(arguments[2]); // 记录路径
if (x == n - 1 && y == m - 1) {
recallMark(arguments[2]); // 会return,提前记录路径
return 1; //走到终点
}
re[x][y] = 1; //该点标记为走过
dfs(x - 1, y, 'top'); //向上走
dfs(x, y + 1, 'right'); //向右走
dfs(x + 1, y, 'down'); //向下走
dfs(x, y - 1, 'left'); //向左走
if (!(x == 0 && y == 0)) // 最后一次回溯在起点不记录
recallMark(arguments[2]); // 记录回溯路径
re[x][y] = 0; //该点还原为没有走过
}
순서는 js 단일 스레드가 절전 모드가 아니기 때문에 오른쪽 위, 왼쪽 아래입니다. 따라서 모든 결과가 먼저 기록되고 (세 번째 문자열 매개 변수가 방향을 나타 내기 위해 dfs에 전달 될 때마다 저장을 용이하게하기 위해) 결과가 기록됩니다. 그리기에 사용됩니다.
레코드 배열이있는 도로 주행 방향, 반대로 dfs 매개 변수 내 recallMark
에서 반대 방향, 역방향 기록 기능이있는 후 배열 도로에 저장 됨
2. reLoad () 미로 읽기
function reLoad() {
let str = prompt("输入地图 用-间隔");
let arr = str.split('-');
let map = [];
for (let i = 0; i < arr.length; i++) {
map.push(arr[i].trim().split(' ').map(Number));
}
return map; // 返回二维数组
}
프롬프트로 얻은 문자열은 str에 저장되고 split
각 행 배열 arr 은 string method 로 나뉩니다. arr의 각 항목은 공백이있는 미로의 숫자 행과 arr의 각 항목 (문자열)입니다. trim
공백을 닫고 문자열의 split
각 자리를 새 배열의 한 항목 map(Number)
으로 나누고 문자열을 숫자 로 변환 한 다음 마지막으로 맵 배열로 밀어 넣고 각 항목을 밀어 넣습니다. 다른 배열로의 배열은 위의 2 차원 배열입니다.