public AStarPointData(AStarPoint _AStartPoint, double _g, double _h, AStarPointData _parent) { pointPos = _AStartPoint; g = _g; h = _h; parent = _parent; }
/// <summary> /// 计算G /// </summary> /// <param name="data"></param> /// <returns></returns> public static double CalG(AStarPointData data, AStarPoint newPos) { double result = data.g + Math.Abs(newPos.x - data.pointPos.x) != Math.Abs(newPos.y - data.pointPos.y) ? StraightLine : SlantLine; double temp = 0; var _type = Map[newPos.x, newPos.y]; switch (_type) { case Space0: temp = 1; break; case Space1: temp = 10; break; } return(result + temp); }
private static bool Search(out List <AStarPoint> pathList) { //用List集合做"开启列表" 来记录扩展的点 List <AStarPointData> openList = new List <AStarPointData>(); //把起点放入开启列表 openList.Add(new AStarPointData(Start_Pnt, 0, 0, null)); //最后一个点的数据 用于反推 AStarPointData endData = null; //是否完成 bool isFinish = false; while (!isFinish && openList.Count > 0) {//找到终点或者"开启列表"为空的时候退出循环 openList.Sort((x, y) => { return(x.F.CompareTo(y.F)); }); AStarPointData data = openList[0]; openList.RemoveAt(0); AStarPoint point = data.pointPos; //将取出的点表示为已访问点 if (Map[point.x, point.y] == Space0 || Map[point.x, point.y] == Space1) { Map[point.x, point.y] = Visited; } for (int i = 0; i < directs.GetLength(0); i++) { AStarPoint newPoint = new AStarPoint(point.x + directs[i, 0], point.y + directs[i, 1]); if (newPoint.x >= 0 && newPoint.x < Max_PNT.x && newPoint.y >= 0 && newPoint.y < Max_PNT.y) { char e = Map[newPoint.x, newPoint.y]; if (e == End) { endData = data; isFinish = true; break; } if (e != Space0 && e != Space1) { continue; } //查找判断点是否在"开启列表"中 AStarPointData tempData = openList.Find(x => x.pointPos.Equals(newPoint)); double tempG = CalG(data, newPoint); if (tempData != null) { if (tempData.g > tempG) { tempData.g = tempG; tempData.parent = data; } } else { double h = CalH(newPoint); AStarPointData newData = new AStarPointData(newPoint, tempG, h, data); openList.Add(newData); } } } } //反向查找 找出路径 pathList = new List <AStarPoint>(); AStarPointData pointData = endData; pathList.Add(End_Pnt); while (pointData != null) { AStarPoint point = pointData.pointPos; if (Map[point.x, point.y] == Visited) { Map[point.x, point.y] = OnPath; pathList.Add(point); } pointData = pointData.parent; } pathList.Add(Start_Pnt); pathList.Reverse(); if (pathList.Count <= 2 && (Math.Abs(Start_Pnt.x - End_Pnt.x) > 1 || Math.Abs(Start_Pnt.y - End_Pnt.y) > 1)) { return(false); } return(true); }