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シングルスレッドにはスリープがないため、順序は右上、左下です。したがって、すべての結果が最初に記録され(3番目の文字列パラメーターが方向を表すために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メソッドによって分割されます。arrの各項目は、スペースを含む迷路内の数字の行であり、次にarrの各項目(文字列)です。がトラバースtrimされ、文字列メソッドが削除されますスペースを閉じてsplitからmap(Number)、文字列の各桁を新しい配列の1つの項目に分割し、文字列を数値に変換して、最後にマップ配列にプッシュし、別の配列への配列は、上記の2次元配列です。

おすすめ

転載: blog.csdn.net/S_aitama/article/details/109157417