寻路算法小游戏

 寻路算法小demo

寻路算法有两种,一种是dfs 深度优先算法,一种是

dfs 深度优先算法

深度优先搜索的步骤分为 1.递归下去 2.回溯上来。顾名思义,深度优先,则是以深度为准则,先一条路走到底,直到达到目标。这里称之为递归下去。

否则既没有达到目标又无路可走了,那么则退回到上一步的状态,走其他路。这便是回溯上来

 bfs 广度优先搜索

广度优先搜索较之深度优先搜索之不同在于,深度优先搜索旨在不管有多少条岔路,先一条路走到底,不成功就返回上一个路口然后就选择下一条岔路,而广度优先搜索旨在面临一个路口时,把所有的岔路口都记下来,然后选择其中一个进入,然后将它的分路情况记录下来,然后再返回来进入另外一个岔路,并重复这样的操作。

数据结构上的运用

DFS用递归的形式,用到了栈结构,先进后出。

BFS选取状态用队列的形式,先进先出。

<html>

<head>
    <title>寻路算法</title>
</head>

<body>
    <div class="body">
        <div class="body-content1">
            <div class="dfs-title">寻路算法</div>
            <div id="dfs-content" class="dfs-cell"></div>
            <div id="btn-list">
                <div id="btn-start-dfs" class="btn-start">dfs</div>
                <div id="btn-start-bfs" class="btn-start">bfs</div>
                <div id="btn-reset">重置</div>
            </div>
        </div>
        <div class="body-content2">
            <div class="dfs-title">.</div>
            <div class="start-point point">
                开始坐标:
                <input id="start-point-x" type="number" placeholder="行" />
                <input id="start-point-y" type="number" placeholder="列" />
            </div>
            <div class="target-point point">
                终点坐标:
                <input id="target-point-x" type="number" placeholder="行" />
                <input id="target-point-y" type="number" placeholder="列" />
            </div>
        </div>
    </div>
</body>
<script>
    let count = 0; //步数计数
    //迷宫地图
    let map = [
        [0, 0, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 0, 0, 0],
        [1, 0, 0, 0, 0, 1, 0, 0],
        [0, 0, 0, 0, 1, 0, 1, 0],
        [1, 0, 0, 0, 1, 0, 0, 0],
        [0, 0, 1, 0, 1, 0, 0, 0],
        [0, 1, 0, 0, 1, 1, 0, 1],
        [0, 0, 1, 1, 1, 0, 0, 0],
        [0, 0, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 0, 0, 0],
        [1, 0, 0, 0, 0, 1, 0, 0],
        [0, 0, 0, 0, 1, 0, 1, 0],
        [1, 0, 0, 0, 1, 0, 0, 0],
        [0, 0, 1, 0, 1, 0, 0, 0],
        [0, 1, 0, 0, 1, 1, 0, 1],
        [0, 0, 1, 1, 1, 0, 0, 0],
    ];
    let cellSize = 20; //px单元格大小
    let startX = 0, //开始坐标
        startY = 0;
    let targetX = 15, //结束坐标
        targetY = 7;
    let canFind = false;

    //遍历方向
    let dx = [0, 1, 0, -1],
        dy = [1, 0, -1, 0];

    let flag = new Array(map.length); //dfs标记走过的路径
    for (let i = 0; i < flag.length; i++) {
        flag[i] = new Array(map[i].length).fill(false);
    }
    //能否到达
    let findFlag = false;

    let step = new Array(map.length); //bfs标记走过的路径
    for (let i = 0; i < step.length; i++) {
        step[i] = new Array(map[i].length).fill(Infinity);
    }
    //单元格点击事件
    function cellClick(e) {
        let wFlag = 0;
        let classList = [...e.classList];
        if (classList.includes("now-in")) return;
        if (classList.includes("wall")) {
            e.classList.remove("wall");
            e.classList.add("space");
        } else if (classList.includes("space")) {
            e.classList.remove("space");
            e.classList.add("wall");
            wFlag = 1;
        }
        let id = e.id.split("-");
        let x = id[2],
            y = id[3];
        map[x][y] = wFlag;
        // console.log(map[x][y], x, y);
    }
    //初始化页面
    function init() {
        initPage();
        initData();
    }

    function initData() {
        const startPointX = document.getElementById("start-point-x");
        const startPointY = document.getElementById("start-point-y");
        const targetPointX = document.getElementById("target-point-x");
        const targetPointY = document.getElementById("target-point-y");
        startPointX.value = startX;
        startPointY.value = startY;
        targetPointX.value = targetX;
        targetPointY.value = targetY;

        startPointX.addEventListener("change", (e) => {
            if (
                e.target.value < 0 ||
                e.target.value >= map.length ||
                map[e.target.value][startY] == 1
            ) {
                alert("非法坐标,请重新输入");
                startPointX.value = startX;
                return;
            }
            startX = parseInt(e.target.value);
            initPage();
        });
        startPointY.addEventListener("change", (e) => {
            if (
                e.target.value < 0 ||
                e.target.value >= map[0].length ||
                map[startX][e.target.value] == 1
            ) {
                alert("非法坐标,请重新输入");
                startPointY.value = startY;
                return;
            }
            startY = parseInt(e.target.value);
            initPage();
        });
        targetPointX.addEventListener("change", (e) => {
            if (
                e.target.value < 0 ||
                e.target.value >= map.length ||
                map[e.target.value][targetY] == 1
            ) {
                alert("非法坐标,请重新输入");
                targetPointX.value = targetX;
                return;
            }
            targetX = parseInt(e.target.value);
            initPage();
        });
        targetPointY.addEventListener("change", (e) => {
            if (
                e.target.value < 0 ||
                e.target.value >= map[0].length ||
                map[targetX][e.target.value] == 1
            ) {
                alert("非法坐标,请重新输入");
                targetPointY.value = targetY;
                return;
            }
            targetY = parseInt(e.target.value);
            initPage();
        });
    }

    function initPage() {
        let innerHtml = ``;
        count = 0;
        findFlag = false;
        for (let i = 0; i < map.length; i++) {
            for (let j = 0; j < map[i].length; j++) {
                flag[i][j] = false;
                innerHtml += `<div id="${"dfs-id-" + i + "-" + j}" class="${
            map[i][j] == 0 ? "space" : "wall"
          } cell" style="width:${cellSize}px;height:${cellSize}px;" click="cellClick"></div>`;
            }
        }
        let dfsContent = document.getElementById("dfs-content");
        dfsContent.style.width = map[0].length * (cellSize + 2) + "px";
        dfsContent.innerHTML = innerHtml;

        let startCell = document.getElementById(
            "dfs-id-" + startX + "-" + startY
        );
        startCell.classList.add("now-in");

        let targetCell = document.getElementById(
            "dfs-id-" + targetX + "-" + targetY
        );
        targetCell.classList.add("target-in");
        let cell = document.getElementsByClassName("cell");
        for (let i = 0; i < cell.length; i++) {
            cell[i].addEventListener("click", () => {
                cellClick(cell[i]);
            });
        }
    }

    function dfs(x, y) {
        const dx = [1, 0, -1, 0],
            dy = [0, 1, 0, -1];
        if (x < 0 || y < 0 || x >= map.length || y >= map[0].length) return;
        if (map[x][y] == 1 || flag[x][y] || findFlag) return;
        let startCell = document.getElementById("dfs-id-" + x + "-" + y);
        startCell.classList.add("now-in");
        if (x == targetX && y == targetY) {
            findFlag = true;
            startCell.innerHTML = `<div style="font-size:small;text-align: center;">${count}</div>`;
            canFind = true;
            return;
        }
        for (let i = 0; i < 4 && !findFlag; i++) {
            flag[x][y] = true;
            startCell.innerHTML = `<div style="font-size:small;text-align: center;">${count}</div>`;
            count++;
            startCell.classList.add("pass");
            startCell.classList.remove("now-in");

            if (!findFlag) dfs(x + dx[i], y + dy[i]);
            if (!findFlag) flag[x][y] = false;
            if (!findFlag) startCell.innerHTML = "";
            if (!findFlag) count--;
            if (!findFlag) startCell.classList.remove("pass");
        }
    }

    function bfs() {
        let quene = [
            [startX, startY]
        ];
        step[startX][startY] = 0;
        // console.log("开始bfs");
        let res = [];
        flag[startX][startY] = true;
        while (quene.length) {
            let p = quene.shift();
            res.push(p);
            let x = p[0],
                y = p[1];
            if (x == targetX && y == targetY) break;
            let f = false;
            for (let i = 0; i < 4; i++) {
                let nx = x + dx[i],
                    ny = y + dy[i];
                if (nx < 0 || nx >= map.length || ny >= map[0].length || ny < 0) {
                    continue;
                }
                if (map[nx][ny] == 1 || flag[nx][ny] == true) {
                    continue;
                }
                flag[nx][ny] = true;
                step[nx][ny] = step[x][y] + 1;
                quene.push([nx, ny]);
                if (nx == targetX && ny == targetY) {
                    f = true;
                    canFind = true;
                    break;
                }
            }
            if (f) break;
        }
        if (canFind) bfsDrawRoad();
    }
    //绘制路线
    function bfsDrawRoad() {
        let road = [
            [targetX, targetY]
        ];
        while (road[0][0] != startX || road[0][1] != startY) {
            let x = road[0][0],
                y = road[0][1];
            for (let i = 0; i < 4; i++) {
                let nx = x + dx[i],
                    ny = y + dy[i];
                if (nx < 0 || ny < 0 || nx >= step.length || ny >= step[0].length)
                    continue;
                if (step[x][y] == step[nx][ny] + 1) {
                    road.unshift([nx, ny]);
                    break;
                }
            }
        }
        for (let i = 0; i < road.length; i++) {
            let startCell = document.getElementById(
                "dfs-id-" + road[i][0] + "-" + road[i][1]
            );
            if (i != road.length - 1) {
                startCell.classList.add("pass");
            } else {
                startCell.classList.add("now-in");
            }

            startCell.innerHTML = `<div style="font-size:small;text-align: center;">${i}</div>`;
        }
    }
    //页面初始化
    init();
    //开始dfs
    let startBtnDfs = document.getElementById("btn-start-dfs");
    startBtnDfs.addEventListener("click", () => {
        canFind = false;
        init();
        dfs(startX, startY);
        // console.log(canFind);
        if (!canFind) alert("无法达到");
    });
    //开始bfs
    let startBtnBfs = document.getElementById("btn-start-bfs");
    startBtnBfs.addEventListener("click", () => {
        canFind = false;
        init();
        bfs();
        // console.log(canFind);
        if (!canFind) alert("无法达到");
    });
    //重置页面
    let resetBtn = document.getElementById("btn-reset");
    resetBtn.addEventListener("click", () => {
        init();
    });
</script>
<style>
    .body {
        display: flex;
        margin: auto;
    }
    
    .body-content1 {
        flex: 1;
    }
    
    .body-content2 {
        flex: 1;
    }
    
    .point {
        margin-top: 1rem;
    }
    
    .dfs-cell {
        display: flex;
        flex-wrap: wrap;
        margin: auto;
    }
    
    .dfs-cell>.cell {
        border: 1px solid gray;
        cursor: pointer;
    }
    
    .dfs-cell>.wall {
        background-color: black;
    }
    
    .now-in {
        background-color: yellow;
    }
    
    .target-in {
        background-color: rgb(245, 162, 9);
    }
    
    .pass {
        background-color: yellowgreen;
    }
    
    .dfs-title {
        text-align: center;
        margin: 2rem;
    }
    
    #btn-list {
        display: flex;
        justify-content: space-between;
        width: 20rem;
        margin: auto;
    }
    
    .btn-start {
        padding: 1rem;
        margin: auto;
        margin-top: 2rem;
        text-align: center;
        background-color: violet;
        width: 2rem;
        cursor: pointer;
    }
    
    #btn-reset {
        padding: 1rem;
        margin: auto;
        margin-top: 2rem;
        text-align: center;
        background-color: violet;
        width: 2rem;
        cursor: pointer;
    }
</style>

</html>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/78929.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

numpy与matplotlib 常用日常代码

matplotlab 和 numpy 可能是python 数据处理工作中用的最多的库了&#xff0c; 官网的文档十分详细&#xff0c;但是就是因为数量庞大&#xff0c;很多时候常用的功能和生僻冷门的功能混在一起&#xff0c;找不到重点。按照二八原则&#xff0c;掌握20%的功能就已经能应付绝大多…

python爬虫——爬取天气预报信息

在本文中&#xff0c;我们将学习如何使用代理IP爬取天气预报信息。我们将使用 Python 编写程序&#xff0c;并使用 requests 和 BeautifulSoup 库来获取和解析 HTML。此外&#xff0c;我们还将使用代理服务器来隐藏我们的 IP 地址&#xff0c;以避免被目标网站封禁。 1. 安装必…

vue上传图片并修改png图片颜色

场景 当涉及到在 Vue 中上传图片并修改 PNG 图片的颜色时&#xff0c;这个任务涵盖了文件上传、图像处理、Canvas 操作等多个方面 在现代 Web 开发中&#xff0c;图片的处理是常见的需求之一。本文将带您深入探讨如何使用 Vue.js 来实现图片上传&#xff0c;并在客户端使用 Can…

小航助学Python编程NOC模拟卷(第1套)(含题库答题软件账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSDN博客 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSD…

【springboot】mongoTemplate增删改查操作

目录 一、代码示例1.1 pom依赖1.2 application配置1.3 controller1.4 service 二、截图示例2.1 新增2.2 修改2.3 详情2.4 分页2.5 删除 一、代码示例 1.1 pom依赖 <!-- mongodb --> <dependency><groupId>org.springframework.boot</groupId><art…

如何批量修改图片名为不同名称

如何批量修改图片名为不同名称&#xff1f;当今社会&#xff0c;因为人们都养成了随手拍照的习惯&#xff0c;所以拥有上千上万张照片的相册已经司空见惯不足为奇。然而&#xff0c;我们在保存这些照片时往往都会碰到一个大难题——电脑中的图片名称千奇百怪&#xff0c;让整个…

STM32 printf函数

printf函数输出流程 用户调用printf()函数到C标准库调用printf函数相关部分&#xff0c;printf函数由编译器提供的stdio.h解析。包含在usart.h文件中。fputc()最终实现输出。用户需要根据最终输出的硬件重新定义该函数&#xff0c;此过程为&#xff1a;printf重定向。 printf的…

WebMagic - 创意前端项目集合(点击链接可在电脑上查看效果)

WebMagic - 创意前端项目集合 欢迎来到 WebMagic 仓库&#xff01;这里汇集了一系列令人惊叹的前端项目&#xff0c;涵盖了HTML5、CSS3和JS等多项技术。无论你是前端开发者、设计师&#xff0c;还是对创意互动内容感兴趣的人&#xff0c;这个仓库都将为你带来无尽的惊喜。 每…

高等数学教材重难点题型总结(三)微分中值定理和导数的应用

第三章&#xff0c;微分中值定理的证明题等&#xff0c;非常重要&#xff0c;需要牢牢掌握 1.证明中值定理对某函数在给定区间上的正确性 2.与中值定理有关的证明题 3.微分中值定理应用于求证不等式 4.洛必达法则求极限 5.洛必达的经典错误反例 6.按某项实现多项式幂展开 7.求带…

【网络】网络层——IP协议

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 网络层中&#xff0c;IP协议首部和有效载荷组成的完整数据称为数据报。 IP协议 &#x1f349;TCP和IP的…

重建与突破,探讨全链游戏的现在与未来

全链游戏&#xff08;On-Chain Game&#xff09;是指将游戏内资产通过虚拟货币或 NFT 形式记录上链的游戏类型。除此以外&#xff0c;游戏的状态存储、计算与执行等皆被部署在链上&#xff0c;目的是为用户打造沉浸式、全方位的游戏体验&#xff0c;超越传统游戏玩家被动控制的…

新能源电动车充电桩控制主板安全特点

新能源电动车充电桩控制主板安全特点 你是否曾经担心过充电桩的安全问题?充电桩主板又是什么样的呢?今天我们就来聊聊这个话题。 充电桩主板采用双重安全防护系统&#xff0c;包括防水、防护、防尘等&#xff0c;确保充电桩安全、可靠。不仅如此&#xff0c;充电桩主板采用先…

C# Linq源码分析之Take (一)

概要 在.Net 6 中引入的Take的另一个重载方法&#xff0c;一个基于Range的重载方法。因为该方法中涉及了很多新的概念&#xff0c;所以在分析源码之前&#xff0c;先将这些概念搞清楚。 Take方法基本介绍 public static System.Collections.Generic.IEnumerable Take (this …

mybatis-plus 根据指定字段 批量 删除/修改

mybatis-plus 提供了根据id批量更新和修改的方法,这个大家都不陌生 但是当表没有id的时候怎么办 方案一: 手写SQL方案二: 手动获取SqlSessionTemplate 就是把mybatis plus 干的事自己干了方案三 : 重写 executeBatch 方法结论: mybatis-plus 提供了根据id批量更新和修改的方法,…

【Linux】POSIX信号量和基于环形队列的生产消费者模型

目录 写在前面的话 什么是POSIX信号量 POSIX信号量的使用 基于环形队列的生产消费者模型 写在前面的话 本文章主要先介绍POSIX信号量&#xff0c;以及一些接口的使用&#xff0c;然后再编码设计一个基于环形队列的生产消费者模型来使用这些接口。 讲解POSIX信号量时&#x…

rabbitMQ服务自动停止(已解决

1、 在rabbitmq的sbin目录下操作 rabbitmq-plugins enable rabbitmq_management 2、 自己去rabbitmq_server-3.7.5文件夹下创建一个data&#xff0c;再执行这个命令&#xff08;用自己的目录哈 set RABBITMQ_BASED:\RabbitTools\RabbitMQ\rabbitmq_server-3.7.5\data 然后去配…

执行Lua脚本后一直查询不到Redis中的数据(附带问题详细排查过程,一波三折)

文章目录 执行Lua脚本后一直查询不到Redis中的数据&#xff08;附带详细问题排查过程&#xff0c;一波三折&#xff09;问题背景问题1&#xff1a;Lua脚本无法切库问题2&#xff1a;RedisTemlate切库报错问题3&#xff1a;序列化导致数据不一致问题4&#xff1a;Lua脚本中单引号…

windows系统丢失mfc120u.dll的解决方法

1.mfc120u.dll是什么 mfc120u.dll是Windows操作系统中的一个动态链接库&#xff08;Dynamic Link Library&#xff0c;简称DLL&#xff09;文件。它包含了一些用于运行C程序的函数和其他资源。这个特定的DLL文件是Microsoft Foundation Classes&#xff08;MFC&#xff09;库的…

wireshark界面内容含义

网络分析工具——WireShark的使用&#xff08;超详细&#xff09;_世间繁华梦一出的博客-CSDN博客 wireshark抓包数据&#xff1a;理解与分析_wireshark里面length_ 佚名的博客-CSDN博客

app 自动化测试 - 多设备并发 -appium+pytest+ 多线程

1、appiumpython 实现单设备的 app 自动化测试 启动 appium server&#xff0c;占用端口 4723电脑与一个设备连接&#xff0c;通过 adb devices 获取已连接的设备在 python 代码当中&#xff0c;编写启动参数&#xff0c;通过 pytest 编写测试用例&#xff0c;来进行自动化测试…