using System; using System.Collections.Generic; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { test mytest = new test(); //定义出发位置 Point startingPoint = new Point(); startingPoint.x = 1; startingPoint.y = 3; //定义目的地 Point destination = new Point(); destination.x = 5; destination.y = 0; //定义移动力 int power = 10; DateTime time1 = DateTime.Now; mytest.FindWay(startingPoint, destination, power); DateTime time2 = DateTime.Now; mytest.PrintMap(startingPoint, destination); Console.WriteLine("用时:" + (time2 - time1)); } } class test { //数值表示移动力消耗 public byte[,] R = new byte[10, 10]{ { 8, 8, 8, 8, 8, 1, 1, 1, 3, 1 }, { 8, 1, 1, 1, 1, 1, 1, 1, 6, 1 }, { 8, 8, 1, 8, 8, 1, 1, 2, 1, 1 }, { 8, 8, 8, 8, 8, 1, 1, 1, 1, 1 }, { 8, 8, 8, 2, 8, 1, 1, 1, 1, 1 }, { 1, 8, 1, 2, 8, 1, 1, 3, 1, 1 }, { 1, 1, 1, 1, 8, 1, 2, 1, 1, 2 }, { 1, 2, 5, 1, 8, 1, 2, 1, 1, 1 }, { 1, 1, 7, 1, 1, 1, 2, 2, 1, 1 }, { 1, 1, 1, 1, 1, 2, 2, 3, 1, 1 }}; //最终路径 List<Point> way = new List<Point>(); //开启列表 List<Point> Open_List = new List<Point>(); //关闭列表 List<Point> Close_List = new List<Point>(); //从开启列表查找F值最小的节点 private Point GetMinFFromOpenList() { Point Pmin = null; foreach (Point p in Open_List) if (Pmin == null || Pmin.G + Pmin.H > p.G + p.H) Pmin = p; return Pmin; } //判断关闭列表是否包含一个坐标的点 private bool IsInCloseList(int x, int y) { foreach (Point p in Close_List) if (p.x == x && p.y == y) return true; return false; } //判断开启列表是否包含一个坐标的点 private bool IsInOpenList(int x, int y) { foreach (Point p in Open_List) if (p.x == x && p.y == y) return true; return false; } //从开启列表返回对应坐标的点 private Point GetPointFromOpenList(int x, int y) { foreach (Point p in Open_List) if (p.x == x && p.y == y) return p; return null; } //检查当前节点附近的节点 private void CheckGrid(Point nowPoint, Point startingPoint, Point destination) { for (int xt = nowPoint.x - 1; xt <= nowPoint.x + 1; xt++) { for (int yt = nowPoint.y - 1; yt <= nowPoint.y + 1; yt++) { //排除超过边界、不相干和关闭列表中的点 if (!(xt >= 0 && xt < R.GetLength(0) && yt >= 0 && yt < R.GetLength(1))) continue; if (IsInCloseList(xt, yt)) continue; if (!(xt == nowPoint.x && yt - 1 == nowPoint.y) && !(xt - 1 == nowPoint.x && yt == nowPoint.y) && !(xt + 1 == nowPoint.x && yt == nowPoint.y) && !(xt == nowPoint.x && yt + 1 == nowPoint.y)) continue; if (IsInOpenList(xt, yt)) { Point pt = GetPointFromOpenList(xt, yt); int G_new = nowPoint.G + R[pt.x, pt.y]; if (G_new < pt.G) { Open_List.Remove(pt); pt.father = nowPoint; pt.G = G_new; Open_List.Add(pt); } } else //不在开启列表中 { Point pt = new Point(); pt.x = xt; pt.y = yt; pt.father = nowPoint; pt.G = pt.father.G + R[pt.x, pt.y]; pt.H = Math.Abs(pt.x - destination.x) + Math.Abs(pt.y - destination.y); Open_List.Add(pt); } } } } public void FindWay(Point startingPoint, Point destination, int power) { Open_List.Add(startingPoint); while (!(IsInOpenList(destination.x, destination.y))) //当终点存在开启列表中就意味着寻路结束了 { Point nowPoint = GetMinFFromOpenList(); Open_List.Remove(nowPoint); Close_List.Add(nowPoint); CheckGrid(nowPoint, startingPoint, destination); } Point p = GetPointFromOpenList(destination.x, destination.y); List<Point> temp = new List<Point>(); while (p.father != null) { temp.Add(p); p = p.father; } temp.Reverse(); foreach (Point pt in temp) { if (pt.G > power) break; way.Add(pt); } } public void PrintMap(Point startingPoint, Point destination) { for (int x = 0; x < 10; x++) { for (int y = 0; y < 10; y++) { if (x == startingPoint.x && y == startingPoint.y) Console.Write("▲"); else if (x == destination.x && y == destination.y) Console.Write("▲"); else if (Contains(x,y)) Console.Write("★"); else Console.Write("□"); } Console.Write("\n"); } } private Boolean Contains(int x, int y) { foreach (Point p in way) if (p.x == x && p.y == y) return true; return false; } } class Point { public Point() { } public int G; public int H; public int x; public int y; public Point father; } }