⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maze.cpp

📁 我们数据结构课的课程设计
💻 CPP
字号:
///////////////////////////////////////////////////////////////
// 文件名:maze.cpp
// 作者:施自成,韩小龙,何键,陈文豪,陈卓
// 
// A*算法流程
// A*是启发试搜索加动态规划。
// 具体实现依靠两个队列Open队列和Close队列。从一点访问四周
// 相邻的格子如果可以移动且当前移动为起点到哪个格子的历史最
// 佳方法则把那个格子按照估价值从小到大插入Open队列里面,几
// 个方向试探结素后取出估价值最小的节点放入Close再从这里开
// 始试探几个相邻的方向同样放入Open队列里面,放入Open的条件
// 是:
// 1.这步在地图上面是可以移动的,
// 2.这步所在节点在Open里面并不存在,
// 3.从起点到这步的实际距离比这点的历史最小距离
//  还短满足这三个条件就把节点放入Open队列。
///////////////////////////////////////////////////////////////

// stdafx.h 包含一些常用的头文件,用于加快编译速度
// 
#include "stdafx.h"
#include "glval.h" 

char matrix[100][100];
char BufferMatrix[100][100];
list<node> open; // 链表,用来保存未扩展的节点
stack<node> close; // 栈,用来保存已扩展的节点
list<node> path; // 链表,用于保存找到的路径
list<node>::iterator iter; // 迭代器,用来对链表进行访问的指针 
// STL常用操作:
// 对象名.empty() // 判断链表是否为空
// 对象名.push(要保存的值)  // 入栈
// 对象名.pop() // 出栈
// 对象名.push_front(要保存的值), 对象名.push_back(要保存的值)// 保存到最前面或最后面
// 对象名.pop_front(), 对象名.pop_back()// 删除最前面或最后面的元素
// iter = 对象名.begin()  // 使iter指向数据结构中的第一个元素
// iter != 对象名.end()  // 比较 iter和数据结构中的最后一个元素

/////////////////////////////////////////////////////////////
// 根据matrix找到最短路径,并将结果保存在path链表中
// 返回 false 表示走不出
// 返回 true 表示已经找到路径
bool findpath()
{
    int i,j; 
	// 在迷宫的四周围填充1
	for (i=0; i<maze_width+2; i++)
	{
		BufferMatrix[0][i] = '1';  
		BufferMatrix[i][maze_width+1] = '1';  
	}
	for (i=0; i<maze_height+2; i++)
	{
		BufferMatrix[i][0] = '1';  
		BufferMatrix[maze_height+1][i] = '1';  
	}
	// 保存迷宫 
	for (i=1; i<maze_height+1; i++)
	{
		for (j=1; j<maze_width+1; j++)
		{
			BufferMatrix[i][j] =  matrix[i-1][j-1];  
		}
	}

	// 用来记录当前节点是否有扩展节点
	bool sign; 

	// tmp用来保存当前节点
	// tmp1用来保存扩展节点
	node tmp, tmp1;  
	tmp.x = 1; 
	tmp.y = 1; 
	tmp.gn = 1; 
	// ★ f(n) = g(n) + h(n) 
	// 其中f(n)为估价函数,表示从起点到终点的路径总长度 
	// ★ g(n)表示从起点到当前节点所走过的路 
	// ★ h(n)表示从当前节点到终点的最短路径 
	int hn = (maze_width-tmp.x)>(maze_height-tmp.y)?(maze_width-tmp.x):(maze_height-tmp.y); 
	tmp.fn = tmp.gn +  hn; 
	// 如果入口堵住,则走不出 
	if (BufferMatrix[1][1] != '0') 
	{
		return false; 
	} 
	// 保存进链表
	open.push_back(tmp); 
	while (!open.empty()) 
	{ 
		sign = false; 
		// 根据fn对open表进行排序
		open.sort(); 
		// 取链表中最后一个元素 
		// 即,fn最小的元素 
		tmp = open.back(); 
		open.pop_back(); 
		close.push(tmp); 
		// 找到出口
		if ((tmp.x == maze_width) && (tmp.y == maze_height))  
			break;
		// 加入8个方向的扩展节点 
		tmp.gn++; 
		// 向右走 
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y][tmp1.x+1] == '0') 
		{ 
			sign = true; 
			// 走过的地方置1
			BufferMatrix[tmp1.y][tmp1.x+1] = '1'; 
			tmp1.x++; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		} 
		// 向右下方走 
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y+1][tmp1.x+1] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y+1][tmp1.x+1] = '1'; 
			tmp1.x++; 
			tmp1.y++; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn;  
			open.push_back(tmp1); 
		}
		// 向下走 
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y+1][tmp1.x] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y+1][tmp1.x] = '1'; 
			tmp1.y++;
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		}
		// 向右上方走
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y-1][tmp1.x+1] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y-1][tmp1.x+1] = '1'; 
			tmp1.x++; 
			tmp1.y--; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		}
		// 向左下方走
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y+1][tmp1.x-1] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y+1][tmp1.x-1] = '1'; 
			tmp1.y++; 
			tmp1.x--; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		}
		// 向左边走
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y][tmp1.x-1] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y][tmp1.x-1] = '1'; 
			tmp1.x--; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		}
		// 向左上方走
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y-1][tmp1.x-1] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y-1][tmp1.x-1] = '1'; 
			tmp1.x--; 
			tmp1.y--; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		}
		// 向上走
		tmp1 = tmp; 
		if (BufferMatrix[tmp1.y-1][tmp1.x] == '0')
		{
			sign = true; 
			BufferMatrix[tmp1.y-1][tmp1.x] = '1'; 
			tmp1.y--; 
			hn = (maze_width-tmp1.x)>(maze_height-tmp1.y)?(maze_width-tmp1.x):(maze_height-tmp1.y); 
			tmp1.fn = tmp1.gn + hn; 
			open.push_back(tmp1); 
		}
		// 无路可走
		if (sign == false)
		{
			close.pop(); 
		}
	}
	if (open.empty())
	{
		return false; 
	}
	else
	{
		// 从出口回溯,找到路径
		tmp = close.top(); 
		close.pop(); 
		while (!close.empty())
		{
			tmp1 = close.top(); 
			close.pop(); 
			// 比较tmp1节点是不是tmp的前一个节点
			// 是前一个节点的条件是:
			// 两者的横纵坐标差不超过1,
			// tmp的gn即步数,等于tmp1的gn+1
			if (abs(tmp.x - tmp1.x) <= 1 &&
				abs(tmp.y - tmp1.y) <= 1 &&
				(tmp.gn == (tmp1.gn + 1)))
			{
				path.push_front(tmp); 
				tmp = tmp1; 
			}
		}
		path.push_front(tmp); 
	}
	open.clear(); 

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -