//迷宫类相关
using system;
using system.drawing;
using system.drawing.drawing2d;
using system.collections;
namespace mazedemo
{
 /// <summary>
 /// 迷宫类
 /// </summary>
 public class cmaze
 {
 bool[,] mg; //地图格子
 stack stack; //堆栈
 point in_p; //入口点
 point out_p; //出口点
 point start_p; //绘制迷时候的起始点
 size boxsize; //每个格子的大小
 int step_count; //共走多少步
 public cmaze()
 {
 stack=new stack();
 this.start_p=new point(0,0);
 this.boxsize=new size(50,50);
 step_count=0;
 }
 public cmaze(bool[,] _mg):this()
 {
 this.mg=_mg;
 }
 public cmaze(bool[,] _mg,point _in,point _out):this()
 {
 this.mg=_mg;
 this.in_p=_in;
 this.out_p=_out;
 stack way=this.test(this.in_p,_in);
 stack.push(new ccoor(this.in_p,way));
 this.step_count++;
 }
 /// <summary>
 /// 绘制迷宫时窗口的起始坐标
 /// </summary>
 public point startpoint
 {
 set{this.start_p=value;}
 get{return this.start_p;}
 }
 /// <summary>
 /// 当前迷宫共走多少步
 /// </summary>
 public int stepcount
 {
 get{return this.step_count;}
 }
 /// <summary>
 /// 迷宫格子大小
 /// </summary>
 public size boxsize
 {
 set{this.boxsize=value;}
 get{return this.boxsize;}
 }
 /// <summary>
 /// 堆栈数据个数
 /// </summary>
 public int stackcount
 {
 get{return this.stack.count;}
 }
 /// <summary>
 /// 绘制迷宫
 /// </summary>
 /// <param name="g"></param>
 public void drawbox(graphics g)
 {
 for(int i=0;i<mg.getlength(0);i++)
 {
 for(int j=0;j<mg.getlength(1);j++)
 {
 point pp=new point((j*boxsize.width)+startpoint.x,(i*boxsize.height)+startpoint.y); //位置
 solidbrush brush;
 rectangle rect=new rectangle(pp,boxsize);
 if(mg[i,j])
 brush=new solidbrush(color.green);
 else
 brush=new solidbrush(color.red);
 g.fillrectangle(brush,rect);
 }
 }
 }
 /// <summary>
 /// 绘制所走线路
 /// </summary>
 /// <param name="g"></param>
 public void drawpath(graphics g)
 {
 ienumerator myenumerator = stack.getenumerator();
 while ( myenumerator.movenext() )
 {
 ccoor c=new ccoor();
 c=(ccoor)myenumerator.current;
 point pp=new point((c.currentpoint.y*boxsize.width)+startpoint.x,(c.currentpoint.x*boxsize.height)+startpoint.y);
 solidbrush brush=new solidbrush(color.blue);
 rectangle rect=new rectangle(pp,boxsize);
 g.fillrectangle(brush,rect);
 }
 }
 /// <summary>
 /// 绘制当前位置的可行路径
 /// </summary>
 /// <param name="g"></param>
 public void drawnextpath(graphics g)
 {
 ccoor c=(ccoor)this.stack.peek();
 stack s=c.waypath;
 ienumerator myenumerator=s.getenumerator();
 while(myenumerator.movenext())
 {
 point p=(point)myenumerator.current;
 point pp=new point((p.y*boxsize.width)+startpoint.x,(p.x*boxsize.height)+startpoint.y);
 solidbrush brush=new solidbrush(color.yellow);
 rectangle rect=new rectangle(pp,boxsize);
 g.fillrectangle(brush,rect);
 }
 }
 /// <summary>
 /// 判断迷宫是否走完
 /// </summary>
 /// <returns></returns>
 public bool isend()
 {
 ccoor coor=(ccoor)this.stack.peek(); //当前位置信息
 if( coor.currentpoint.x==this.out_p.x && coor.currentpoint.y==this.out_p.y )
 return true;
 else
 return false;
 }
 /// <summary>
 /// 走一迷宫中的一个格子
 /// </summary>
 /// <returns>数字状态</returns>
 public int step()
 {
 ccoor coor=(ccoor)this.stack.peek(); //当前位置信息
 //是否到达出口
 if(!(coor.currentpoint.x==this.out_p.x&&coor.currentpoint.y==this.out_p.y))
 {
 stack ss=coor.waypath;
 if(ss.count==0)
 {
 this.stack.pop();
 return 0;
 }
 point p=(point)ss.pop(); //当前位置可继续移动的下一个位置
 if(p.x==this.out_p.x&&p.y==this.out_p.y)
 {
 this.stack.push(new ccoor(p,new stack()));
 return 0;
 }
 stack st=this.test(p,coor.currentpoint); //得到下一个可移动位置的所有可移动位置
 if(st.count==0)
 {
 return 0;
 }
 ccoor newcoor=new ccoor(p,st); //建立新的位置信息
 this.stack.push(newcoor); //压入堆栈
 this.step_count++; //所走步骤加1
 return 0;
 }
 else
 return 1;
 }
 /// <summary>
 /// 走迷宫
 /// </summary>
 public void run()
 {
 while(this.step()!=1);
 }
 /// <summary>
 /// 回复到迷宫起点
 /// </summary>
 public void reset()
 {
 this.stack.clear();
 stack way=this.test(this.in_p,this.in_p);
 stack.push(new ccoor(this.in_p,way));
 this.step_count=1;
 }
 /// <summary>
 /// 探测可行路线
 /// 探测顺序 右->前->左->后
 /// 左
 /// |
 /// 后--+-->前
 /// |
 /// 右
 /// </summary>
 /// <param name="p">从当前点查询四周是否有可行路线</param>
 /// <param name="perv_p">先前的路线</param>
 /// <returns>可行路线堆栈</returns>
 public stack test(point p,point perv_p)
 {
 stack stack_way=new stack(); //该点可行位置堆栈
 int x,y;
 //后
 x=p.x;
 y=p.y-1;
 this.signpost(x,y,stack_way,perv_p);
 //左
 x=p.x-1;
 y=p.y;
 this.signpost(x,y,stack_way,perv_p);
 //前
 x=p.x;
 y=p.y+1;
 this.signpost(x,y,stack_way,perv_p);
 //右
 x=p.x+1;
 y=p.y;
 this.signpost(x,y,stack_way,perv_p);
 return stack_way;
 }
 /// <summary>
 /// 判断该方向是否可行,可行则将信息压入堆栈,只在test()函数中调用
 /// </summary>
 /// <param name="x">x坐标</param>
 /// <param name="y">y坐标</param>
 /// <param name="s">堆栈</param>
 /// <param name="perv_p">来时候的方向</param>
 private void signpost(int x,int y,stack s,point perv_p)
 {
 if( (x>=0 && x<this.mg.getlength(0)) && (y>=0 && y<this.mg.getlength(1)) )
 {
 if(this.mg[x,y]&&!(x==perv_p.x&&y==perv_p.y))
 s.push(new point(x,y));
 }
 }
 /// <summary>
 /// 迷宫简图
 /// </summary>
 /// <returns>字符地图</returns>
 public override string tostring()
 {
 string str="";
 for(int i=0;i<mg.getlength(0);i++)
 {
 for(int j=0;j<mg.getlength(1);j++)
 {
 if(this.mg[i,j])
 str+="□";
 else
 str+="■";
 }
 str+="/n";
 }
 return str;
 }
 }
 /// <summary>
 /// 当前坐标信息,和可走方向坐标
 /// </summary>
 public class ccoor
 {
 private point curr_p; //当前坐标
 private stack way; //可走方向坐标
 public ccoor()
 {
 //...
 }
 public ccoor(point p,stack w)
 {
 curr_p=p;
 way=w;
 }
 public point currentpoint
 {
 get{return this.curr_p;}
 set{this.curr_p=value;}
 }
 public stack waypath
 {
 set{this.way=value;}
 get{return this.way;}
 }
 }
}