Ejemplo n.º 1
0
 public EntityLocationCell()
 {
     X          = 0;
     Y          = 0;
     IsWall     = false;
     G          = 0;
     H          = 0;
     ParentCell = null;
 }
Ejemplo n.º 2
0
        private static int GetDistanceCost(EntityLocationCell cStart, EntityLocationCell cEnd)
        {
            int iDistanceCost = 999;
            int iDistanceX    = Math.Abs(cStart.X - cEnd.X);
            int iDistanceY    = Math.Abs(cStart.Y - cEnd.Y);

            iDistanceCost = iDistanceX + iDistanceY;

            return(iDistanceCost);
        }
Ejemplo n.º 3
0
        private static List <EntityLocationCell> GetAllAroundCells(EntityLocationCell pCurrentCell, List <EntityLocationCell> lstDisableCells)
        {
            List <EntityLocationCell> lstAroundCells = new List <EntityLocationCell>();

            EntityLocationCell cUpCell = new EntityLocationCell();

            cUpCell.X = pCurrentCell.X;
            cUpCell.Y = pCurrentCell.Y - 1;
            if ((cUpCell.X > 0) && (cUpCell.Y > 0))
            {
                lstAroundCells.Add(cUpCell);
            }

            EntityLocationCell cDownCell = new EntityLocationCell();

            cDownCell.X = pCurrentCell.X;
            cDownCell.Y = pCurrentCell.Y + 1;
            if ((cDownCell.X > 0) && (cDownCell.Y > 0))
            {
                lstAroundCells.Add(cDownCell);
            }

            EntityLocationCell cLeftCell = new EntityLocationCell();

            cLeftCell.X = pCurrentCell.X - 1;
            cLeftCell.Y = pCurrentCell.Y;
            if ((cLeftCell.X > 0) && (cLeftCell.Y > 0))
            {
                lstAroundCells.Add(cLeftCell);
            }

            EntityLocationCell cRifhtCell = new EntityLocationCell();

            cRifhtCell.X = pCurrentCell.X + 1;
            cRifhtCell.Y = pCurrentCell.Y;
            if ((cRifhtCell.X > 0) && (cRifhtCell.Y > 0))
            {
                lstAroundCells.Add(cRifhtCell);
            }

            for (int i = 0; i < lstAroundCells.Count; i++)
            {
                if (IsInLocationList(lstAroundCells[i], lstDisableCells))
                {
                    lstAroundCells[i].IsWall = true;
                }
            }

            return(lstAroundCells);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 检查一个Cell是不是在禁止到达的List中
        /// </summary>
        /// <param name="cCurrentCell"></param>
        /// <param name="lstDisableCells"></param>
        /// <returns></returns>
        private static bool IsInLocationList(EntityLocationCell cCurrentCell, List <EntityLocationCell> lstDisableCells)
        {
            bool bIsInLocationList = false;

            if (lstDisableCells == null)
            {
                return(false);
            }
            if (lstDisableCells.Count == 0)
            {
                return(false);
            }

            foreach (EntityLocationCell cell in lstDisableCells)
            {
                if ((cell.X == cCurrentCell.X) && (cell.Y == cCurrentCell.Y))
                {
                    bIsInLocationList = true;
                    break;
                }
            }

            return(bIsInLocationList);
        }
Ejemplo n.º 5
0
        //Point p = new System.Drawing.Point();
        public static List <EntityLocationCell> FindPath(EntityLocationCell pStartLocation, EntityLocationCell pEndLocation, List <EntityLocationCell> lstDisableCells, bool bIncludeStartPoint = false)
        {
            List <EntityLocationCell> lstPathReturn = new List <EntityLocationCell>();

            bool bIsOutputDebug = false;

            int iShowFindNum = 1;

            //开启列表
            List <EntityLocationCell> OpenList = new List <EntityLocationCell>();
            //关闭列表
            List <EntityLocationCell> CloseList = new List <EntityLocationCell>();

            //起点
            EntityLocationCell pStart = pStartLocation;
            //终点
            EntityLocationCell pEnd = pEndLocation;

            System.Diagnostics.Debug.WriteLine("寻路开始,start({0},{1}),end({2},{3})...", pStart.X, pStart.Y, pEnd.X, pEnd.Y);

            //将起点作为待处理的点放入开启列表,
            OpenList.Add(pStart);

            //如果开启列表没有待处理点表示寻路失败,此路不通
            while (OpenList.Count > 0)
            {
                //遍历开启列表,找到消费最小的点作为检查点
                EntityLocationCell pCurrentCell = OpenList[0];
                for (int i = 0; i < OpenList.Count; i++)
                {
                    if (OpenList[i].F < pCurrentCell.F && OpenList[i].H < pCurrentCell.H)
                    {
                        pCurrentCell = OpenList[i];
                        break;
                    }
                }
                if (bIsOutputDebug)
                {
                    System.Diagnostics.Debug.WriteLine("当前检查点:(" + pCurrentCell.X + "," + pCurrentCell.Y + ") 编号:" + iShowFindNum + "  open列表节点数量:" + OpenList.Count);
                }

                //if (iShowFindNum == 438)
                //{
                //    Console.WriteLine(iShowFindNum.ToString());
                //}

                //显示在界面,和A*算法无关
                //pCurrentCell.obj.transform.Find("Num").GetComponent<Text>().text = showFindNum.ToString();
                iShowFindNum++;

                //从开启列表中删除检查点,把它加入到一个“关闭列表”,列表中保存所有不需要再次检查的方格。
                OpenList.Remove(pCurrentCell);
                CloseList.Add(pCurrentCell);

                //检查是否找到终点
                if ((pCurrentCell.X == pEnd.X) && (pCurrentCell.Y == pEnd.Y))
                {
                    Console.WriteLine("寻路结束");

                    lstPathReturn.Add(pCurrentCell); //加入终点

                    EntityLocationCell cRecall = new EntityLocationCell();
                    cRecall = pCurrentCell.ParentCell;

                    while (!((cRecall.X == pStart.X) && (cRecall.Y == pStart.Y)))
                    {
                        EntityLocationCell cRecallAdd = new EntityLocationCell();
                        //cRecallAdd.X = cRecall.X;
                        //cRecallAdd.Y = cRecall.Y;
                        cRecallAdd = cRecall;
                        lstPathReturn.Add(cRecallAdd);

                        EntityLocationCell cRecallTemp = new EntityLocationCell();
                        cRecallTemp = cRecall.ParentCell;

                        cRecall = cRecallTemp;
                    }
                    //根据参数bIncludeStartPoint判断是否要加入起点在返回值list中
                    if (bIncludeStartPoint)
                    {
                        lstPathReturn.Add(pStart); //加入起点
                    }
                    string sMessage = "";
                    for (int i = lstPathReturn.Count; i > 0; i--)
                    {
                        if (i > 1)
                        {
                            sMessage += "(" + lstPathReturn[i - 1].X + "," + lstPathReturn[i - 1].Y + ") ->";
                        }
                        else
                        {
                            sMessage += "(" + lstPathReturn[i - 1].X + "," + lstPathReturn[i - 1].Y + ")";
                        }
                    }
                    System.Diagnostics.Debug.WriteLine(sMessage);

                    System.Diagnostics.Debug.WriteLine("FindNum:" + iShowFindNum.ToString() + ",OpenList:" + OpenList.Count + ",CloseList:" + CloseList.Count);

                    return(lstPathReturn);
                }
                //if (pCurrentCell == pEnd)
                //{
                //    Console.WriteLine("寻路结束!");
                //    //grid.CreatePath(pCurrentCell);
                //    return;
                //}

                //根据检查点来找到周围可行走的点
                //1.如果是墙或者在关闭列表中则跳过
                //2.如果点不在开启列表中则添加
                //3.如果点在开启列表中且当前的总花费比之前的总花费小,则更新该点信息
                List <EntityLocationCell> listAroundCells = GetAllAroundCells(pCurrentCell, lstDisableCells);
                foreach (EntityLocationCell cell in listAroundCells)
                {
                    if (cell.IsWall || CloseList.Contains(cell))
                    {
                        continue;
                    }

                    int iAroundCellCostG = pCurrentCell.G + GetDistanceCost(cell, pCurrentCell);

                    if (iAroundCellCostG < cell.G || !OpenList.Contains(cell))
                    {
                        cell.G          = iAroundCellCostG;
                        cell.H          = GetDistanceCost(cell, pEnd);
                        cell.F          = cell.G + cell.H;
                        cell.ParentCell = pCurrentCell;
                        if (bIsOutputDebug)
                        {
                            System.Diagnostics.Debug.WriteLine("cell:(" + cell.X + "," + cell.Y + ")  parent:(" + pCurrentCell.X + "," + pCurrentCell.Y + ")  " + cell.F);
                        }
                        //if (!OpenList.Contains(cell)) //这个Contains必须完全相同,G值F值等会造成反复加入
                        bool bContain = false;
                        foreach (EntityLocationCell co in OpenList)
                        {
                            if ((co.X == cell.X) && (co.Y == cell.Y))
                            {
                                bContain = true;
                                break;
                            }
                        }
                        if (!bContain)
                        {
                            OpenList.Add(cell);
                        }

                        //显示在界面,和A*算法无关
                        //cell.obj.transform.Find("Cost").GetComponent<Text>().text = cell.fCost.ToString();
                    }
                }
            }

            System.Diagnostics.Debug.WriteLine("寻路失败!");
            return(null);
        }