迷宫

迷宫
/* 源码名称:迷宫
* * 日期:2012.10.27
 * 程序功能:迷宫游戏
* * 作者:侯兴鼎
 */
#include
using namespace std;
//
//customspass:迷宫当前所在关关数,默认为第1关;
//count:将数据(x,y)入栈次数的累加
//
int customspass=1,count=0;
//
//设置迷宫数组的最大范围
//如需改变关数,可通过改变SIZE值来增加或减小范围
//
#define SIZE 20
/*
* * 方向结点结构体
 */
template 
struct Node
{
 T data1,data2; //data1(x),data2(y)
    Node *next;  //此处也可以省略
};
/*
* * 迷宫通路存储栈
 */
class MazeStack
{
public:
    MazeStack( );    //置空链栈
    ~MazeStack();    //释放链栈中各结点的存储空间
 void Push(int x,int y);  //将元素x,y入栈
    void Pop();    //将栈顶元素出栈
 private:
  Node *top;   //栈顶指针即链栈的头指针
};
/*
* * 迷宫类
 */
class Maze     
{
public:
 Maze();
 ~Maze(){} 
 void Display();    //迷宫图显示函数 
protected:
 char M[SIZE][SIZE];   //迷宫图存储
};
/*
* * 迷宫行走方向类
 */
class Move:public Maze  
{
public:
 Move(int X=1,int Y=1):
  x(X),y(Y){}
 void Remove(MazeStack &t);  //行走函数
 void AutoMatic(MazeStack &t); //自动行走函数
protected:
 intx,y;      //行走方向座标数据(x,y)
}; 
/*
* * 迷宫图构造函数
 */
Maze::Maze()    
{
 //
 //第一关迷宫图定义
 //
 if(customspass==1)
 {
  char m[10][10]={
  {1,1,1,1,1,1,1,1,1,1}, //0
  {1,12,1,1,1,0,1,1,1,1}, //1
  {1,1,0,1,0,1,1,1,1,1}, //2
  {1,0,1,0,0,0,0,0,0,1}, //3
  {1,0,1,1,1,0,1,1,1,1}, //4
  {1,1,0,0,1,1,0,0,0,1}, //5
  {1,0,1,1,0,0,1,1,0,1}, //6
  {1,1,0,1,1,1,0,0,1,1}, //7
  {1,0,1,0,1,1,1,1,3,1}, //8
  {1,1,1,1,1,1,1,1,1,1}}; //9
    //0  2  4  6  8 
  //
  //通过关数(customspass)来判断迷宫图的宽和高
  //给迷宫图数组初始化
  //
  for(int y=0;y<5*(customspass+1);y++)
   for(int x=0;x<5*(customspass+1);x++)
    M[y][x]=m[y][x];
 }
 //
 //第二关迷宫图定义
 //
 if(customspass==2)     
 {
  char m[15][15]={
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //0
  {1,12,1,0,0,1,0,1,0,1,0,0,1,0,1}, //1
  {1,1,0,1,1,0,1,0,1,0,1,1,0,1,1}, //2
  {1,0,1,1,0,1,0,1,1,1,1,0,1,0,1}, //3
  {1,1,0,1,0,1,0,1,1,0,1,0,1,1,1}, //4
  {1,1,0,1,0,1,1,0,0,1,0,1,1,0,1}, //5
  {1,1,1,0,1,0,1,1,1,1,1,0,0,1,1}, //6
  {1,1,0,1,1,1,0,1,1,0,1,1,1,0,1}, //7
  {1,0,1,0,1,1,1,1,1,1,0,1,0,1,1}, //8
  {1,1,1,1,0,1,0,1,0,1,1,0,1,0,1}, //9
  {1,1,0,0,1,0,1,0,1,0,1,1,0,1,1}, //10
  {1,0,1,0,1,1,1,1,1,1,1,1,0,1,1}, //11
  {1,1,0,1,1,0,1,0,1,0,1,0,1,0,1}, //12
  {1,0,1,0,0,1,0,1,0,1,0,1,0,3,1}, //13
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}; //14
    //0  2  4  6  8 10  12  14
  //
  //通过关数(customspass)来判断迷宫图的宽和高
  //给迷宫图数组初始化
  //
  for(int y=0;y<5*(customspass+1);y++)
   for(int x=0;x<5*(customspass+1);x++)
    M[y][x]=m[y][x];
 }
 //
 //第三关迷宫图定义
 //
 if(customspass==3)    
 {
  char m[20][20]={
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //0
  {1,12,1,1,1,0,1,1,0,1,1,0,0,1,0,1,1,1,0,1}, //1
  {1,1,0,1,0,1,1,1,0,1,0,1,1,0,1,0,1,0,1,1}, //2
  {1,0,1,0,0,0,0,0,1,1,0,1,0,1,1,1,0,1,0,1}, //3
  {1,0,1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,1,0,1}, //4
  {1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,0,1,0,1}, //5
  {1,0,1,1,0,0,1,1,0,1,1,1,0,1,1,0,1,1,0,1}, //6
  {1,1,0,1,1,1,0,1,1,0,1,0,1,1,0,1,0,1,1,1}, //7
  {1,1,1,0,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1}, //8
  {1,1,0,1,1,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1}, //9
  {1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1}, //10
  {1,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,0,0,1,1}, //11
  {1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1}, //12
  {1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,1,0,0,1,1}, //13
  {1,1,0,0,0,0,1,1,0,1,1,1,1,0,1,0,1,1,0,1}, //14
  {1,1,0,1,1,1,1,0,1,1,0,1,1,0,1,0,1,0,1,1}, //15
  {1,0,1,1,1,0,1,1,1,0,1,0,0,1,0,1,1,1,0,1}, //16
  {1,1,0,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,1,1}, //17
  {1,1,1,0,1,1,1,0,0,1,1,1,1,0,1,1,1,1,3,1}, //18
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}}; //19
    //0  2  4  6  8 10  12  14  16  18
  //
  //通过关数(customspass)来判断迷宫图的宽和高
  //给迷宫图数组初始化,
  //
  for(int y=0;y<5*(customspass+1);y++)
   for(int x=0;x<5*(customspass+1);x++)
    M[y][x]=m[y][x];
 }
}
/*
* * 迷宫图显示函数
 */
void Maze::Display()     
{
 //
 //通过关数(customspass)来判断显示迷宫图
 //
 for(int y=0;y<5*(customspass+1);y++)
 {
  for(int x=0;x<5*(customspass+1);x++)
   cout<<" "<<M[y][x];
  cout<<endl;
 }
}
/*
* * 方向显示函数:通过座标显示方向,便于用户观看
 */
void Direction(int x,int y)
{
 if(x==1&&y==0)
  cout<<"右"<<' ';
 if(x==1&&y==1)
  cout<<"右下"<<' ';
 if(x==0&&y==1)
  cout<<"下"<<' ';
 if(x==-1&&y==1)
  cout<<"左下"<<' ';
 if(x==-1&&y==0)
  cout<<"左"<<' ';
 if(x==-1&&y==-1)
  cout<<"左上"<<' ';
 if(x==0&&y==-1)
  cout<<"上"<<' ';
 if(x==1&&y==-1)
  cout<<"右上"<<' ';
}
/*
* * 迷宫行走函数
 */
void Move::Remove(MazeStack & t)    
{
 //
 //abscissa:表示当前位置的横座标;
 //ordinate:表示当前位置的纵座标
 //charnumber:表示行走方向的字符型编码
 //
 int abscissa=1,ordinate=1;
 char charnumber; 
 //
 //行走方向数组
 //
 Move move[8]={
  Move(1,0),  //0右
  Move(1,1),  //1右下
  Move(0,1),  //2下
  Move(-1,1),  //3左下
  Move(-1,0),  //4左
  Move(-1,-1), //5左上
  Move(0,-1),  //6上
  Move(1,-1)}; //7右上
 //
 //行走判断功能
 //
 while(1)
 {
  cout<<"请输入您下一步要走的方向编码(0~7):"<<endl;
  cout<<"(编码:右:0/右下:1/下:2/左下:3/左:4/左上:5/上:6/右上:7)"<<endl;
  cin>>charnumber; //输入字符型方向编码
  //
  //判断输入行走方向符合要求
  //
  if(charnumber>='0'&&charnumber<='7')     
  { 
   //
   //intnumber:表示整型方向编码
   //将输入的字符型编码转化为整型编码
   //
   int intnumber=charnumber-48;
   //
   //判断是障碍物
   //
   if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==1)  
    cout<<"此处无路!"<<endl; 
   //
   //判断不是障碍物
   //
   else
   {
    //
    //终点判断
    //
    if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==3) 
    {
     M[ordinate][abscissa]=0;      //清除行走痕迹
     //行走前进显示
     M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]=12;
     Display();
     t.Push (move[intnumber].x,move[intnumber].y ); //行走方向数据入栈
     count++;          //栈内数据信息总数加1
     cout<<"恭喜您顺利通过第"
      <<customspass<<"关!"<<'\a'
      <<'\a'<<'\a'<<endl;
     break;           //结束本关游戏
    }
    M[ordinate][abscissa]=0;       //清除行走痕迹
    abscissa+=move[intnumber].x;      //改变当前位置横座标值
    ordinate+=move[intnumber].y;      //改变当前位置纵座标值
    M[ordinate][abscissa]=12;       //行走前进显示
    t.Push(move[intnumber].x,move[intnumber].y);  //行走方向数据入栈
    Display();
    count++;           //栈内数据信息总数加1
    cout<<'\a'; 
   }
  }
  //
  //判断输入行走方向不符合要求
  //
  else
   cout<<"输入错误!"<<endl;
 }
}
/*
* * 系统自动行走
 */
void Move::AutoMatic(MazeStack & t)
{
 //
 //abscissa:表示当前位置的横座标;
 //ordinate:表示当前位置的纵座标
 //intnumber:表示行走方向编码
 //mark给死路做个标记
 //
 int abscissa=1,ordinate=1;
 int intnumber=0; 
 int mark=0;   
 //
 //行走方向数组
 //
 Move move[8]={
  Move(1,0),  //0右
  Move(1,1),  //1右下
  Move(0,1),  //2下
  Move(-1,1),  //3左下
  Move(-1,0),  //4左
  Move(-1,-1), //5左上
  Move(0,-1),  //6上
  Move(1,-1)}; //7右上
 //
 //行走判断功能
 //
 while(1)
 { 
  //
  //判断是倒走
  //
  if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==16) 
  {
   //
   //判断是无路可走
   //为了确保每个方向都走过,把无路标记mark定义为2
   //
   if(mark==2)
   { //倒退一步显示
    M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]=12;
    M[ordinate][abscissa]=33;  //标记无路记号
    cout<<"清除走过路径存储:";
    t.Pop();      //清除走过路径方向数据
    abscissa+=move[intnumber].x; //改变当前位置横座标值
    ordinate+=move[intnumber].y; //改变当前位置纵座标值
    count--;      //栈内数据信息总数减1
    intnumber=0;     //方向编码初始化
    mark=0;       //无路标记初始化
   }
   //
   //判断不是无路可走
   //
   else
   { //
    //判断方向编码没有超出范围
    //
    if(intnumber!=7)
    {
    mark++;    //无路标记加1
    intnumber++;  //方向编码加1
    }
    //
    //判断方向编码超出范围
    //
    else
    {
     mark=2;   //无路标记设置为2实现无路功能
     intnumber=0; //方向编码初始化
    }
   }
  }
  //
  //判断不是倒走
  //
  else
   {
    //
    //判断是障碍物
    //
    if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==1)  
    {
     //
     //判断方向编码达到最后一个方向编码
     //
     if(intnumber==7) 
      intnumber=0; //方向编码初始化
     //
     //判断方向编码达到最后一个方向编码
     //
     else
      intnumber++; //进入下一方向
    } 
    //
    //判断不是障碍物
    //
    else
    {
     //
     //终点判断
     //
     if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==3) 
     {
      M[ordinate][abscissa]=16;      //走过标记
      //行走前进显示
      M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]=12; 
      Display();
      t.Push (move[intnumber].x,move[intnumber].y); //行走方向数据入栈
      count++;          //栈内数据信息总数加1
      cout<<"恭喜您顺利通过第"
      <<customspass<<"关!"<<'\a'
      <<'\a'<<'\a'<<endl;
      break;           //结束本关游戏
     }
     //
     //有路可走
     //
     if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==0)
     {
      M[ordinate][abscissa]=16;      //给走过的路径做下标记
      abscissa+=move[intnumber].x;     //改变当前位置横座标值
      ordinate+=move[intnumber].y;     //改变当前位置纵座标值
      M[ordinate][abscissa]=12;      //行走前进显示
      t.Push(move[intnumber].x,move[intnumber].y); //行走方向数据入栈
      count++;          //栈内数据信息总数加1
      intnumber=0;         //行走方向编码初始化
      mark=0;           //无路标记初始化
     }
     //
     //判断是死路
     //
     if(M[ordinate+move[intnumber].y][abscissa+move[intnumber].x]==33)
     {
      cout<<"此方向是死路!"<<endl;
      //
      //判断方向编码没有达到最后一个方向编码
      //
      if(intnumber!=7)
       intnumber++;  //行走方向编码加1进入下一方向
      //
      //判断方向编码达到最后一个方向编码
      //
      else
      {
       intnumber=0;  //行走方向编码初始化
       mark=2;    //无路标记设置为2实现无路功能
      }
     }
    }
   }
 }
}
/*
* * 迷宫通路存储栈初始化
 */
MazeStack::MazeStack( )
{
 top=NULL; //迷宫栈初始化
}
/*
* * 迷宫通路存储栈清除数据
 */
MazeStack::~MazeStack( )
{
 while (top)
 {
  Node *p;
  p=top->next;
        delete top;
        top=p;
 }
}
/*
* * 迷宫通路存储栈行走方向(x,y)入栈
 */
void MazeStack::Push(int x,int y)
{
    Node *s;
 s=new Node;   
    s->data1 = x;  //申请一个数据域为data1的结点s
    s->data2 = y;  //申请一个数据域为data2的结点s
 s->next = top;
 top=s;    //将结点s插在栈顶
}
/*
* * 迷宫通路存储栈行走方向(x,y)出栈
 */
void MazeStack::Pop( )
{  
    Node *p;
 int x,y;     //定义x,y用以存储出栈的数据信息
    if (top==NULL)throw"下溢";
 x=top->data1;    //暂存栈顶元素data1
 y=top->data2;    //暂存栈顶元素data2
 p=top;
 top=top->next;    //将栈顶结点摘链
    delete p;
 Direction(x,y);    //调用方向显示函数,方便用户观看
}
/*
* * 游戏规则菜单显示
 */
void Mune1()    
{
 //
 //a:显示起点图标及行走图标;b:显示终点图标;c:显示障碍物
 //
 char a=12,b=3,c=1;
 cout<<endl<<"**********************"<<endl<<endl;
 cout<<"  迷宫游戏规则:"<<endl<<endl;
 cout<<"  起点:“"<<a<<"”"<<endl
  <<"  终点:“"<<b<<"”"<<endl
  <<"  “"<<c<<"”为障碍物"<<endl
  <<"  空白处为路。"<<endl;
 cout<<"方向编码为:"<<endl<<"  向右:0,向右下:1,"<<endl
  <<"  向下:2,向左下:3,"<<endl
  <<"  向左:4,向左上:5,"<<endl
  <<"  向上:6,向右上:7."<<endl<<endl;
 cout<<"**********************"<<endl;
}
/*
* * 游戏选择菜单显示
 */
void Mune2()    
{
 cout<<endl<<"******************"<<endl<<endl;
 cout<<"请选择:"<<endl
  <<"  1.下一关;"<<endl
  <<"  2.本关;"<<endl
  <<"  3.上一关;"<<endl
  <<"  4.游戏重新开始;"<<endl
  <<"  5.导出路径"<<endl<<endl;
 cout<<endl<<"******************"<<endl<<endl;
}
/*
* * 通关选择
 */
void Mune3(int sign,MazeStack &ms)    
{
 char choose; //通关选择编号
 cout<<"请输入您的选择编号(输入:1~5)"<<endl;
 cin>>choose; //输入选择编号
 //
 //判断是通关选择范围
 //
 if(choose<='5'&&choose>='1')
 {
  //
  //通关选择
  //
  switch(choose)
  {
   //
   //下一关
   //
   case '1':
    //
    //判断是最后一关
    //
    if(customspass>=SIZE/5-1)
    {
     cout<<"对不起!您已通过了最后一关!"<<endl;
     Mune3(sign,ms);  //重新输入选择
    }
    //
    //判断不是最后一关
    //
    else
    {
     cout<<"你真棒,勇于挑战!"<<endl;
     customspass++;  //关数加1
     count=0;   //入栈信息总数清零
    }
    break;
   //
   //本关
   //
   case '2': 
    cout<<"请不要害怕,继续加油!"<<endl;
    count=0;    //入栈信息总数清零
    break;
   //
   //上一关
   //
   case '3':
    //
    //判断是第一关
    //
    if(customspass<=1)
    {
     cout<<"对不起!您已经在第一关了!"<<endl;
     Mune3(sign,ms);  //重新输入选择
    }
    //
    //判断不是第一关
    //
    else
    {
     cout<<"请不要退缩,想想就能过去!"<<endl;
     count=0;   //入栈信息总数清零
     customspass--;  //关数减1
    }
    break;             
   //
   //游戏重新开始
   //
   case '4':
    cout<<"没关系,我们从头再来!"<<endl;
    count=0;    //入栈信息总数清零
    customspass=1;   //关数初始化
    break;
   //
   //导出路径
   //
   case '5':
    if(sign==0)
    {
     cout<<"路径(终点-起点):"<<count<<endl;
     for(int i=count;i>0;i--)
     ms.Pop();   //导出行走方向
     count=0;   //入栈信息总数清零
     sign++;    //sign加1,表示导出过路径
    }
    else
     cout<<"路径信息已被清除!"<<endl;
    Mune2();    //游戏选择菜单显示
    Mune3(sign,ms);   //通关选择
    break;
  }
 }
 //
 //判断不是通关选择范围
 //
 else
 {
  cout<<"输入错误!"<<endl;
  Mune3(sign,ms);   //通关选择
 }
}
/*
* * 判断是否要退出游戏
 */
int ExitProcess(int exit,MazeStack &ms)
{
 char quit;    //游戏是否退出判断
 int sign=0;    //sign:标记有没有导出过路径
 cout<<endl<<endl;
 //
 //选择判断
 //
 while(1)
 {
  cout<<"是否退出游戏?(是:“Y”;否:“N”)"<<endl;
  cin>>quit;
  //
  //判断退出游戏
  //
  if(quit=='Y')
  {
   exit=0;    //游戏结束
   return exit;
  }
  //
  //判断继续游戏
  //
  if (quit=='N')
  {
   Mune2();   //游戏选择菜单显示
   Mune3(sign,ms);  //通关选择
   break;
  }
  //
  //不在判断范围
  //
  else
   cout<<"输入错误!"<<endl;
 }
}
/*
* * 迷宫自主通关和系统通关选择
 */
void Choose(Maze &ma,Move &mo,MazeStack &ms)
{
 char choose;     //游戏通关方式命令
 cout<<endl
  <<"****欢迎进入迷宫游戏第"
  <<customspass<<"关!****"
  <<'\a'<<'\a'<<'\a'<<endl<<endl;
  ma.Display();    //显示第n关迷宫图
  cout<<"您要自己走迷宫,还是看看系统走迷宫?回答:Y(是),N(否)"<<endl;
  //
  //迷宫自主通关和系统通关选择判断
  //
  while(1)
  {
   cin>>choose;
   //
   //判断是自主通关
   //
   if(choose=='Y')
   {
    mo.Remove(ms);  //调用自主通关算法
    break;
   }
   //
   //判断是系统通关
   //
   if(choose=='N')
   {
    mo.AutoMatic(ms); //调用系统通关算法
    break;
   }
   //
   //不在判断范围
   //
   else
   {
    cout<<"输入错误!"<<endl;
    cout<<"请重新输入:"<<endl;
   }
  }
}
/*
* * 迷宫运行主函数
 */
void main()

 intexit;       //游戏结束判断标记
 Mune1();       //游戏规则菜单显示
 //
 //进入迷宫系统
 //
 while(exit)
 {
  //
  //类对象定义在循环里才可以实现多关
  //
  Maze ma;      //迷宫图对象
  Movemo;      //迷宫行走对象
  MazeStackms;     //迷宫存储栈对象
  Choose(ma,mo,ms);    //迷宫自主通关和系统通关选择
  exit=ExitProcess(exit,ms);  //游戏结束判断
 }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章