/// <summary> /// 返回distanse范围内所有可以通过的点 /// </summary> /// <param name="startPos"></param> /// <param name="expandWidth">搜索范围</param> /// <param name="canMoveFunc">点是否是可以通过的</param> /// <returns>点列表</returns> public static List <Vector2> ExpandAera(Vector2 startPos, int expandWidth, Func <Vector2, bool> canMoveFunc) { RouteDic SearchDic = new RouteDic(); //索引队列 List <Vector2> queue = new List <Vector2>(); List <Vector2> avaliablePos = new List <Vector2>(); Vector2 start = startPos; SearchDic[start] = 0; queue.Add(start); Vector2 p = start; bool flag = true; bool AddNextRoute(Vector2 ov) { if (canMoveFunc(p + ov) && !SearchDic.ContainsKey(p + ov)) { if (SearchDic[p] + 1 > expandWidth) { //queue.Remove(p); flag = false; return(false); } SearchDic[p + ov] = SearchDic[p] + 1; queue.Add(p + ov); avaliablePos.Add(p + ov); } return(true); }; while (flag) { if (queue.Count == 0) { avaliablePos.Add(start); return(avaliablePos); } else { //初始化当前这个点 //取第一个点,值最小的点 p = queue[0]; AddNextRoute(new Vector2(1, 0)); AddNextRoute(new Vector2(-1, 0)); AddNextRoute(new Vector2(0, 1)); AddNextRoute(new Vector2(0, -1)); //去掉这个点 queue.Remove(p); } } avaliablePos.Add(start); return(avaliablePos); }
/// <summary> /// 基于距离判定的优化DFS算法 起点终点,返回路径点列表 /// </summary> /// <param name="start">起始点</param> /// <param name="stop">终点</param> /// <param name="canMoveFunc">一个方法用于指示目标点是否是可以穿过的</param> public static SearchResult Search(Vector2 start, Vector2 stop, Func <Vector2, bool> canMoveFunc) { SearchResult result = new SearchResult(); //保存路径信息 RouteDic SearchDic = new RouteDic(); //首先校验一下终点是否可行 if (!canMoveFunc(stop)) { result.Success = false; result.ResultList = new List <Vector2>() { stop }; result.SearchAeraCount = SearchDic.Count; return(result); } //待检测点队列 List <Vector2> queue = new List <Vector2>(); SearchDic[start] = 0; queue.Add(start); Vector2 v = start; bool flag = true; //添加点进队列 bool AddNextRoute(Vector2 ov) { if (canMoveFunc(v + ov) && !SearchDic.ContainsKey(v + ov)) { Vector2 np = v + ov; SearchDic[np] = SearchDic[v] + 1; if (np == stop) { flag = false; } else if (np.Distance(stop) <= v.Distance(stop)) { queue.Insert(0, np); } else { queue.Add(np); } } else if ((v + ov) == stop) { flag = false; } return(true); }; while (flag) { if (queue.Count == 0) { result.Success = false; result.ResultList = new List <Vector2>() { stop }; result.SearchAeraCount = SearchDic.Count; return(result); } else { //取第一个点,值最小的点 v = queue[0]; //添加周围的点 AddNextRoute(new Vector2(1, 0)); AddNextRoute(new Vector2(-1, 0)); AddNextRoute(new Vector2(0, 1)); AddNextRoute(new Vector2(0, -1)); //去掉这个点 queue.Remove(v); } } //结果路径 List <Vector2> path = new List <Vector2>(); path.Add(stop); while (true) { v = path.First(); if (v == start) { break; } //将周围最小的一个点加入下一步 List <RouteData> minSet = new List <RouteData>(); minSet.Add(new RouteData(v + Vector2.Left, SearchDic)); minSet.Add(new RouteData(v + Vector2.Right, SearchDic)); minSet.Add(new RouteData(v + Vector2.Up, SearchDic)); minSet.Add(new RouteData(v + Vector2.Down, SearchDic)); minSet.Sort(); path.Insert(0, minSet[0].vector); } result.ResultList = path; result.SearchAeraCount = SearchDic.Count; return(result); }
/// <summary> /// 使用路径字典初始化 /// </summary> public RouteData(Vector2 v, RouteDic dic) { vector = v; depth = dic[v]; }