maze走迷宫-C++

迷宫程序实际上是图的遍历的应用,只是在本例中迷宫的每个入口都是只有4个方向(上下左右),而在图中每个顶点可以有任意个邻接顶点,邻接顶点之间也可以有回环。在遍历时可以使用递归调用(占用系统栈空间),也可以在遍历过程中把信息存入自己建立的容器(栈适合于深度优先遍历, 后进先出的特点);从一个顶点v到他的未访问的邻接顶点有多个路径,既然深入下去一条,就需要记住其他几条路径(也就是v的其他未访问的邻接顶点),或者至少记住未访问的路径的所有公共顶点(也即v),这种会节省栈空间,但是略麻烦,需要重新寻找v的all adjacent vertex,如果graph存储为martrix,总体需要查找时间为O(V平方),如果为adjacent list结构总体需要O(E)。

在这个maze例子中就是用DFS深度优先遍历,直到找出出口。

边界border用1表示,通路用0表示,入口用m表示,出口用e表示,访问过标志用,表示。

#pragma once
#include <iostream>
#include <string>
#include <stack>
using namespace std;

template<class T>
class Stack : public stack<T>
{
public:
	T pop()
	{
		T tmp = top();
		stack<T>::pop();
		return tmp;
	}
};

class Cell
{
	friend class Maze;
public:
	Cell(int i = 0, int j = 0) : x(i), y(j) {  }
	bool operator==(const Cell &c) const
	{
		return x == c.x && y == c.y;
	}
private:
	int x, y;
};

class Maze {
public:
	Maze();
	void exitMaze();
private:
	Cell currentCell, exitCell, entryCell;
	const char exitMarker, entryMarker, visited, passage, wall;
	Stack<Cell> mazeStack;
	char **store;         // array of strings;
	void pushUnvisited(int, int);
	int rows, cols;
	friend ostream& operator<< (ostream& out, const Maze& maze) {
		for (int row = 0; row <= maze.rows + 1; row++)
			out << maze.store[row] << endl;
		out << endl;
		return out;
	}
};

Maze::Maze() : exitMarker('e'), entryMarker('m'), visited(','),
passage('0'), wall('1') {
	char str[80], *s;
	int col, row = 0;
	Stack<char*> mazeRows;
	cout << "Enter a rectangular maze using the following "
		<< "characters:\nm - entry\ne - exit\n1 - wall\n 0 - passage"
		<< "\nEnter one line at a time, end with ctrl-z:\n";
	while (cin >> str) {
		row++;
		cols = strlen(str);
		s = new char[cols + 3];	// two borders and a \0
		mazeRows.push(s);
		strcpy(s + 1, str);
		s[0] = s[cols + 1] = wall;
		s[cols + 2] = '\0';

		if (strchr(s, exitMarker) != nullptr)
			exitCell = Cell(row, strchr(s, exitMarker) - s);
		if (strchr(s, entryMarker) != nullptr)
			entryCell = Cell(row, strchr(s, entryMarker) - s);
	}
	rows = row;
	store = new char*[rows + 2];	// add up and bottem border
	store[0] = new char[cols + 3];
	store[rows + 1] = new char[cols + 3];
	while (!mazeRows.empty())
		store[row--] = mazeRows.pop();
	
	store[0][cols + 2] = store[rows + 1][cols + 2] = '\0';
	for (col = 0; col <= cols + 1; ++col) {
		store[0][col] = wall;         // fill the borderline rows with 1s;
		store[rows + 1][col] = wall;
	}
}

void Maze::pushUnvisited(int row, int col)
{
	if (store[row][col] == passage || store[row][col] == exitMarker)
		mazeStack.push(Cell(row, col));
}

void Maze::exitMaze()
{
	int row, col;
	currentCell = entryCell;
	while (!(currentCell == exitCell)) {
		row = currentCell.x;
		col = currentCell.y;
		cout << *this;
		if (!(currentCell == entryCell))
			store[row][col] = visited;
		pushUnvisited(row - 1, col);
		pushUnvisited(row + 1, col);
		pushUnvisited(row, col - 1);
		pushUnvisited(row, col + 1);
		// 栈为空,说明已经没有可以试的路径了
		if (mazeStack.empty()) {
			cout << *this;
			cout << "Falure.\n";
			return;
		}
		else
			currentCell = mazeStack.pop();
	}
	cout << *this;
	cout << "Success.\n";
}


int main()
{
	Maze maze;
	maze.exitMaze();

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值