Beispiel #1
0
    //获得成本最小的节点
    AstarListNode AstarGetMinCostList(AstarList astar)
    {
        AstarListNode min     = astar.openHead.next;
        AstarListNode current = min.next;

        while (current != null)
        {
            if (current.h < min.h)
            {
                min = current;
            }
            current = current.next;
        }
        return(min);
    }
Beispiel #2
0
    public bool AStarSearch(List <List <int> > map, int startX, int startY, int endX, int endY)
    {
        astarPathCount = 0;
        astarPathList.Clear();
        _map    = map;
        _startX = startX;
        _startY = startY;
        _endX   = endX;
        _endY   = endY;

        if (AstarIsBlock(endX, endY))
        {
            return(false);
        }
        int[] offsetX = new int[] { 0, 0, -1, 1 };
        int[] offsetY = new int[] { 1, -1, 0, 0 };
//		int[] offsetX = new int[]{0, 0, -1, 1, -1, -1, 1, 1};
//		int[] offsetY = new int[]{1, -1, 0, 0, 1, -1, 1, -1};
        AstarList astar = new AstarList();

        astar.openHead   = new AstarListNode();
        astar.closedHead = new AstarListNode();
        AstarListNode currentNode = null;
        AstarListNode startNode   = new AstarListNode();

        AstarNodeInit(startNode, null, _startX, _startY, _endX, _endY);
        AstarAddNode(astar.openHead, startNode);

        while (astar.openHead.next != null)
        {
            currentNode = AstarGetMinCostList(astar);
            if (currentNode.x == endX && currentNode.y == endY)
            {
                break;
            }
            else
            {
                AstarAddNode(astar.closedHead, currentNode);
                AstarRemoveNode(astar.openHead, currentNode);
                for (int i = 0; i < 4; i++)
                {
                    int x = currentNode.x + offsetX[i];
                    int y = currentNode.y + offsetY[i];
                    if (x < 0 || x >= _map.Count || y < 0 || y >= _map[0].Count)
                    {
                        continue;
                    }
                    else
                    {
                        if (!AstarCheckNodeInList(x, y, astar.openHead) &&
                            !AstarCheckNodeInList(x, y, astar.closedHead) &&
                            !AstarIsBlock(x, y))
                        {
                            AstarListNode endNode = new AstarListNode();
                            AstarNodeInit(endNode, currentNode, x, y, endX, endY);
                            AstarAddNode(astar.openHead, endNode);
                        }
                    }
                }
            }
        }
        if (astar.openHead.next == null && (currentNode.x != endX || currentNode.y != endY))
        {
            astarPathCount = 0;
        }
        else
        {
            while (currentNode != null)
            {
                Vector2i point = new Vector2i();
                point.x = currentNode.x;
                point.y = currentNode.y;
                //astarPathList.Add(point);
                astarPathList.Insert(0, point);
                currentNode = currentNode.father;
                astarPathCount++;
            }
            return(true);
        }
        return(false);
    }
Beispiel #3
0
        /// <summary>
        /// 重启A*寻路,最短路径保存在Player1MinRoad或Player2MinRoad中,返回最短路径长度
        /// </summary>
        /// <param name="Player">寻路玩家</param>
        /// <param name="Location_row">该玩家所在位置行</param>
        /// <param name="Location_col">该玩家所在位置列</param>
        /// <returns>最短路径长度</returns>
        public int AstarRestart(ChessBoard ToAstarSearch, EnumNowPlayer Player, int Location_row, int Location_col)
        {
            //bool IfContains = false;
            System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start(); //  开始监视代码运行时间
            /***************待测代码段****************/

            //int TableSearchResult = 0;
            //string BoardHashCode = LookupRoadAlgorithm.ResultSaveTable.GetHashCode_String(
            //    ToAstarSearch, Player);
            //if (ResultSaveTable.Search(BoardHashCode, ref TableSearchResult))
            //{
            //    Console.WriteLine("此局面已在存储表中!K值:" + BoardHashCode + "V值:" + TableSearchResult.ToString());
            //    /***************待测代码段****************/
            //    stopwatch.Stop(); //  停止监视
            //    TimeSpan timespan = stopwatch.Elapsed; //  获取当前实例测量得出的总时间
            //    Console.WriteLine("存储表命中寻路用时:" + timespan.TotalMilliseconds.ToString() + "ms");
            //    //return TableSearchResult;
            //    IfContains = true;
            //}
            //else
            //{
            //    /***************待测代码段****************/
            //    stopwatch.Stop(); //  停止监视
            //    TimeSpan timespan2 = stopwatch.Elapsed; //  获取当前实例测量得出的总时间
            //    Console.WriteLine("存储表查询费时:" + timespan2.TotalMilliseconds.ToString() + "ms");
            //}
            //stopwatch.Restart();
            /***************待测代码段****************/

            Min_DistanceLength = 999;
            List <AstarList> InitAList = new List <AstarList>();

            Astar_Stop = false;

            AstarList InitGrid = new AstarList(6, 0, 6, Location_row, Location_col);

            InitAList.Add(InitGrid);

            int distance = LookupRoad_Astar(ToAstarSearch, Player, InitGrid, 1,
                                            new List <AstarList>(), InitAList);

            /***************待测代码段****************/
            stopwatch.Stop();                       //  停止监视
            TimeSpan timespan3 = stopwatch.Elapsed; //  获取当前实例测量得出的总时间

            if (QuoridorEvalution.AIRunTime.Astar_s == 0)
            {
                QuoridorEvalution.AIRunTime.Astar_s = timespan3.TotalMilliseconds;
            }
            else
            {
                QuoridorEvalution.AIRunTime.Astar_s += timespan3.TotalMilliseconds;
                QuoridorEvalution.AIRunTime.Astar_s /= 2;
            }
            QuoridorEvalution.AIRunTime.AstarNum++;

            //if (!IfContains)
            //    LookupRoadAlgorithm.ResultSaveTable.Add(BoardHashCode, Min_DistanceLength);

            return(Min_DistanceLength);
        }
Beispiel #4
0
        /// <summary>
        /// A*寻路,最短路径保存在Player1MinRoad或Player2MinRoad中,返回最短路径长度
        /// </summary>
        /// <param name="Player">寻路玩家</param>
        /// <param name="NowGrid">当前寻路的格子</param>
        /// <param name="num_renew">迭代次数</param>
        /// <param name="OpenList">Open列表</param>
        /// <param name="CloseList">Close列表</param>
        /// <returns></returns>
        public int LookupRoad_Astar(ChessBoard ThisChessBoard, EnumNowPlayer Player, AstarList NowGrid, int num_renew, List <AstarList> OpenList, List <AstarList> CloseList)
        {
            int Location_row = NowGrid.Grid_row;
            int Location_col = NowGrid.Grid_col;

            if (Astar_Stop == true)
            {
                return(Min_DistanceLength);
            }

            int Row_Destination = 0;

            #region 设置目的地行
            switch (Player)
            {
            case EnumNowPlayer.Player1:
                Row_Destination = 6;
                break;

            case EnumNowPlayer.Player2:
                Row_Destination = 0;
                break;

            default:
                break;
            }
            #endregion

            #region 检查四周能移动的位置添加进P_List_Enable列表
            //计算四周能移动的位置的距离
            List <Point> P_List_Enable = new List <Point>();
            //左
            if (Location_col > 0 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col].IfLeftBoard))
            {
                P_List_Enable.Add(new Point(Location_row, Location_col - 1));
            }
            //右
            if (Location_col < 6 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col + 1].IfLeftBoard))
            {
                P_List_Enable.Add(new Point(Location_row, Location_col + 1));
            }
            //上
            if (Location_row > 0 &&
                !(ThisChessBoard.ChessBoardAll[Location_row, Location_col].IfUpBoard))
            {
                P_List_Enable.Add(new Point(Location_row - 1, Location_col));
            }
            //下
            if (Location_row < 6 &&
                !(ThisChessBoard.ChessBoardAll[Location_row + 1, Location_col].IfUpBoard))
            {
                P_List_Enable.Add(new Point(Location_row + 1, Location_col));
            }
            #endregion

            #region   扫描是否有木板,用来减少搜索空间
            bool flag_NoBoard      = true;
            bool flag_UpNowBoard   = true;
            bool flag_DownNowBoard = true;

            for (int k = Location_row + 1; k <= Row_Destination; k++)//下扫
            {
                if (ThisChessBoard.ChessBoardAll[k, Location_col].IfUpBoard)
                {
                    flag_DownNowBoard = false;
                    break;
                }
            }
            for (int k = Location_row - 1; k >= Row_Destination; k--)//上扫
            {
                if (ThisChessBoard.ChessBoardAll[k + 1, Location_col].IfUpBoard)
                {
                    flag_UpNowBoard = false;
                    break;
                }
            }
            if (flag_DownNowBoard && flag_UpNowBoard)
            {
                flag_NoBoard = true;
            }
            else
            {
                flag_NoBoard = false;
            }

            if (flag_NoBoard)
            {
                Astar_Stop         = true;
                Min_DistanceLength = Math.Abs((Row_Destination - Location_row)) + CloseList.Last().G;

                #region 迭代寻找最短路径
                List <Point> MinRoad;
                if (Player == EnumNowPlayer.Player1)
                {
                    Player1MinRoad = new List <Point>();
                    MinRoad        = Player1MinRoad;
                }
                else
                {
                    Player2MinRoad = new List <Point>();
                    MinRoad        = Player2MinRoad;
                }

                if (Location_row < Row_Destination)
                {
                    for (int i = Row_Destination; i >= Location_row; i--)
                    {
                        MinRoad.Add(new Point(i, Location_col));
                    }
                }
                else
                {
                    for (int i = Row_Destination; i <= Location_row; i++)
                    {
                        MinRoad.Add(new Point(i, Location_col));
                    }
                }
                AstarList ALBuff = CloseList.Last();
                while (true)
                {
                    if (ALBuff.Father != null)
                    {
                        MinRoad.Add(new Point(ALBuff.Father.Grid_row, ALBuff.Father.Grid_col));
                        ALBuff = ALBuff.Father;
                    }
                    else
                    {
                        break;
                    }
                }
                #endregion
                return(Min_DistanceLength);
            }

            #endregion

            #region 搜索树搜索策略——A*算法
            List <int> P_Dis = new List <int>();
            for (int i = 0; i < P_List_Enable.Count; i++)
            {
                P_Dis.Add(999);
            }
            int minF     = 9999;
            int minindex = 0;
            for (int i = 0; i < P_List_Enable.Count && i >= 0; i++)
            {
                int Hbuff = Math.Abs(P_List_Enable[i].X - Row_Destination);
                P_Dis[i] = Hbuff;
                int  Gbuff        = num_renew;
                int  Fbuff        = Hbuff + Gbuff;
                bool flag_InClose = false;
                //检测是否在Close列表里
                for (int j = 0; j < CloseList.Count; j++)
                {
                    if (P_List_Enable[i].X == CloseList[j].Grid_row && P_List_Enable[i].Y == CloseList[j].Grid_col)
                    {
                        P_List_Enable.Remove(P_List_Enable[i]);
                        P_Dis.Remove(P_Dis[i]);
                        i--;
                        flag_InClose = true;
                        break;
                    }
                }
                if (flag_InClose)
                {
                    continue;
                }

                bool flag_InOpen = false;
                //检测是否在Open列表里
                for (int j = 0; j < OpenList.Count; j++)
                {
                    if (P_List_Enable[i].X == OpenList[j].Grid_row && P_List_Enable[i].Y == OpenList[j].Grid_col)
                    {
                        P_List_Enable.Remove(P_List_Enable[i]);
                        P_Dis.Remove(P_Dis[i]);
                        i--;
                        flag_InOpen = true;

                        if (Gbuff < OpenList[j].G)
                        {
                            OpenList[j].G      = Gbuff;
                            OpenList[j].F      = Fbuff;
                            OpenList[j].H      = Hbuff;
                            OpenList[j].Father = NowGrid;
                        }
                        break;
                    }
                }

                if (!flag_InOpen && !flag_InClose)
                {
                    AstarList NewGrid = new AstarList(Hbuff, Gbuff, Fbuff, P_List_Enable[i].X, P_List_Enable[i].Y);
                    NewGrid.Father = NowGrid;
                    OpenList.Add(NewGrid);
                }
            }
            AstarList MinFGrid = new AstarList(-1, -1, -1, -1, -1);
            for (int i = 0; i < OpenList.Count; i++)
            {
                int Fbuff = OpenList[i].F;
                if (Fbuff < minF)
                {
                    minF     = Fbuff;
                    minindex = i;
                    MinFGrid = OpenList[i];
                }
            }
            CloseList.Add(MinFGrid);

            int dislengthbuff = 0;
            if (MinFGrid.Grid_row == Row_Destination && Astar_Stop == false)
            {
                Min_DistanceLength += MinFGrid.G;
                Astar_Stop          = true;
                return(Min_DistanceLength);
            }
            else
            {
                if (OpenList.Count > 0)
                {
                    OpenList.Remove(MinFGrid);
                    dislengthbuff = LookupRoad_Astar(ThisChessBoard, Player, MinFGrid, MinFGrid.G + 1, OpenList, CloseList);
                }
                else
                {
                    return(999);
                }
            }
            #endregion

            return(dislengthbuff);
        }