迷宫找出口,找最近出口

        迷宫中存在起点与终点,墙壁用数字2表示,行走路线用数字1表示,可行走的点用0表示。

#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <iterator>
using namespace std;

//5(一)
class CMaze
{
public:
	CMaze()
	{
		int iSize = 6;
		_maze_info.resize(iSize);
		for (int i = 0; i < iSize; ++i)
		{
			for (int j = 0; j < iSize; ++j)
			{
				if (i == 0 || j == 0 || i == iSize-1 || j == iSize-1)
				{
					_maze_info[i].push_back(2);
				}
				else
				{
					_maze_info[i].push_back(0);
				}
			}
		}
		_maze_info[1][2] = 2;
		_maze_info[2][2] = 2;
		_maze_info[3][2] = 2;
		//_maze_info[4][2] = 2;
		_begin_point = make_pair<int, int>(1, 1);
		_end_point = make_pair<int, int>(4, 4);
	}
	bool findOutRoad()
	{
		//return findOutRoadOne(_begin_point.first, _begin_point.second);
		vector<pair<int, int>> veRoad;
		return findOutRoadAll(_begin_point.first, _begin_point.second, veRoad);
	}
	//是否可以走出去
	bool findOutRoadOne(int x, int y)
	{
		//cout << "---------------------" << endl;
		//show();
		if (x == _end_point.first && y == _end_point.second)
			return true;
		_maze_info[x][y] = 1;
		if (_maze_info[x - 1][y] == 0) return findOutRoadOne(x - 1, y);
		else if (_maze_info[x][y - 1] == 0) return findOutRoadOne(x, y - 1);
		else if (_maze_info[x + 1][y] == 0) return findOutRoadOne(x + 1, y);
		else if (_maze_info[x][y + 1] == 0) return findOutRoadOne(x, y + 1);
		else
			return false;
	}
	//路线
	bool findOutRoadAll(int x, int y, std::vector<pair<int, int>> &road)
	{
		if (x == _end_point.first && y == _end_point.second)
		{
			for (auto &it : road)
			{
				cout << "road: " << it.first << " - " << it.second << endl;
			}
			cout << endl;
			return true;
		}
		bool bRet = false;
		_maze_info[x][y] = 1;
		road.push_back(std::make_pair(x-1, y));
		if (_maze_info[x - 1][y] == 0) bRet = findOutRoadAll(x - 1, y, road);
		if (bRet) return true;
		road.pop_back();
		road.push_back(std::make_pair(x, y-1));
		if (_maze_info[x][y - 1] == 0) bRet = findOutRoadAll(x, y - 1, road);
		if (bRet) return true;
		road.pop_back();
		road.push_back(std::make_pair(x + 1, y));
		if (_maze_info[x + 1][y] == 0) bRet = findOutRoadAll(x + 1, y, road);
		if (bRet) return true;
		road.pop_back();
		road.push_back(std::make_pair(x, y+1));
		if (_maze_info[x][y + 1] == 0) bRet = findOutRoadAll(x, y + 1, road);
		return bRet;
	}
	void show()
	{
		for (int i = 0; i < _maze_info.size(); ++i)
		{
			for (int j = 0; j < _maze_info[i].size(); ++j)
				cout << _maze_info[i][j] << "  ";
			cout << endl;
		}
		cout << endl;
	}


	vector<vector<int>> _maze_info;
	pair<int, int> _begin_point;     //开始
	pair<int, int> _end_point;       //结束
};

       以上代码只能表示是否出去与其中的路线打印,但是并不是最近的路线。寻找最近路线,需要每次向着终点的方向前进,可以使用简化版A*算法。

class AStar
{
public:
	struct stRoadInfo
	{
		int iPosx = 0;
		int iPosy = 0;
		int iFPosx = 0;
		int iFPosy = 0;
		int iVal = 0;
	};
	AStar()
	{
		int iSize = 6;
		_maze_info.resize(iSize);
		for (int i = 0; i < iSize; ++i)
		{
			for (int j = 0; j < iSize; ++j)
			{
				if (i == 0 || j == 0 || i == iSize - 1 || j == iSize - 1)
				{
					_maze_info[i].push_back(2);
				}
				else
				{
					_maze_info[i].push_back(0);
				}
			}
		}
		_maze_info[1][2] = 2;
		_maze_info[2][2] = 2;
		_maze_info[3][2] = 2;
		//_maze_info[4][2] = 2;
		_begin_point = make_pair<int, int>(1, 1);
		_end_point = make_pair<int, int>(4, 4);
	}
	bool find_road()
	{
		stRoadInfo info;
		build_roadinfo(_begin_point, std::make_pair(0, 0), info);
		openlist.insert(std::make_pair(info.iVal, info));
		while (1)
		{
			auto itopen = openlist.begin();
			if (itopen == openlist.end())
			{
				return false;
			}
			std::pair<int, int> pairtmp = std::make_pair(itopen->second.iPosx, itopen->second.iPosy);
			closelist.insert(std::make_pair(pairtmp, itopen->second));
			openlist.erase(itopen);
			if (get_instance(pairtmp) == 0)
			{
				while (pairtmp.first != 0 && pairtmp.second != 0)
				{
					auto it = closelist.find(pairtmp);
					if (it == closelist.end()) break;
					cout << pairtmp.first << " - " << pairtmp.second << endl;
					pairtmp = std::make_pair(it->second.iFPosx, it->second.iFPosy);
				}
				return true;
			}
			//方向
			if (_maze_info[pairtmp.first - 1][pairtmp.second] == 0 && closelist.find(std::make_pair(pairtmp.first - 1, pairtmp.second)) == closelist.end())
			{
				stRoadInfo info;
				build_roadinfo(std::make_pair(pairtmp.first-1, pairtmp.second), pairtmp, info);
				openlist.insert(std::make_pair(info.iVal, info));
			}
			if (_maze_info[pairtmp.first][pairtmp.second-1] == 0 && closelist.find(std::make_pair(pairtmp.first, pairtmp.second-1)) == closelist.end())
			{
				stRoadInfo info;
				build_roadinfo(std::make_pair(pairtmp.first, pairtmp.second-1), pairtmp, info);
				openlist.insert(std::make_pair(info.iVal, info));
			}
			if (_maze_info[pairtmp.first + 1][pairtmp.second] == 0 && closelist.find(std::make_pair(pairtmp.first + 1, pairtmp.second)) == closelist.end())
			{
				stRoadInfo info;
				build_roadinfo(std::make_pair(pairtmp.first + 1, pairtmp.second), pairtmp, info);
				openlist.insert(std::make_pair(info.iVal, info));
			}
			if (_maze_info[pairtmp.first][pairtmp.second+1] == 0 && closelist.find(std::make_pair(pairtmp.first, pairtmp.second+1)) == closelist.end())
			{
				stRoadInfo info;
				build_roadinfo(std::make_pair(pairtmp.first, pairtmp.second+1), pairtmp, info);
				openlist.insert(std::make_pair(info.iVal, info));
			}
		}
	}
	void build_roadinfo(std::pair<int, int> &pos, std::pair<int, int> &fpos, AStar::stRoadInfo &info)
	{
		info.iPosx = pos.first;
		info.iPosy = pos.second;
		info.iFPosx = fpos.first;
		info.iFPosy = fpos.second;
		info.iVal = get_instance(pos);
	}
	int get_instance(std::pair<int, int> &begin)
	{
		return abs(begin.first - _end_point.first) + abs(begin.second - _end_point.second);
	}
private:
	vector<vector<int>> _maze_info;
	pair<int, int> _begin_point;     //开始
	pair<int, int> _end_point;       //结束

	std::multimap<int, stRoadInfo> openlist;
	std::map<std::pair<int, int>, stRoadInfo> closelist;
};

 

#include #include #define N1 9 #define N2 8 #define T N1*N2 #define M 4 char B[N1+1][N2+1]; int count=0; //记录路径条数 typedef struct node1 { int a1; int a2; }find,direct[M+1]; typedef struct { int b1; int b2; int id; }site; typedef struct //顺序栈 { site ht[T]; int top; }Stack; void Push(Stack *s,int a,int b) { s->top++; s->ht[s->top].b1=a; s->ht[s->top].b2=b; } void Gettop(Stack * s,int *a,int *b) { *a=s->ht[s->top].b1; *b=s->ht[s->top].b2; } void create(char *a) //从文件读出迷宫(正确) { int i=0,j=0,p=1; char x; FILE *fp; fp=fopen("in.txt","r"); if(fp==NULL) { printf("文件不能打开!\n"); exit(0); } x=fgetc(fp); while(x!=EOF) { if(x=='0') { i++; a[i]=x; } if(x=='1') { i++; a[i]=x; } x=fgetc(fp); } printf(" ~~~~~~~生成迷宫~~~~~~~\n"); x=fgetc(fp); while(p<=T) //用二维数组b记录迷宫每个位置是否可行 { for(i=1;i<=N1;i++) for(j=1;j<=N2;j++) { B[i][j]=a[p]; p++; } } printf(" "); printf("■■■■■■■■■■■■\n"); printf(" ■"); printf(" ■\n"); for(i=1;i<=N1;i++) { printf(" "); printf("■ "); for(j=1;jht[s1->top].id=id; B[x][y]='*'; while(s1->top>0) { Gettop(s1,&x,&y); id=s1->ht[s1->top].id; if(x==B1&&y==B2) { count++; fprintf(fp,"%d%c%c",count,':',' '); printf("第 %d 条路径(长度为%d):\n",count,s1->top); s1->ht[s1->top].id=0; for(i=1;itop;i++) { printf("(%d,%d,%d)->",s1->ht[i].b1,s1->ht[i].b2,s1->ht[i].id); fprintf(fp,"%c%d%c%d%c%d%c%c",'(',s1->ht[i].b1,',',s1->ht[i].b2,',',s1->ht[i].id,')',' '); if(i==0) fprintf(fp,"%c%c%c%c",'\n',' ',' ',' '); if(i%8==0) printf("\n"); } fprintf(fp,"%c",'\n'); printf("结束!\n\n"); if(s1->toptop=s1->top; min=s1->top; for(i=1;itop;i++) s2->ht[i]=s1->ht[i]; } B[x][y]='0'; s1->top--; //退栈(s1->top--) Gettop(s1,&x,&y); id=s1->ht[s1->top].id; } fun=0; while(idht[s1->top].b1; y=s1->ht[s1->top].b2; x=x+p[id].a1; y=y+p[id].a2; if(x==0||y==0||x>N1||y>N2) continue; if(B[x][y]=='0') { fun=1; break; } } if(fun==1) //找到通路 { s1->ht[s1->top].id=id; Push(s1,x,y); B[x][y]='*'; s1->ht[s1->top].id=0; } else { x=s1->ht[s1->top].b1; y=s1->ht[s1->top].b2; B[x][y]='0'; s1->top--; } } if(count==0) printf(" 无路径!\n"); else { printf("\n\n\n "); printf("所有路径已存储在文件%s 中,请去查!\n\n",filename); } return 1; } void Print(Stack *s2,char filename[]) { int i; FILE *fp; fp=fopen(filename,"a+"); if(fp==NULL) { printf("文件不能打开!\n"); exit(0); } if(count!=0) { fprintf(fp,"%s","最短路径为:"); fprintf(fp,"%c",'\n'); printf(" "); printf("%s\n","**********最短路径**********\n"); for(i=1;itop;i++) { printf("(%d,%d,%d) ->",s2->ht[i].b1,s2->ht[i].b2,s2->ht[i].id); fprintf(fp,"%c%d%c%d%c%d%c%c",'(',s2->ht[i].b1,',',s2->ht[i].b2,',',s2->ht[i].id,')',' '); if(i==0) fprintf(fp,"%c",'\n'); if(i%7==0) printf("\n"); } fprintf(fp,"%c",'\n'); printf("结束!\n"); printf("(最短路径长度: %d)\n",s2->top); } } void main() //主函数 { char a[T+1]; //二维数组b记录迷宫的每个位置 char filename1[20],filename2[20]; int x1,x2,y1,y2,k; Stack *s1,*s2; direct f1; f1[1].a1=0; f1[1].a2=1; //判断方向(右) f1[2].a1=1; f1[2].a2=0; //(下) f1[3].a1=0; f1[3].a2=-1; //(左) f1[4].a1=-1; f1[4].a2=0; //(上) s1=(Stack *)malloc(sizeof(Stack)); s2=(Stack *)malloc(sizeof(Stack)); s1->top=0; //指向栈顶(初始化栈) s2->top=0; create(a); printf("\n\n "); printf("请输入入口坐标: "); scanf("%d%d",&x1,&x2); printf(" "); printf("请输入出口坐标: "); scanf("%d%d",&y1,&y2); printf(" "); printf("请输入存储所有路径的文件名:"); scanf("%s",filename1); printf(" "); printf("请输入存储最短路径的文件名:"); scanf("%s",filename2); system("cls"); k=search(x1,x2,y1,y2,s1,s2,f1,filename1); if(k==1) Print(s2,filename2); printf("\n"); }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值