C++ 编写的栈解迷宫程序

//--------------------文件名: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值