迷宫求解

2013-01-22

摘要:用“穷举”的方法,从入口出发,顺某一方向向前探索。若能走通,继续;不能,原路返回,换方向继续。这样;遍历所有的道路,直到发现出口。因为要原路返回,也需要栈。

View Code
  1 using System;
  2 using System.Collections.Generic;
  3 
  4 namespace MazePath
  5 {
  6     //方向
  7     public enum Direct{NA=-1,East=0,South=1,West=2,North=3,Out=886};
  8 
  9     struct Point
 10     {
 11         public int x;
 12         public int y;
 13     }
 14     struct Element
 15     {
 16         public Point p;
 17         public Direct d; 
 18     }
 19 
 20     class Program
 21     {
 22         static void Main(string[] args)
 23         {
 24             Point start = GetStartMark();
 25             Point end = GetEndMark();
 26             int[,] maze = InitMaze();
 27             int[,] diradd = InitDirAdd();
 28             MazePath(start, end, maze, diradd);
 29             Console.Read();
 30         }
 31 
 32         /// <summary>
 33         /// step 1 依次尝试东南西北四个方向,
 34         /// step 1.1 如果下一步可通,标记下一位置已访问,把当前位置和方向入栈
 35         /// step 1.1.1 若下一位置为出口,显示所有路径,返回
 36         /// step 1.1.2 若不是,则可通往的位置为当前位置
 37         /// step 1.2 如果不通,换个方向
 38         /// step 2 如果不通或已走过,退栈取得上一次位置和方向,换其他方向
 39         /// </summary>
 40         /// <param name="start"></param>
 41         /// <param name="end"></param>
 42         /// <param name="maze"></param>
 43         /// <param name="diradd"></param>
 44         static void MazePath(Point start, Point end, int[,] maze, int[,] diradd)
 45         {
 46             Point p;
 47             Element elem;
 48             Stack<Element> S1 = new Stack<Element>();
 49             Stack<Element> S2 = new Stack<Element>();
 50             maze[start.x, start.y] = 2; //入口点作上标记 
 51             p = start;
 52             elem.p = p;
 53             elem.d = Direct.East;
 54             do
 55             {
 56                 //step 1. 依次尝试东南西北四个方向
 57                 while (elem.d < Direct.North)
 58                 {
 59                     p = GetNextPoint(elem.p, elem.d, diradd);
 60                     //step 1.1 若当前位置可通,标记可通往的位置,并入栈当前位置、方向
 61                     if (maze[p.x, p.y] == 0) 
 62                     {                        
 63                         maze[p.x, p.y] = 2;
 64                         S1.Push(elem);
 65                         //step 1.1.1 若下一位置为出口,显示所有路径,返回。
 66                         if (p.x == end.x && p.y == end.y)
 67                         {
 68                             elem.p = p;
 69                             elem.d = Direct.Out; //方向输出为-1 判断是否到了出口 
 70                             S1.Push(elem);
 71                             Console.WriteLine("\n0=东 1=南 2=西 3=北 886为则走出迷宫\n\n通路为:(行坐标,列坐标,方向)\n");
 72                             while (S1.Count != 0) //逆置序列 并输出迷宫路径序列 
 73                             {
 74                                 S2.Push(S1.Pop());
 75                             }
 76                             while (S2.Count != 0)
 77                             {
 78                                 elem = S2.Pop();
 79                                 Console.WriteLine("坐标'{0},{1}',方向{2}->", elem.p.x, elem.p.y, elem.d);
 80                             }
 81                             return;
 82                         }
 83                         //step 1.1.2 若不是,则可通往的位置为当前位置
 84                         else
 85                         {
 86                             elem.p = p;
 87                             elem.d = Direct.East;
 88                         }
 89                     }
 90                     // step 1.2 如果不通,换个方向
 91                     else
 92                     {
 93                         elem.d = TurnClockwise(elem.d);
 94                     }
 95                 }
 96                 //step 2 如果不通或已走过,退栈取得上一次位置和方向,换其他方向
 97                 if (S1.Count != 0)
 98                 {
 99                     elem = S1.Pop();
100                     elem.d = TurnClockwise(elem.d);
101                 }
102             }
103             while (S1.Count != 0);
104 
105             Console.WriteLine("没有找到可以走出此迷宫的路径\n");
106         }
107 
108         static int[,] InitMaze()
109         {
110             //横坐标向右为正,纵坐标向下为正
111             /// + ----+
112             /// |     |
113             /// | | | |
114             /// | |   |
115             /// | +---+
116             /// |     
117             /// +------
118             
119             //0为可通,1为不可通
120             int[,] maze = new int[,] { { 1, 1, 1, 1, 1, 1, 1 }, { 0, 0, 0, 0, 0, 0, 1 }, { 1, 0, 1, 1, 1, 0, 1 }, { 1, 0, 0, 0, 1, 0, 1 }, { 1, 0, 1, 0, 1, 0, 1 }, { 1, 0, 0, 0, 1, 0, 0 }, { 1, 1, 1, 1, 1, 0, 1 } };
121             return maze;
122         }
123 
124         //得到迷宫的入口点
125         static Point GetStartMark()
126         {
127             Point mark;
128             mark.x = 1;
129             mark.y = 0;
130             return mark;
131         }
132         //得到迷宫的出口点
133         static Point GetEndMark()
134         {
135             Point mark;
136             mark.x = 6;
137             mark.y = 5;
138             return mark;
139         }
140         //按东西南北走,相对应x,y坐标的增减
141         static int[,] InitDirAdd()
142         {
143             int[,] dirAdd = new[,] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } };
144             return dirAdd;
145         }
146         //顺时针旋转
147         static Direct TurnClockwise(Direct d)
148         {
149             return d + 1;
150         }
151 
152         //下一步
153         static Point GetNextPoint(Point p, Direct d, int[,] diradd)
154         {
155             Point q;
156             q.x = p.x + diradd[(int)d, 0];
157             q.y = p.y + diradd[(int)d, 1];
158             return q;
159         }
160     }
161 }

 

posted @ 2013-01-22 11:23  明-Ming  阅读(252)  评论(0编辑  收藏  举报