走迷宫以及求迷宫最优解

走迷宫可以用递归也可以用非递归来解决:
#include <iostream>
#include <assert.h>
#include <stack>
using namespace std;

template<size_t M, size_t N>
class Maze
{
public:
	Maze(int maze[M][N])
	{
		for (size_t i = 0; i < M; i++)
		{
			for (size_t j = 0; j < N; j++)
			{
				_maze[i][j] = maze[i][j];
			}
		}
	}

	struct Pos  //迷宫中的每一个位置都用坐标来表示,用结构体来保存这个位置
	{
		int _row;
		int _col;
	};
	 
	bool CheckAccess(Pos next)  //检查下一个位置是否可通
	{
		if ((next._row >= 0 && next._row < M) && (next._col >= 0 && next._col < N) && _maze[next._row][next._col] == 0)
		{
			return true;
		}

		return false;
	}

	bool GetMazePath(Pos entry)  //获取迷宫的通路
	{
		stack<Pos> path;
		path.push(entry);

		while (!path.empty())
		{
			Pos cur = path.top();  //栈顶就是当前位置
			_maze[cur._row][cur._col] = 2;  // 把走过的位置设置为2

			if (cur._row == M - 1)  //当前位置就是出口,此处认为出口的cow==M-1
			{
				return true;
			}

			//试探当前位置的上下左右四个位置
			//试探上
			Pos next = cur;
			next._row -= 1;
			if (CheckAccess(next))
			{
				path.push(next);
				continue;
			}

			//试探下
			next = cur; //每次都要回到当前位置再继续试探
			next._row += 1;
			if (CheckAccess(next))
			{
				path.push(next);
				continue;
			}

			//试探左
			next = cur;
			next._col -= 1;
			if (CheckAccess(next))
			{
				path.push(next);
				continue;
			}

			//试探右
			next = cur;
			next._col += 1;
			if (CheckAccess(next))
			{
				path.push(next);
				continue;
			}

			Pos back = path.top();
			_maze[back._row][back._col] = 3; //回溯过的位置设置为3
			path.pop();  
		}

		return false;
	}

	bool GetMazePathR(Pos entry)  //递归获取迷宫的通路
	{
		Pos cur = entry;
		_maze[cur._row][cur._col] = 2;

		if (cur._row == M - 1)
		{
			return true;
		}

		//试探右
		Pos next = cur;
		next._col += 1;
		if (CheckAccess(next))
		{
			if (GetMazePathR(next))
				return true;
		}

		//试探上
	    next = cur;
		next._row -= 1;
		if (CheckAccess(next))
		{
			if (GetMazePathR(next))
				return true;
		}

		//试探下
		next = cur;
		next._row += 1;
		if (CheckAccess(next))
		{
			if (GetMazePathR(next))
				return true;
		}

		//试探左
		next = cur;
		next._col -= 1;
		if (CheckAccess(next))
		{
			if (GetMazePathR(next))
				return true;
		}
		
		_maze[cur._row][cur._col] = 3;
		return false;
	}

	void Print()
	{
		for (size_t i = 0; i < M; i++)
		{
			for (size_t j = 0; j < N; j++)
			{
				cout << _maze[i][j] << " ";
			}
			cout << endl;
		}
		cout << endl;
	}

protected:
	int _maze[M][N];
};

以下是测试代码:

#include "Maze.h"

void ReadMaze(int maze[10][10])
{
	FILE* fout = fopen("MazeMap.txt", "r");
	assert(fout);

	for (size_t i = 0; i < 10; i++)
	{
		for (size_t j = 0; j < 10;)
		{
			char ch = fgetc(fout);
			if (ch == '0' || ch == '1')
			{
				maze[i][j] = ch - '0';
				j++;
			}
		}
	}
	fclose(fout);
}

void Test()
{
	int maze[10][10];
	ReadMaze(maze);

	Maze<10, 10> m(maze);
	m.Print();
	Maze<10, 10>::Pos entry;
	entry._row = 2;
	entry._col = 0;
	m.GetMazePath(entry);
	//m.GetMazePathR(entry);
	m.Print();
}

int main()
{
	Test();

	system("pause");
	return 0;
}
输出结果:



以下为求迷宫最优解的代码:

bool CheckAccess(Pos cur, Pos next)
	{
		if ((next._row >= 0 && next._row < M) && (next._col >= 0 && next._col < N))
		{
			if (_maze[next._row][next._col] == 0 || _maze[next._row][next._col] > _maze[cur._row][cur._col])//迷宫的下一个位置的值为0或者必须必当前位置大才可通
			{
				return true;
			}
		}

		return false;
	}

	void GetShortPath(Pos entry, stack<Pos>& path, stack<Pos>& shortPath)
	{
		Pos cur = entry;
		path.push(cur);

		if (cur._row == M - 1)
		{
			if (shortPath.empty() || shortPath.size() > path.size())
			{
				shortPath = path;
			}
			//Print();
		}

		//试探当前位置的上下左右四个位置
		//试探上
		Pos next = cur;
		next._row -= 1;
		if (CheckAccess(cur, next))
		{
			_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
			GetShortPath(next, path, shortPath);
		}
		//试探下
		next = cur;
		next._row += 1;
		if (CheckAccess(cur, next))
		{
			_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
			GetShortPath(next, path, shortPath);
		}
		//试探左
		next = cur;
		next._col -= 1;
		if (CheckAccess(cur, next))
		{
			_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
			GetShortPath(next, path, shortPath);
		}
		//试探右
		next = cur;
		next._col += 1;
		if (CheckAccess(cur, next))
		{
			_maze[next._row][next._col] = _maze[cur._row][cur._col] + 1;
			GetShortPath(next, path, shortPath);
		}

		path.pop();
	}

测试代码如下:

void ReadMaze(int maze[10][10])
{
	FILE* fout = fopen("MazeMap.txt", "r");
	assert(fout);

	for (size_t i = 0; i < 10; i++)
	{
		for (size_t j = 0; j < 10;)
		{
			char ch = fgetc(fout);
			if (ch == '0' || ch == '1')
			{
				maze[i][j] = ch - '0';
				j++;
			}
		}
	}
	fclose(fout);
}

void Test()
{
	int maze[10][10];
	ReadMaze(maze);

	Maze<10, 10> m(maze);
	m.Print();
	Maze<10, 10>::Pos entry;
	entry._row = 2;
	entry._col = 0;

	stack<Maze<10, 10>::Pos> path, shortPath;
	m.GetShortPath(entry, path, shortPath);
	m.Print();
}

int main()
{
	Test();

	system("pause");
	return 0;
}

输出结果:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值