Node.js 시각화 미로 문제


사진 발표

여기에 사진 설명 삽입
인터페이스가 정말 추합니다

입력 형식 미로 : 통로, 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 차원 배열입니다.

추천

출처blog.csdn.net/S_aitama/article/details/109157417