1. 程式人生 > >使用棧求解迷宮問題C++

使用棧求解迷宮問題C++

使用棧求解迷宮問題 C++

題目:以一個 m*n 的長方陣表示迷宮,0 和 1 分別表示迷宮中的通路和障礙。設計一個程式,對任意設定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結論。 迷宮根據一個迷宮資料檔案建立。迷宮資料檔案由一個包含 0、1 的矩陣組成。迷宮的通路可以使用通路上各點的座標序列進行展示(使用圖形展示最佳)。

棧類的定義:
//這裡使用的是連結串列描述棧類,可直b接使用STL裡面的現成stack,需include stack

#include<iostream>
#include<windows.h >
using namespace std;    
template <class T>
class LinkedStack;    //使用了模板類
template <class T>
class Node {
	friend LinkedStack<T>;
private:
	T data;
	Node<T> *link;
};

template<class T>
class LinkedStack {
public:
	LinkedStack() {   //建構函式
		top=0; 
	}
	~LinkedStack();
	bool IsEmpty() const
	{
		return top == 0;
	}
	T Top() const;
	LinkedStack<T>& push(const T& x);
	LinkedStack<T>& pop();
	bool findPath();
	void init();
	void randomMaze();
	bool setPathOnMaze();
	void outputMaze(); 
	void set(int m,int n) {     //改變maze_size的值
		maze_size.row = m;
		maze_size.col = n;
	}
private:
	Node<T> *top; // 指向棧頂節點
	T maze_size = { 20,30 };   //預設為20*30的大小
	int ** const maze = new int*[maze_size.row + 2];   //二維陣列用於儲存
	T offset[4];  //儲存位置資訊

};
template<class T>    //解構函式
LinkedStack<T>::~LinkedStack()
{  Node<T>*node;
	 while (top) {
		 node = top->link;
		 delete top;
		 top = node;
	}
}
template<class T>     //獲得棧頂元素資料
T LinkedStack<T>::Top() const{
	if (IsEmpty()) { cout << "棧為空" << endl; }
	return top->data;
}
template<class T>
LinkedStack<T>& LinkedStack<T>::push(const T& x) {    //棧裡面新增元素
	Node<T> *next = new Node<T>;
	next->data = x;
	next->link = top;
	top = next;
	return *this;
}
template<class T>
LinkedStack<T>& LinkedStack<T>::pop() {   //棧裡面刪除元素
	Node<T>*next = top;
	top = top->link;
	delete next;
	return *this;

}

現在已經初始化連結串列棧stack了,現在用棧的元素,開始編寫迷宮方法

template<class T>
void LinkedStack<T>::init()
{

	//偏移
	offset[0].row = 0; offset[0].col = 1; //right
	offset[1].row = 1; offset[1].col = 0; //down
	offset[2].row = 0; offset[2].col = -1; //left
	offset[3].row = -1; offset[3].col = 0; //up

	for (int i = 0; i < maze_size.row + 2; i++)
	{
		maze[i] = new int[maze_size.col+2];
	}
}

template<class T>
void LinkedStack<T>::randomMaze()
{
	int i, j, rate;

	for (i = 0; i < maze_size.row + 2; i++)
	{
		for (j = 0; j < maze_size.col+2; j++)
		{
			//設定圍牆
			if ((i == 0) || (i == maze_size.row + 1) || (j == 0) || (j == maze_size.col + 1))
			{
				maze[i][j] =5;
			}
			else
			{
				rate = rand() % 10 + 1;   //使用隨機數方法,產生隨機數1-10
				if (rate<=2)
				{
					maze[i][j] = 1;//隨機生成障礙
				}
				else
				{
					maze[i][j] = 0;
				}
			}
		}
	}
	//最後保證起點和終點能走
	maze[1][1] = maze[maze_size.row][maze_size.col] = 0;
}

template<class T>
bool LinkedStack<T>::findPath()
{
	//POSITION here;//當前位置
	//cout << "good1" << endl;
	T here;
	here.row = here.col = 1;
	maze[1][1] = 3; //放置障礙,防止回來
	int option = 0; //next step
	const int lastOption = 3;

	//find a path
	while (here.row !=maze_size.row || here.col !=maze_size.col)
	{
		//not reach the end
		int r, c;
		while (option <= lastOption)
		{
			r = here.row +offset[option].row;
			c = here.col +offset[option].col;
			if (maze[r][c] == 0)
			{
				break;
			}
			option++;//next choice
		}

		//相鄰的位置能走?
		if (option <= lastOption)
		{
			push(here);
			here.row = r;
			here.col = c;
			maze[r][c] = 3; //走過了
			option = 0;
		}
		else
		{
			if (IsEmpty())
			{
				return false;
			}
			//go back
			maze[here.row][here.col] = 3; //此路不可通
			here =Top();
			pop();
			option = 0;
		}
	}

	maze[maze_size.row][maze_size.col] = 2;
	return true;
}

template<class T>
bool LinkedStack<T>::setPathOnMaze()    //將棧裡面的資料輸出給maze陣列的值,設為2
{
	T pos;
	if (IsEmpty()) {
		cout << endl;
		cout << "經過嘗試,迷宮沒有出路" << endl;
			return false;
	}
	while (!IsEmpty())
	{
		pos =Top();
		pop();
		maze[pos.row][pos.col] = 2;//路徑
	}
	return true;
}

//然後,可以開始輸出我們的地圖了。
template<class T>
void LinkedStack<T>::outputMaze()
{
	int i, j;
	for (i = 0; i <maze_size.row + 2; i++)
	{
		for (j = 0; j<maze_size.col + 2; j++)
		{
			if (maze[i][j] == 1)
			{
				cout << "1"<<" ";
			
			}
			else if ((maze[i][j] == 0) || (maze[i][j] == 3))
			{
			
				cout << "0"<<" ";
			}
			else if (maze[i][j] == 5)
			{
			
			}
			else
			{
				HANDLE hOut;
				hOut = GetStdHandle(STD_OUTPUT_HANDLE);
				SetConsoleTextAttribute(hOut, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
				cout << "#"<<" ";
				SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
			}
		}
		cout << endl;
	}


}

下面是main方法

typedef struct
{
	   int row;
	   int col;
	}POSITION;    //使用結構體 POSITION,來初始化位置資訊

int main()
{
	cout << "請輸入迷宮的長和寬,等下會隨機生成迷宮" << endl;
	int m, n;
	cin >> m >> n;
	LinkedStack<POSITION> path;
	path.set(m, n);
	path.init();

	path.randomMaze();
	path.outputMaze();
	cout << "**********************************************************"<<endl;
	path.findPath();
	if (path.setPathOnMaze()) {

		path.outputMaze();
	}
	return 0;
}

在這裡插入圖片描述