寻路算法 --- 深度寻路算法
深度寻路:大地图 空旷地形 适用于不一定要找到最佳路径的情况 尽量每个角落都走遍
广度寻路:不需要回退 一定能找到最佳路径 循环多 小地图
#include <iostream>
using namespace std;#include <graphics.h>#include "MyStack.h"//格子宽高
#define SPACE 80//Y 竖着 行数
#define ROWS 10
//X 横着 列数
#define COLS 10
//状态 路 墙
enum states{ Road,Wall };
//4个方向可以试探-> 人为规定试探方向 枚举
enum direct{p_up,p_down,p_left,p_right};//用数组下标区分地图上的某一个位置
class MyPoint{
public:int row, col; //为了操作方便,写成公有属性-> 行 列friend bool operator==(const MyPoint& p1, const MyPoint& p2);
};bool operator==(const MyPoint& p1, const MyPoint& p2){//双目运算符一般声明为友元if ((p1.row == p2.row) && (p1.col == p2.col) ) return true;return false;
}//辅助地图-> 地图元素不同
class PathNode{
public://states val; //地图上的值direct dir; //当前试探方向bool isFind; //是否走过
};//图片变量
IMAGE pos, ren, road, wall;void printMap(int map[ROWS][COLS], MyPoint pos); //显示地图
void drawMap(int map[ROWS][COLS],MyPoint pos);int main(){initgraph(SPACE*COLS, SPACE*ROWS,SHOWCONSOLE); //窗口宽高loadimage(&road, "road.bmp", SPACE, SPACE, true);loadimage(&wall, "wall.bmp", SPACE, SPACE, true);loadimage(&ren, "ren.bmp", SPACE, SPACE, true);loadimage(&pos, "pos.bmp", SPACE/2, SPACE/2, true); //点//地图int map[ROWS][COLS] = {{ Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall },{ Wall, Road, Wall, Road, Road, Wall, Wall, Road, Road, Wall },{ Wall, Road, Wall, Road, Wall, Wall, Wall, Road, Wall, Wall },{ Wall, Road, Wall, Road, Road, Road, Wall, Road, Wall, Wall },{ Wall, Road, Road, Road, Wall, Road, Wall, Road, Wall, Wall },{ Wall, Road, Wall, Wall, Wall, Road, Wall, Road, Wall, Wall },{ Wall, Road, Wall, Wall, Wall, Road, Road, Road, Road, Wall },{ Wall, Road, Wall, Road, Road, Road, Wall, Road, Wall, Wall },{ Wall, Road, Wall, Road, Wall, Road, Wall, Road, Road, Wall },{ Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall, Wall }};//辅助地图-> 1.记录每个点的当前试探方向 2.记录每个点有没有走过PathNode pathMap[ROWS][COLS] = { p_up };/* 有3个元素的情况 记录地图上的值,需要原地图的值拷贝到辅助地图中-> 如果只有两个元素可以不考虑for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS; j++){pathMap[i][j] = map[i][j];}}*/MyPoint begPos = { 1, 1 };//起点 MyPoint endPos = { 8, 8 };//终点while (1);return 0;
}void drawMap(int map[ROWS][COLS], MyPoint pos){for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS; j++){if (i == pos.row && j == pos.col){putimage(j*SPACE, i*SPACE, &ren);}else if (Wall == map[i][j]){putimage(j*SPACE, i*SPACE, &wall);}else if (Road == map[i][j]){putimage(j*SPACE, i*SPACE, &road);}}}
}
void printMap(int map[ROWS][COLS], MyPoint pos){system("cls");for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS; j++){if (i == pos.row && j == pos.col){cout << "人";}else if (Wall == map[i][j]){cout << "墙";}else if (Road == map[i][j]){cout << " ";}}cout << endl;}
}
深度寻路算法思想
有4个可以移动的方向,需要逐个去尝试、去找 -> 一般会人为规定试探的顺序
1. 只走直线,总共有四个方向可以试探,没有八个方向用来试探(不能走斜线)
人为规定试探顺序 一般来说是 顺时针 或 逆时针-> 走格子类的游戏,地图中有很多个宝箱,不知道宝箱在哪里,用深度寻路算法,从某个地方出发,一路去找,每个角落都去走一遍,把每个宝箱都打开. . .
这里按照上下左右的顺序-> 给每一个格子都人为设置试探顺序:每一个格子一开始都是往上走,一定是按照上、下、左、右的顺序
并且记录每个点的当前试探方向-> 节约时间,往上试过了,往下试过了,就没必要重复试探,直接往左边开始. . .
2. 走过的标记为走过-> 判断是否能走:1.判断是路,不是障碍物 2.并且没有走过
3. 回退机制-> 上、下、左、右都不能走的情况,不能直接寻路结束,应该有回退机制
3.1 每走一步 把每一个点的坐标都入栈
3.2 需要回退的时候
3.2.1 删除栈顶元素
3.2.2 跳到当前栈顶元素处
所有的回退,存档,函数传参都是栈结构实现的:利用先进后出的特性,可以存数据,可以很好地记录顺序,需要撤销、回退时,非常方便
人物到达死胡同,需要回退,只需要把栈顶元素删掉,让人物跳到当前栈顶处即可,就实现了回退,要加入元素,在当前栈顶入栈
注意:回退时,已经把它从栈中删掉了,所以,从起点找到终点后,当前栈中记录的元素为蓝色部分-> 即从起点找到终点的路径,实际走的路线为红色部分
1.已知当前点的坐标,找试探点-> 在辅助地图中记录了当前点的当前试探方向
2.判断试探点是否能走, 如果能走,走的时候标记点已经走过了,要入栈 如果不能走:
2.1.(前面三个方向中某一个能走)试探方向改变
2.2.(第四个方向还是不能走) 回退,删除栈顶元素,跳到当前栈顶元素处即可
3.判断是否结束循环
3.1找到终点了
3.2没有找到终点,但是栈空了-> 整个地图都找遍了
//准备一个栈-> 栈中存坐标MyStack<MyPoint> stack;//起点标记为走过pathMap[begPos.row][begPos.col].isFind = true;//起点入栈stack.push(begPos);//当前点的坐标MyPoint currentPos = begPos;//试探点-> 用于试探MyPoint searchPos;//是否找到终点bool isFindEnd = false;//循环寻路while (1){searchPos = currentPos;//让试探点==当前点switch (pathMap[currentPos.row][currentPos.col].dir){//判断当前点的当前试探方向-> 辅助地图case p_up: //上searchPos.row--; //1 找到试探点 试探点==当前点 当前点的当前试探方向往上 y-1//2 判断试探点是否能走//试探方向改变-> 前面3个方向不管能不能走都直接改 当前点的 试探方向-> 节约代码pathMap[currentPos.row][currentPos.col].dir = p_down; //枚举类型不能直接++ 采用赋值的方式if (pathMap[searchPos.row][searchPos.col].isFind == false &&//没有走过map[searchPos.row][searchPos.col] == Road){//试探点的值Road 是路 可以走//2.1 能走 currentPos = searchPos;//走 pathMap[currentPos.row][currentPos.col].isFind = true; //辅助地图中标记走过 stack.push(currentPos);//入栈}//else{//2.2 不能走//} break;case p_down: //下searchPos.row++; //1 找到试探点//2 判断是否能走//试探方向改变pathMap[currentPos.row][currentPos.col].dir = p_left;if (pathMap[searchPos.row][searchPos.col].isFind == false &&//没有走过map[searchPos.row][searchPos.col] == Road){//是路 可以走//2.1 能走 currentPos = searchPos;//走 pathMap[currentPos.row][currentPos.col].isFind = true;//标记走过 stack.push(currentPos);//入栈}break;case p_left: //左searchPos.col--; //1 找到试探点//2 判断是否能走//试探方向改变pathMap[currentPos.row][currentPos.col].dir = p_right;if (pathMap[searchPos.row][searchPos.col].isFind == false &&//没有走过map[searchPos.row][searchPos.col] == Road){//是路 可以走//2.1 能走 currentPos = searchPos;//走 pathMap[currentPos.row][currentPos.col].isFind = true;//标记走过 stack.push(currentPos);//入栈}break;case p_right: //右searchPos.col++; //1 找到试探点-> 往右不需要修改试探方向//2 判断是否能走if (pathMap[searchPos.row][searchPos.col].isFind == false &&//没有走过map[searchPos.row][searchPos.col] == Road){//是路 可以走//2.1 能走 currentPos = searchPos;//走 pathMap[currentPos.row][currentPos.col].isFind = true;//标记走过 stack.push(currentPos);//入栈}else{//2.2.2 第四个方向还不能走 //回退stack.pop(); //删除栈顶元素currentPos = stack.getTop(); //跳到当前栈顶元素处-> 获取当前栈顶元素}break;}//end of switch (pathMap[currentPos.row][currentPos.col].dir)printMap(map, currentPos); //每一步都做一次打印drawMap(map, currentPos);Sleep(300);//3 判断是否结束循环//3.1 找到终点了结束循环if (endPos == currentPos){//需要运算符重载-> 没有与这些操作数匹配的"=="运算符isFindEnd = true; //不知道是由于栈空还是找到终点结束循环-> 需要做标记 如果找到终点标记它为真break;}//3.2 栈空了结束循环if (stack.isEmpty()) break;}if (isFindEnd){//找到终点cout << "喜大普奔,找到终点啦!" << endl;while (!stack.isEmpty()){//栈不等于空 打印路径 栈顶->栈底-> 逆着打印cout << "(" << stack.getTop().row << "," << stack.getTop().col << ") ";putimage(stack.getTop().col*SPACE + SPACE/4, stack.getTop().row*SPACE + SPACE / 4, &pos);stack.pop();//退掉一个}cout << endl;}
MyStack.h
#pragma once
//数组描述栈
//pArr[0] 栈底 pArr[size-1] 栈顶
#include <iostream>
using namespace std;template<class T>
class MyStack
{T* pArr; //指向动态数组int size; //描述动态数组元素个数int capacity; //当前空间
public:MyStack(){pArr = NULL;capacity = size = 0;}~MyStack(){_clear();}//入栈void push(const T& data);//出栈T pop();//遍历栈 栈底到栈顶void travel();//获取栈顶元素T getTop()const{ return pArr[size - 1]; }//判断栈是否为空bool isEmpty()const{return (0 == size);}//返回栈中元素个数int getSize()const{ return size; }
private:void _clear();
};
template<class T>
void MyStack<T>::_clear(){if (pArr){delete[] pArr;pArr = NULL;capacity = size = 0;}
}template<class T>
//遍历数组
void MyStack<T>::travel(){cout << "MyStack capacity:" << capacity << ",size:" << size << ":";for (int i = 0; i < size; i++)cout << *(pArr + i) << " ";cout << endl;
}
template<class T>
//入栈
void MyStack<T>::push(const T& data){//0 判断是否需要开空间if (size >= capacity){//计算新开空间大小capacity = capacity +(((capacity >> 1) > 1) ? (capacity >> 1) : 1);//1 开空间 T* pNew = new T[capacity];if (pArr){//2 原有数据拷贝过来memcpy(pNew, pArr, sizeof(T)*size);//3 释放原有内存段delete[] pArr;}//4 pArr指向新内存段pArr = pNew;}//5 新数据进来pArr[size++] = data;
}template<class T>
//出栈
T MyStack<T>::pop(){if (size > 0){T temp = pArr[size - 1];size--;//cout << "出栈成功!" << endl;return temp;}//cout << "出栈失败!" << endl;//return (T)NULL;
}
寻路算法 --- 深度寻路算法相关推荐
- Day8:寻路算法---深度寻路
一.基础概念: 寻路算法 --- 深度寻路算法_https://blog.csdn.net/weixin_60569662/article/details/123651939 思路: 1. 规定试探方 ...
- 寻路算法--深度寻路算法
深度寻路算法 深度寻路算法思想 规定试探方向顺序-顺时针(上右下左)和逆时针方向(上左下右) 实时记录每个点 当前试探方向 记录每个点是否走过 如果四个方向都不能走,则需要回退 回退每走一步,栈结构存 ...
- android 绘制歌词算法,深度学习算法写歌词
AI开发平台ModelArts ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及半自动化标注.大规模分布式Training.自动化模型生成,及端-边-云模型 ...
- c/c++数据结构之深度寻路算法基础(含自己写的源码)
一.深度寻路算法原理 第一步,我们要规定好人物的试探方向 : 即上右下左,上左下右 什么意思呢?就是计算机中的人物要看看自己的四周是空地还是墙,如果是墙就不能走,是空地则可以走. 第二步. 我们要进行 ...
- 数据结构学习第十八课(寻路算法之深度寻路)
寻路算法 /* 寻路算法: 找路径1 深度寻路:不一定能找到最短路径,回退,循环较少,步骤简单,适用于空旷地图;只能走直线 2 广度寻路:一定能找到最短路径,不需要回退,循环较多,步骤复杂,适用于较小 ...
- C语言-老鼠走迷宫(深度寻路算法)
老鼠走迷宫-c语言(基于深度优先的寻路算法) 这个是学校的课设,刚开始有点头疼,但是感觉越做越有意思了,于是就有如下代码,可能相较于大佬还有差距,但是这是我目前所能做的最优的程序了吧! 话不多说,说一 ...
- 寻路算法 --- 广度寻路算法
深度寻路:一个个去试,空旷地形 广度寻路:和深度寻路算法思想截然不同,不是一个个去试,而是依次展开:同样是从起点开始,看周围有哪些可以走的,依次去建立一棵树[ 只有四个方向:四叉树 ],总有一个地方, ...
- 实用高效的寻路算法——A*寻路算法的实现及优化思路
前言:寻路是游戏比较重要的一个组成部分.因为不仅AI还有很多地方(例如RTS游戏里操控人物点到地图某个点,然后人物自动寻路走过去)都需要用到自动寻路的功能. 本文将介绍一个经常被使用且效率理想的寻路方 ...
- 寻路的几种算法_Godot游戏开发实践之二:AI之寻路新方式
一.前言 AI 一直是游戏开发中一个热门词汇,当然这不是人工智能的那个 AI ,而是指有着人类思想的 NPC 或者聪明的敌人等等.根据游戏的类型和复杂程度, AI 的实现可以很简单,也可以非常复杂.作 ...
最新文章
- android特效按钮点击效果
- spark中的广播变量broadcast
- 第二章 寄存器基础概念
- 学习记录——背包问题基础公式解释回顾
- 过年最大的烦恼是什么?
- mysql官网下载驱动包
- oracle字段类型number默认值,Oracle 字段类型 | 学步园
- Web App - MUI框架实战
- 伦敦大学计算机研究生雅思要求,【留学科普】伦敦TOP10大学雅思要求来了!你够得上吗?...
- Spigot 算法之一 计算调和级数的和
- c语言字符画小狗,C语言字符画,字符闪画
- 小天使改名(水题 杭电排位赛-2)
- wps公式如何加序号_WPS表格技巧—筛选后也会自动连续的序号
- LeetCode刷题13-简单-罗马数字转整数
- 香港银行开户失败的原因及应对方法 香港银行开户要求愈发严资者如果想在香港银行开户,需对香港银行开户政透彻的了解,这样才能确保开户的成功率。
- 点到直线的距离公式和平行线的距离公式
- spring 运行原理
- python的idel下添加清屏功能
- 用Kbuilder制作卡拉OK教程
- 破 AI 天网?马斯克脑机接口实现与猪连接