c/c++数据结构之深度寻路算法基础(含自己写的源码)

一、深度寻路算法原理

        第一步,我们要规定好人物的试探方向 : 即上右下左,上左下右

        什么意思呢?就是计算机中的人物要看看自己的四周是空地还是墙,如果是墙就不能走,是空地则可以走。

        第二步、 我们要进行实时记录

        为什么要实时进行记录,那是因为我们需要确定每个点是否已经走过,走过去之后,如果走到尽头就需要回退,所以每走一步,都需要存储一下当前点的位置(那么最好便是利用栈结构)。
        这样,等人物达到尽头,没有找到终点需要回退的时候,出栈,返回当前栈顶元素,让当前点返回到上一个,就和游戏的存档一样,回到了上一步。
        而最后到达终点,栈结构就已经存储了从开始到终点的路径,若是想要看路径,既可以在控制台以字符串的形式释放打印,也可以在图形化中用其他图片展示。

二、现在开始代码

        这里的栈结构我自己写一个,因为效果是比较简单的,很多功能并不需要。

        这里的头文件和cpp文件要一起使用。

头文件:

#pragma once
#include<iostream>
//深度寻路算法需要的功能
//入栈 
//出栈 

template<class _Ty>
class myStack {
public:
	_Ty* pNode;
	int len;
	int maxLen;
public:
	myStack() { pNode = NULL; len = maxLen = 0; }
	~myStack()
	{
		if (pNode)
		{
			delete[] pNode;
			pNode = NULL;
			len = maxLen = 0;
		}
	}
	//入栈
	void push(const _Ty& data);
	//出栈
	void pop() { if (len > 0)len--; }
	//获取当前栈顶元素  因为不知道创建的是什么类型,所以用_Ty
	_Ty getTop() { return pNode[len - 1]; }
	//判断栈是否为空
	bool isEmpty() { return (len == 0); }
};

//入栈
template<class _Ty>
void myStack<_Ty>::push(const _Ty& data)
{
	if (maxLen<=len)
	{//判断需要申请的内存 >>右移,等同于/2
		maxLen = maxLen + (((maxLen >> 1) > 1) ? (maxLen >> 1) : 1);	
	}
	_Ty* pNew = new _Ty[maxLen];
	if (pNode)
	{
		memcpy(pNew, pNode, sizeof(_Ty) * len);
		delete[] pNode;
	}
	pNode = pNew;
	pNew[len++] = data;

}

 cpp文件:

#include"testZhang.h"
#include<graphics.h>

using namespace std;
#define ROWS 10
#define COLS 10

//方向枚举
enum direct { p_up, p_right, p_down, p_left };//0,1,2,3
//辅助地图
struct pathNode
{
	int dir;		//方向
	bool isFind;	//是否走过,0没走过 ,1走过
};
//点类型
struct MyPoint
{
	int row;
	int col;
	bool operator==(const MyPoint& p1)
	{
		if (row == p1.row && col == p1.col)
		{
			return true;
		}
		return false;
	}
};
//正方形宽高
#define SPACE 80
IMAGE ren, road, wall, endpos;
void initGame();
void drawMap(int map[ROWS][COLS], MyPoint pos);
void printMap(int map[ROWS][COLS], MyPoint pos);
int main()
{
	initGame();
	//地图
	int map[ROWS][COLS] = {
		{1,1,1,1,1,1,1,1,1,1},
		{1,0,1,1,0,1,0,0,0,1},
		{1,0,1,0,0,0,0,1,1,1},
		{1,0,0,0,1,1,0,0,0,1},
		{1,0,1,0,0,0,1,0,1,1},
		{1,0,1,1,1,0,0,0,1,1},
		{1,0,0,0,1,0,1,0,1,1},
		{1,0,1,1,1,0,1,0,1,1},
		{1,1,1,0,0,0,0,0,0,1},
		{1,1,1,1,1,1,1,1,1,1}
	};
	pathNode pathMap[ROWS][COLS] = { 0 };
	//回退功能,可以用标准模板库的栈结构,也可以自己写  这里我自己做一个
	//准备一个栈
	myStack<MyPoint> stack;
	//起点 和 终点
	MyPoint begPos = { 1,1 };
	MyPoint endPos = { 8,3 };
	//起点入栈
	stack.push(begPos);
	//标记起点走过
	pathMap[begPos.row][begPos.col].isFind = true;
	//当前点
	MyPoint currentPos = begPos;
	//试探点
	MyPoint searchPos;
	//是否找到终点
	bool isFind = false;
	while (1)//循环寻路
	{
		//找出试探点
		searchPos = currentPos;
		switch (pathMap[currentPos.row][currentPos.col].dir)//是什么方向
		{
		case p_up:
			searchPos.row--;
			//更改当前点的试探方向 通过枚举的++改变方向
			pathMap[currentPos.row][currentPos.col].dir++;
			//判断能否走
			if (map[searchPos.row][searchPos.col] == 0 &&//是路 
				pathMap[searchPos.row][searchPos.col].isFind == false)
			{//能走
				//走
				currentPos = searchPos;

				//标记当前点走过
				pathMap[currentPos.row][currentPos.col].isFind = true;
				//入栈
				stack.push(currentPos);
			}
			break;
		case p_right:
			searchPos.col++;
			//更改当前点的试探方向 通过枚举的++改变方向
			pathMap[currentPos.row][currentPos.col].dir++;
			//判断能否走
			if (map[searchPos.row][searchPos.col] == 0 &&//是路 
				pathMap[searchPos.row][searchPos.col].isFind == false)
			{//能走
				//走
				currentPos = searchPos;

				//标记当前点走过
				pathMap[currentPos.row][currentPos.col].isFind = true;
				//入栈
				stack.push(currentPos);
			}
			break;
		case p_down:
			searchPos.row++;
			//更改当前点的试探方向 通过枚举的++改变方向
			pathMap[currentPos.row][currentPos.col].dir++;
			//判断能否走
			if (map[searchPos.row][searchPos.col] == 0 &&//是路 
				pathMap[searchPos.row][searchPos.col].isFind == false)
			{//能走
				//走
				currentPos = searchPos;

				//标记当前点走过
				pathMap[currentPos.row][currentPos.col].isFind = true;
				//入栈
				stack.push(currentPos);
			}
			break;
		case p_left:
			searchPos.col--;
			//因为往左是最后一个方向,所有可以赋值为0 也可以不搞
			//判断能否走
			if (map[searchPos.row][searchPos.col] == 0 &&//是路 
				pathMap[searchPos.row][searchPos.col].isFind == false)
			{//能走
				//走
				currentPos = searchPos;

				//标记当前点走过
				pathMap[currentPos.row][currentPos.col].isFind = true;
				//入栈
				stack.push(currentPos);
			}
			else//死胡同
			{
				stack.pop();//删除顶元素
				currentPos = stack.getTop();//跳到栈顶元素
			}
			break;
		}

		//延迟看效果
		Sleep(100);
		drawMap(map, currentPos);
		printMap(map, currentPos);


		//判断是否到达终点
		if (endPos == currentPos)
		{
			isFind = true;
			break;
		}
		//判断栈是否为空
		if (stack.isEmpty())
		{
			break;
		}
	}
	int x, y;
	if (isFind)
	{
		cout << "找到终点了";
		while (!stack.isEmpty())
		{
			x = stack.getTop().row;
			y = stack.getTop().col;
			cout << "[" << x << "," << y << "]  ";
			putimage(y* SPACE+SPACE/4 , x* SPACE+SPACE/4 , &endpos);//找到终点后显示路径
			stack.pop();
		}
		cout << endl;
	}

	while (1) {}
	return 0;
}

void initGame()
{
	initgraph(COLS * SPACE, ROWS * SPACE, SHOWCONSOLE);

	loadimage(&ren, "res/pic_ShengDu/ren.bmp", SPACE, SPACE, true);
	loadimage(&wall, "res/pic_ShengDu/wall.bmp", SPACE, SPACE, true);
	loadimage(&road, "res/pic_ShengDu/road.bmp", SPACE, SPACE, true);
	loadimage(&endpos, "res/pic_ShengDu/pos.bmp", SPACE/2, SPACE/2, true);
}
void printMap(int map[ROWS][COLS], MyPoint pos)
{
	system("cls");
	for (int i = 0; i < ROWS; i++)
	{
		for (int k = 0; k < COLS; k++)
		{
			if (i == pos.row && k == pos.col)
			{
				cout << "人";
			}
			else if (1 == map[i][k])
			{
				cout << "墙";
			}
			else if (0 == map[i][k])
			{
				cout << "  ";
			}
		}
		cout << endl;
	}
}
void drawMap(int map[ROWS][COLS], MyPoint pos)
{
	system("cls");
	for (int i = 0; i < ROWS; i++)
	{
		for (int k = 0; k < COLS; k++)
		{
			if (i == pos.row && k == pos.col)
			{
				putimage(k * SPACE, i * SPACE, &ren);
			}
			else if (1 == map[i][k])
			{
				putimage(k * SPACE, i * SPACE, &wall);
			}
			else if (0 == map[i][k])
			{
				putimage(k * SPACE, i * SPACE, &road);
			}
		}
	}
}

结束效果:

命令行效果:

 图片效果:

猜你喜欢

转载自blog.csdn.net/q244645787/article/details/126858972