• 《算法七》(深度寻路算法)


    深度寻路算法:
      二维地图:二维数组
      二维数组上标识特定数值作为地图上对象
      应用于RGB游戏中比较广泛
      缺点:1.二维地图,只可以走直线
         2.不一定能找到最佳路径

    怎么寻路:
      1.一个方向只能试探一次
      顺时针: 上 右 下 左
      逆时针: 上 左 下 右
      2.需要标记已经走过,走过了的不能再走

    深度寻路算法逻辑:

      1.地图

      2 辅助地图

      3.起点 终点

      4.准备栈

      5.标记起点走过

      7起点入栈

      8 寻路:
        8.1 准备变量

        8.2 确定试探点

        8.3 改变当前点试探方向

        8.4 试探试探点能不能走

        8.5 走

        8.6 标记当前点已经走过

        8.7 当前点入栈

    深度寻路代码:

    int _tmain(int argc, _TCHAR* argv[])
    {
    	//1 地图
    	int map[ROWS][COLS] = {
    		{ 1, 1, 1, 1, 1, 1, 1, 1 },
    		{ 1, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 1, 0, 1, 0, 1, 1 },
    		{ 1, 0, 1, 0, 1, 0, 1, 1 },
    		{ 1, 0, 1, 0, 1, 0, 0, 1 },
    		{ 1, 0, 1, 0, 1, 0, 1, 1 },
    		{ 1, 0, 0, 0, 1, 0, 0, 1 },
    		{ 1, 1, 1, 1, 1, 1, 1, 1 }
    	};
    	//2 辅助地图
    	pathNode pathMap[ROWS][COLS] = { 0 };
    	for (int i = 0; i < ROWS; i++){
    		for (int j = 0; j < COLS; j++){
    			pathMap[i][j].val = map[i][j];
    		}
    	}
    
    	//4 起点 终点
    	MyPoint beginPos;
    	MyPoint endPos;
    	printf("请输入起点(x,y)
    ");
    	scanf("%d,%d", &(beginPos.col), &(beginPos.row) );
    	printf("请输入终点(x,y)
    ");
    	scanf("%d,%d", &(endPos.col), &(endPos.row));
    
    
    
    	//5 准备栈
    	MyStack<MyPoint> stack;
    	//6 标记起点走过
    	pathMap[beginPos.row][beginPos.col].isFind = true;
    	//7 起点入栈
    	stack.push(beginPos);
    	//8 寻路
    	//8.1 准备变量
    
    	//当前角色位置
    	MyPoint currentPos = beginPos;
    	//角色试探点
    	MyPoint searchPos;
    	bool isFindEnd = false;
    
    	initDraw();//准备图形界面
    	while (1){
    		searchPos = currentPos;
    		switch (pathMap[currentPos.row][currentPos.col].dir)
    		{
    		case p_up:
    			//8.2 确定试探点
    			searchPos.row--;
    			//8.3 改变当前点试探方向
    			pathMap[currentPos.row][currentPos.col].dir = p_right;
    			//8.4 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			break;
    		case p_right:
    			//8.2 确定试探点
    			searchPos.col++;
    			//8.4 改变当前点试探方向
    			pathMap[currentPos.row][currentPos.col].dir = p_down;
    			//8.3 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			break;
    		case p_down:
    			//8.2 确定试探点
    			searchPos.row++;
    			//8.4 改变当前点试探方向
    			pathMap[currentPos.row][currentPos.col].dir = p_left;
    			//8.3 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			break;
    		case p_left:
    			//8.2 确定试探点
    			searchPos.col--;
    			//8.3 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			else{//不能走
    				//8.8 回退
    				//8.8.1 退栈
    				stack.pop();
    				//8.8.2 当前点变为栈顶元素
    				currentPos = stack.getTop();
    			}
    			break;
    		}
    
    		printMap(map, currentPos);
    		drawMap(map, currentPos);
    
    
    		//找到终点  循环结束
    		if (currentPos.row == endPos.row &&
    			currentPos.col == endPos.col){
    			isFindEnd = true;
    			break;
    		}
    		//栈为空:回到起点  循环结束
    		if (stack.isEmpty())
    			break;
    	}
    	//9 打印整个路径
    	if (isFindEnd){
    		printf("path:");
    		while (!stack.isEmpty()){
    			//9.1 打印栈顶元素
    			printf("(%d,%d)
    ", stack.getTop().row, stack.getTop().col);
    			//9.2 退栈
    			stack.pop();
    		}
    	}
    
    	while (1);
    	return 0;
    }
    

    完整代码:

    //定义栈
    //定义栈
    template<class T>
    class MyStack{
    	T* pBuff;
    	size_t capacity;
    	size_t len;
    	
    public:
    	MyStack(){
    		pBuff = NULL;
    		capacity = len =0;
    	}
    	~MyStack(){
    		if(pBuff){
    			delete[] pBuff;
    		}
    		pBuff = NULL;
    		capacity = len =0;	
    	}
    	void push(const T& data);//入栈 
    	void pop(void);//出栈 
    	T getTop(void);//获取栈顶元素 
    	bool isEmpty(void);//判断是否为空 
    }; 
    
    template<class T>
    void MyStack<T>::push(const T& data){//入栈
    	if (len >= capacity){
    		capacity = capacity + (((capacity >> 1) > 1) ? (capacity >> 1) : 1 );
    		T* pNew = new T[capacity];
    		if (pBuff){
    			memcpy(pNew, pBuff, sizeof(T)*len);
    			delete[] pBuff;
    		}
    		pBuff = pNew;
    	}
    	pBuff[len++] = data; 
    }
     
    template<class T> 
    //出栈 
    void MyStack<T>::pop(void){
    	len--;
    }
    
    template<class T>
    //获取栈顶元素 
    T MyStack<T>::getTop(void){
    	return pBuff[len - 1];
    }
    
    template<class T>
    //判断是否为空
    bool MyStack<T>::isEmpty(void){
    	return (len==0);
    } 
     
    // 深度寻路算法.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "MyStack.h"
    //#include <windows.h>
    #include <graphics.h>
    
    /*
    	RPG游戏中 地图
    	深度寻路算法
    		1.二维地图,只能走直线
    		2.不一定能找到最佳路径
    
    	广度寻路算法
    		
    	A星寻路算法
    		
    
    寻路:
    	1.一个方向只能试探一次
    		顺时针: 上 右 下 左
    		逆时针: 上 左 下 右
    	2.需要标记已经走过,走过了的不能再走
    		
    */
    //x 横  列数
    #define COLS  8
    //y 竖  行数
    #define ROWS  8
    //每个格子大小
    #define SPACE  50
    
    //方向枚举
    enum direct{p_up,p_right,p_down,p_left};
    
    //辅助地图元素类型
    struct pathNode{
    	int		val;	//这个点上是什么
    	direct	dir;	//试探方向
    	bool	isFind;	//有没有走过    0 false  没走过 1 true 走过
    };
    
    //点结构
    struct MyPoint{
    	int row;	//y
    	int col;	//x
    };
    
    //图片全局变量
    IMAGE g_wall, g_road, g_people;
    
    
    void printMap(int map[ROWS][COLS], MyPoint pos);
    void initDraw();
    void drawMap(int map[ROWS][COLS], MyPoint pos);
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//1 地图
    	int map[ROWS][COLS] = {
    		{ 1, 1, 1, 1, 1, 1, 1, 1 },
    		{ 1, 0, 1, 0, 0, 0, 0, 1 },
    		{ 1, 0, 1, 0, 1, 0, 1, 1 },
    		{ 1, 0, 1, 0, 1, 0, 1, 1 },
    		{ 1, 0, 1, 0, 1, 0, 0, 1 },
    		{ 1, 0, 1, 0, 1, 0, 1, 1 },
    		{ 1, 0, 0, 0, 1, 0, 0, 1 },
    		{ 1, 1, 1, 1, 1, 1, 1, 1 }
    	};
    	//2 辅助地图
    	pathNode pathMap[ROWS][COLS] = { 0 };
    	for (int i = 0; i < ROWS; i++){
    		for (int j = 0; j < COLS; j++){
    			pathMap[i][j].val = map[i][j];
    		}
    	}
    
    	//4 起点 终点
    	MyPoint beginPos;
    	MyPoint endPos;
    	printf("请输入起点(x,y)
    ");
    	scanf("%d,%d", &(beginPos.col), &(beginPos.row) );
    	printf("请输入终点(x,y)
    ");
    	scanf("%d,%d", &(endPos.col), &(endPos.row));
    
    
    
    	//5 准备栈
    	MyStack<MyPoint> stack;
    	//6 标记起点走过
    	pathMap[beginPos.row][beginPos.col].isFind = true;
    	//7 起点入栈
    	stack.push(beginPos);
    	//8 寻路
    	//8.1 准备变量
    
    	//当前角色位置
    	MyPoint currentPos = beginPos;
    	//角色试探点
    	MyPoint searchPos;
    	bool isFindEnd = false;
    
    	initDraw();//准备图形界面
    	while (1){
    		searchPos = currentPos;
    		switch (pathMap[currentPos.row][currentPos.col].dir)
    		{
    		case p_up:
    			//8.2 确定试探点
    			searchPos.row--;
    			//8.3 改变当前点试探方向
    			pathMap[currentPos.row][currentPos.col].dir = p_right;
    			//8.4 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			break;
    		case p_right:
    			//8.2 确定试探点
    			searchPos.col++;
    			//8.4 改变当前点试探方向
    			pathMap[currentPos.row][currentPos.col].dir = p_down;
    			//8.3 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			break;
    		case p_down:
    			//8.2 确定试探点
    			searchPos.row++;
    			//8.4 改变当前点试探方向
    			pathMap[currentPos.row][currentPos.col].dir = p_left;
    			//8.3 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			break;
    		case p_left:
    			//8.2 确定试探点
    			searchPos.col--;
    			//8.3 试探试探点能不能走
    			if (pathMap[searchPos.row][searchPos.col].isFind != true &&//没有走过
    				pathMap[searchPos.row][searchPos.col].val != 1)//不是障碍
    			{//能走
    				//8.5 走
    				currentPos = searchPos;
    				//8.6 标记当前点已经走过
    				pathMap[currentPos.row][currentPos.col].isFind = true;
    				//8.7 当前点入栈
    				stack.push(currentPos);
    			}
    			else{//不能走
    				//8.8 回退
    				//8.8.1 退栈
    				stack.pop();
    				//8.8.2 当前点变为栈顶元素
    				currentPos = stack.getTop();
    			}
    			break;
    		}
    
    		printMap(map, currentPos);
    		drawMap(map, currentPos);
    
    
    		//找到终点  循环结束
    		if (currentPos.row == endPos.row &&
    			currentPos.col == endPos.col){
    			isFindEnd = true;
    			break;
    		}
    		//栈为空:回到起点  循环结束
    		if (stack.isEmpty())
    			break;
    	}
    	//9 打印整个路径
    	if (isFindEnd){
    		printf("path:");
    		while (!stack.isEmpty()){
    			//9.1 打印栈顶元素
    			printf("(%d,%d)
    ", stack.getTop().row, stack.getTop().col);
    			//9.2 退栈
    			stack.pop();
    		}
    	}
    
    
    	LOGFONT font = { 0 };
    	font.lfHeight = 25;
    	font.lfWeight = 10;
    	settextstyle(&font);
    	outtextxy((COLS*SPACE - 110) / 2, (ROWS*SPACE - 25) / 2, L"恭喜你通关!");
    
    
    
    
    	while (1);
    	return 0;
    }
    
    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){//人
    				printf("人");
    			}
    			else if (map[i][j] == 1){//障碍
    				printf("墙");
    			}
    			else{//路
    				printf("  ");
    			}
    		}
    		printf("
    ");
    	}
    	Sleep(500);
    }
    
    void initDraw(){
    	initgraph(COLS*SPACE, ROWS*SPACE, SHOWCONSOLE);
    	loadimage(&g_wall, L"wall.jpg", SPACE, SPACE, true);
    	loadimage(&g_road, L"road.jpg", SPACE, SPACE, true);
    	loadimage(&g_people, L"people.jpg", SPACE, SPACE, true);
    }
    
    void drawMap(int map[ROWS][COLS], MyPoint pos){
    	cleardevice();//清屏
    	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, &g_people);
    			}
    			else if (map[i][j] == 1){//障碍
    				putimage(j*SPACE, i*SPACE, &g_wall);
    			}
    			else{//路
    				putimage(j*SPACE, i*SPACE, &g_road);
    			}
    		}
    	}
    }
    
  • 相关阅读:
    [ZJOI2006]书架
    [NOI2005]维护数列
    Python 最佳实践
    python中使用多继承
    python 抽象类、抽象方法的实现
    30个有关Python的小技巧
    一行 Python 实现并行化 -- 日常多线程操作的新思路
    python日志模块logging
    在Python中怎么表达True
    有趣的库:pipe(类似linux | 管道)库
  • 原文地址:https://www.cnblogs.com/Whgy/p/12292614.html
Copyright © 2020-2023  润新知