//--------------------文件名:Maze.cpp-------------------------
//-------------By Leon on Nov 17th,2006----------------
//说明:本程序以迷宫问题进行演示,了解栈和链表的数据结构.
//运行过程:(由于未详细设计算法,故地图较简单),
// 演示找到出口路径的过程.
//主要算法思想:
// 1.初始化迷宫,构造辅助运行栈和结果链表
// 2.从入口开始
// do
// {
// if (当前位置可通)
// {
// 当前位置入栈
// if (当前位置是出口)
// {
// 结束
// }
// else
// {
// 取得当前位置当前方向上的下一位置为当前位置
// 将新当前位置入栈
// }
// }
// else
// {
// 从栈中弹出栈顶元素为当前位置
// while(当前位置已无下一有效位置 && 栈不为空)
// {
// 将当前位置标记为无效
// 弹出栈顶元素为当前位置
// }
// if (当前位置还有下一有效位置时)
// {
// 当前位置方向调整
// 当前位置进栈
// 取得取得当前位置当前方向上的下一位置为当前位置
// }
// }
// }while(栈不为空时);
// 未找到出口
// 3.生成新地图
// 4.显示地图
//
本程序在Magic Linux与g++3.4 下编译运行成功
#include <iostream>
#include <string>
#include <list>
#include <stack>
using namespace std;
typedef unsigned int Direction;
const unsigned int MAZEWIDTH = 10; //define a Maze that in the size of 8*8
const unsigned int MAZEHEIGHT = 10;
//class MazeSymbol_t
//迷宫类型:每个迷宫格都有三种可能值:*为可通过路径 #为墙壁 @四周均不通
//
class MazeSymbol_t{
private:
char SYMBOL; //posible value are:STAR('*'),WELL('#'),AT('@')
public:
MazeSymbol_t():SYMBOL(' ') { }
MazeSymbol_t(char sibo){ setsymbol(sibo); }
//operations
char getsymbol() { return SYMBOL; }
void setsymbol(char sibo)
{
switch(sibo)
{
case' ':SYMBOL = ' ';break;
case'*':SYMBOL = '*';break;
case'#':SYMBOL = '#';break;
case'@':SYMBOL = '@';break;
}
}
};
//struct MazeType
//迷宫数组结构:二维数组矩阵表示 高宽由MAZEHEIGHT和MAZEWIDTH决定
//
typedef struct{
MazeSymbol_t mazearr[MAZEHEIGHT][MAZEWIDTH];
}MazeType;
//class MazePos
//迷宫格座标值
class MazePos
{
public:
//public varibles
unsigned int maze_x;
unsigned int maze_y;
//constructors
MazePos() //Default Construction
:maze_x(0),maze_y(0) {}
MazePos(int m_x,int m_y):maze_x(m_x),maze_y(m_y) {}
MazePos(const MazePos &mp) //copy constructor
{
maze_x = mp.maze_x;
maze_y = mp.maze_y;
}
//operations
bool operator==(const MazePos &mp)
{
return ((maze_x == mp.maze_x) && (maze_y == mp.maze_y));
}
MazePos &operator=(const MazePos &mp)
{
maze_x = mp.maze_x;
maze_y = mp.maze_y;
return (*this);
}
};
//MazePos entrance(x,y);
//迷宫入口座标值:其值规定迷宫起始座标
//
MazePos entrance(1,1);
//class SElemType
//栈类型:为了保证在任何位置上都能沿原路返回
// 需要一个后进先出的结构来保存从入口到当前位置的路径
class SElemType
{
public:
int curstep; //the "serial number" in the current position
MazePos curpos; //the location of the current position
Direction di; //the direction to the next position
SElemType(int cs = 0,MazePos cp = entrance,Direction d = 1)
:curstep(cs),curpos(cp),di(d){}
SElemType &setVal(int step,MazePos pos,Direction d)
{ curstep = step;
curpos = pos;
di = d;
return *(this);
}
bool operator==(const SElemType set)
{
return (curpos == set.curpos);
}
SElemType &operator=(const SElemType set)
{
curstep = set.curstep;
curpos = set.curpos;
di = set.di;
return (*this);
}
};
//class Maze
//迷宫:封装对迷宫矩阵的相关操作
class Maze
{
private:
MazeType maze;
public:
list<MazePos> pathpos;
list<MazePos>::iterator itr;
Maze();
bool FindMazepath(MazePos start,MazePos end); //寻找从入口点到终点的一条路径
bool Pass(MazePos curpos); //判断当前位置是否为可行块
void FootPrint(MazePos curpos); //标记当前位置可行
void MarkPrint(MazePos curpos); //标记当前位置为不通
void DisplayMaze(); //显示迷宫
MazePos NextPos(MazePos curpos,Direction di);//根据方向寻找下一目标块
};
Maze::Maze() //初使化迷宫
{//initialization the maze
int i,j;
for(i = 0;i != 10;i++)
{
maze.mazearr[0][i].setsymbol('#');
maze.mazearr[9][i].setsymbol('#');
}
for(j = 1;j != 9;j++)
{
maze.mazearr[j][0].setsymbol('#');
maze.mazearr[j][9].setsymbol('#');
}
maze.mazearr[1][3].setsymbol('#');maze.mazearr[1][7].setsymbol('#');
maze.mazearr[2][3].setsymbol('#');maze.mazearr[2][7].setsymbol('#');
maze.mazearr[3][5].setsymbol('#');maze.mazearr[3][6].setsymbol('#');
maze.mazearr[3][8].setsymbol('#');
maze.mazearr[4][2].setsymbol('#');maze.mazearr[4][3].setsymbol('#');
maze.mazearr[4][4].setsymbol('#');maze.mazearr[4][7].setsymbol('#');
maze.mazearr[5][4].setsymbol('#');
maze.mazearr[6][2].setsymbol('#');maze.mazearr[6][6].setsymbol('#');
maze.mazearr[6][8].setsymbol('#');
maze.mazearr[7][2].setsymbol('#');maze.mazearr[7][3].setsymbol('#');
maze.mazearr[7][4].setsymbol('#');maze.mazearr[7][5].setsymbol('#');
maze.mazearr[7][8].setsymbol('#');
maze.mazearr[8][1].setsymbol('#');maze.mazearr[8][2].setsymbol('#');
maze.mazearr[8][6].setsymbol('#');maze.mazearr[8][8].setsymbol('#');
}
bool Maze::FindMazepath(MazePos start,MazePos end)
{
stack< SElemType,list<SElemType> > mstack;
MazePos curpos(start);
int curstep =1;
bool found = false;
Direction di;
SElemType elem;
do{
if(Pass(curpos)){
FootPrint(curpos);
mstack.push(elem.setVal(curstep,curpos,1)); //add to the route
if(curpos == end) found = true; //arrive at the end position
else{
curpos = NextPos(curpos,1);
curstep++;
}//else
}//if
else{
if(!mstack.empty()){
elem = mstack.top();
mstack.pop();
while(elem.di == 4 &&
!mstack.empty()){
MarkPrint(elem.curpos);
elem = mstack.top();
mstack.pop();
curstep--;
}//while
if(elem.di < 4){
elem.di++;
mstack.push(elem);
curpos = NextPos(elem.curpos,elem.di);
}//if
}//if
}//else
}while(!mstack.empty() && !found);
//将可走通的路径装入列表
while(!mstack.empty()){
curpos = (mstack.top()).curpos;
pathpos.push_front(curpos);
mstack.pop();
}
return found;
}//FindMazepath
void Maze::FootPrint(MazePos curpos)
{ maze.mazearr[curpos.maze_x][curpos.maze_y].setsymbol('*'); }
void Maze::MarkPrint(MazePos curpos)
{ maze.mazearr[curpos.maze_x][curpos.maze_y].setsymbol('@'); }
bool Maze::Pass(MazePos curpos)
{
if(curpos.maze_x < 0 || curpos.maze_x >= MAZEWIDTH
|| curpos.maze_y < 0 || curpos.maze_y >= MAZEHEIGHT)
return false;
return(maze.mazearr[curpos.maze_x][curpos.maze_y].getsymbol() == ' ');
}
void Maze::DisplayMaze()
{
cout<<endl;
for(int x = 0;x < MAZEHEIGHT;x++)
{
for(int y = 0;y < MAZEWIDTH;y++)
{
switch (maze.mazearr[x][y].getsymbol()){
case ' ':cout<<" ";break;
case '#':cout<<"#";break;
case '*':cout<<"*";break;
case '@':cout<<"@";break;
default:cout<<"?";break;
}
}
cout<<endl;
}
cout<<endl;
}
MazePos Maze::NextPos(MazePos curpos,Direction di)
{ // North:4
//di=1,2,3,4 : West:3 East:1
MazePos pos;// South:2
switch(di)
{
case 1:curpos.maze_y++;break;
case 2:curpos.maze_x++;break;
case 3:curpos.maze_y--;break;
case 4:curpos.maze_x--;break;
default:cout<<"Error:Direction not found"<<endl;break;
}
pos = curpos;
return pos;
}
int main(void)
{
MazePos exitpos(8,7);
Maze maze;
maze.DisplayMaze();
cout<<"/nAfter Finding MazePath:......"<<endl;
if(maze.FindMazepath(entrance,exitpos))
{
maze.DisplayMaze();
cout<<"Find a way out!!"<<endl;
cout<<"/nShow the path position below:"<<endl;
for(maze.itr = maze.pathpos.begin();maze.itr != maze.pathpos.end();++maze.itr)
{
cout<<"("<<(*maze.itr).maze_x<<","<<(*maze.itr).maze_y<<")"<<endl;
}
}
else cout<<"There is no way out"<<endl;
return 0;
}