Beispiel #1
0
    bool checkPos(Pos cur, int dx, int dy)
    {
        var o_score = astar_search[cur.y + dy, cur.x + dx];

        if (o_score != null && o_score.closed)
        {
            return(false);
        }

        var cur_score = astar_search[cur.y, cur.x];
        Pos o_pos     = new Pos(cur.x + dx, cur.y + dy);

        if (mapInstance.map[cur.y + dy, cur.x + dx] == 8)
        {
            var a = new AScore(cur_score.G + 1, 0);
            a.parent = cur;
            astar_search[cur.y + dy, cur.x + dx] = a;
            Debug.Log("寻路完成。");
            return(true);
        }
        if (mapInstance.map[cur.y + dy, cur.x + dx] == 0)
        {
            if (o_score == null)
            {// 在open表中没有该节点,计算该节点的h与g值,并把
                var a = new AScore(cur_score.G + 1, Pos.AStarDistance(o_pos, mapInstance.endPos));
                a.parent = cur;
                astar_search[cur.y + dy, cur.x + dx] = a;
                list.Add(o_pos);
            }
            else if (o_score.G > cur_score.G + 1)
            {// 在Open表中有该节点,比较两个x的G值,更新目标节点的G值。
                o_score.G      = cur_score.G + 1;
                o_score.parent = cur;
                if (!list.Contains(o_pos))
                {// 如果检查列表中没有该节点,加入
                    list.Add(o_pos);
                }
            }
        }
        return(false);
    }
Beispiel #2
0
    IEnumerator Astar_search()
    {
        astar_search = new AScore[map.GetLength(0), map.GetLength(1)];

        List <Pos> list = new List <Pos>();

        astar_search[StartPosition.y, StartPosition.x] = new AScore(0, 0);
        list.Add(StartPosition);

        // 每一个点的处理函数
        Func func = (Pos cur, int ox, int oy) =>
        {
            var o_score = astar_search[cur.y + oy, cur.x + ox];
            if (o_score != null && o_score.closed)
            {
                return(false);
            }
            var cur_score = astar_search[cur.y, cur.x];
            Pos o_pos     = new Pos(cur.x + ox, cur.y + oy);
            if (map[cur.y + oy, cur.x + ox] == EndPoint)
            {
                var a = new AScore(cur_score.G + 1, 0);
                a.parent = cur;
                astar_search[cur.y + oy, cur.x + ox] = a;
                Debug.Log("寻路完成");
                return(true);
            }
            if (map[cur.y + oy, cur.x + ox] == 0)
            {
                if (o_score == null)
                {
                    var a = new AScore(cur_score.G + 1, Pos.AStarDistance(o_pos, EndPosition));
                    a.parent = cur;
                    astar_search[cur.y + oy, cur.x + ox] = a;
                    list.Add(o_pos);
                }
                else if (o_score.G > cur_score.G + 1)
                {
                    o_score.G      = cur_score.G + 1;
                    o_score.parent = cur;
                    if (!list.Contains(o_pos))
                    {
                        list.Add(o_pos);
                    }
                }
            }
            return(false);
        };


        while (list.Count > 0)
        {
            list.Sort((Pos p1, Pos p2) =>
            {
                AScore a1 = astar_search[p1.y, p1.x];
                AScore a2 = astar_search[p2.y, p2.x];
                //return a1.H.CompareTo(a2.H);
                return(a1.CompareTo(a2));
            });
            Pos cur = list[0];
            list.RemoveAt(0);
            astar_search[cur.y, cur.x].closed = true;


            if (cur.y > 0)
            {
                if (func(cur, 0, -1))
                {
                    break;
                }
            }

            if (cur.y < Height - 1)
            {
                if (func(cur, 0, 1))
                {
                    break;
                }
            }

            if (cur.x > 0)
            {
                if (func(cur, -1, 0))
                {
                    break;
                }
            }

            if (cur.x < Width - 1)
            {
                if (func(cur, 1, 0))
                {
                    break;
                }
            }

            short[,] temp_map = new short[map.GetLength(0), map.GetLength(1)];
            for (int i = 0; i < Height; ++i)
            {
                for (int j = 0; j < Width; ++j)
                {
                    temp_map[i, j] = short.MaxValue;
                    //if (map_search[i,j] != null && map_search[i,j].closed)
                    if (astar_search[i, j] != null)
                    {
                        temp_map[i, j] = (short)astar_search[i, j].F;
                    }
                }
            }
            Show_Search(temp_map);

            yield return(new WaitForSeconds(0.01f));
        }

        yield return(null);
    }
Beispiel #3
0
    //===============-BFS-================================================================================
    #endregion
    #region DFS
    //===============-DFS-================================================================================
    IEnumerator DFS()
    {
        bfs_search = new short[map.GetLength(0), map.GetLength(1)];
        // map_search和map一样大小,每个元素的值:32767(short.MaxValue)代表不可通过或者未探索,其他值代表移动的步数
        for (int i = 0; i < H; ++i)
        {
            for (int j = 0; j < W; ++j)
            {
                bfs_search[i, j] = short.MaxValue;                //先初始化一个标记数组。
            }
        }
        List <Pos> queue = new List <Pos>();
        Func       func  = (Pos cur, int ox, int oy) =>
        {
            //END=9/START=8
            if (map[cur.y + oy, cur.x + ox] == END)                                         //到达END=9
            {
                bfs_search[cur.y + oy, cur.x + ox] = (short)(bfs_search[cur.y, cur.x] + 1); //==-32768
                Debug.Log("Done");
                return(true);
            }
            //起始点的下一个点不为墙并且在地图内
            if (map[cur.y + oy, cur.x + ox] == 0)                                               //bfs_search[startpos,startpos]=[0,0]下面设置,这里判断是否在地图内和不是墙
            {
                if (bfs_search[cur.y + oy, cur.x + ox] > bfs_search[cur.y, cur.x] + 1)          //最初始的bfs_search[cur.y,cur.x]=0;
                {
                    bfs_search[cur.y + oy, cur.x + ox] = (short)(bfs_search[cur.y, cur.x] + 1); //搜索过的地方变成1,标记将去的点为已走过
                    queue.Add(new Pos(cur.x + ox, cur.y + oy));                                 //第二个点入队列表示为current了
                }
            }
            return(false);
        };

        bfs_search[startPos.y, startPos.x] = 0;        //设置起始点的步数为0
        queue.Add(startPos);
        while (queue.Count > 0)
        {
            int   min_i    = 0;
            Pos   cur      = queue[min_i];
            float min_dist = Pos.AStarDistance(cur, endPos);
            for (int i = 0; i < queue.Count; i++)
            {
                float d = Pos.AStarDistance(queue[i], endPos);
                if (d < min_dist)
                {
                    min_i    = i;
                    cur      = queue[i];
                    min_dist = 0;
                }
            }
            queue.RemoveAt(min_i);
            //上
            if (cur.y > 0)
            {
                //000
                //000
                //000  ->2 往上移动为2-1=1 变成第一行
                if (func(cur, 0, -1))
                {
                    break;
                }
            }
            //下
            if (cur.y < H - 1)
            {
                if (func(cur, 0, 1))
                {
                    break;
                }
            }
            //左
            if (cur.x > 0)
            {
                if (func(cur, -1, 0))
                {
                    break;
                }
            }
            //右
            if (cur.x < W - 1)
            {
                if (func(cur, 1, 0))
                {
                    break;
                }
            }
            if (bfs_search[cur.y, cur.x] > cur_depth)         //最初cur_depth=0 第一次后变成1
            {
                cur_depth = bfs_search[cur.y, cur.x];
                RefreshPath(bfs_search);
                yield return(new WaitForSeconds(0.1f));
            }
        }
        gameState = GameState.ShowPath;
        yield  return(null);
    }
Beispiel #4
0
    private AScore[,] astar_search;    //是一个而为的点的信息,点里包含权重,F = G + H ; G为点要走过自身的格子距离,H为到目标点的距离
    IEnumerator AStar()
    {
        astar_search = new AScore[map.GetLength(0), map.GetLength(1)]; //确保星可以遍布在地图每个点
        List <Pos> MapTargetPoslist = new List <Pos>();                //只用来保存要涉及到的点的坐标

        astar_search[startPos.y, startPos.x] = new AScore(0, 0);       //让第一个起始点的G和H为0
        MapTargetPoslist.Add(startPos);                                //将起始点记录进我们路线 ,因为是从此出发

        Func func = (Pos curPos, int ox, int oy) =>
        {
            var tar_Score = astar_search[curPos.y + oy, curPos.x + ox];            //表示下一个去的点;
            if (tar_Score != null && tar_Score.closed)
            {
                return(false);
            }

            var cur_Score = astar_search[curPos.y, curPos.x];            //表示当前所在的点
            Pos nextPos   = new Pos(curPos.x + ox, curPos.y + oy);

            if (map[curPos.y + oy, curPos.x + ox] == END)
            {
                var end_Score = new AScore(cur_Score.G + 1, 0);
                end_Score.parent = curPos;
                astar_search[curPos.y + oy, curPos.x + ox] = end_Score;
                Debug.Log("Done");
                return(true);
            }
            if (map[curPos.y + oy, curPos.x + ox] == 0)     //表示下一个点我们还没走过
            {
                if (tar_Score == null)
                {
                    var a = new AScore(cur_Score.G + 1, Pos.AStarDistance(nextPos, endPos));              //AStarDistance计算了下一个点 中点到endPos的距离放在H里,然后创建下个点
                    a.parent = curPos;
                    astar_search[curPos.y + oy, curPos.x + ox] = a;
                    MapTargetPoslist.Add(nextPos);
                    //Debug.Log("next "+curPos.x+" "+curPos.y);
                }
            }
            return(false);
        };

        while (MapTargetPoslist.Count > 0)
        {
            MapTargetPoslist.Sort((Pos p1, Pos p2) =>
            {
                AScore a1 = astar_search[p1.y, p1.x];
                AScore a2 = astar_search[p2.y, p2.x];
                return(a1.CompareTo(a2));
            });            //得到F最小的点放在list[0]
            Pos cur = MapTargetPoslist[0];
            MapTargetPoslist.RemoveAt(0);
            astar_search[cur.y, cur.x].closed = true;            //标记当前点为 以访问;
            // 上
            if (cur.y > 0)
            {
                if (func(cur, 0, -1))
                {
                    break;
                }
            }
            // 下
            if (cur.y < H - 1)
            {
                if (func(cur, 0, 1))
                {
                    break;
                }
            }
            // 左
            if (cur.x > 0)
            {
                if (func(cur, -1, 0))
                {
                    break;
                }
            }
            // 右
            if (cur.x < W - 1)
            {
                if (func(cur, 1, 0))
                {
                    break;
                }
            }

            short[,] temp_map = new short[map.GetLength(0), map.GetLength(1)];
            for (int i = 0; i < H; ++i)
            {
                for (int j = 0; j < W; ++j)
                {
                    temp_map[i, j] = short.MaxValue;
                    //if (map_search[i,j] != null && map_search[i,j].closed)
                    if (astar_search[i, j] != null)
                    {
                        temp_map[i, j] = (short)astar_search[i, j].F;
                    }
                }
            }
            RefreshPath(temp_map);
            yield return(0);
        }
        Debug.Log("开始显示路线");
        gameState = GameState.ShowPath;
        yield return(null);
    }
Beispiel #5
0
    IEnumerator DFS()
    {
        bfs_search = new short[map.GetLength(0), map.GetLength(1)];

        // map_search和map一样大小,每个元素的值:32767(short.MaxValue)代表不可通过或者未探索,其他值代表移动的步数

        for (int i = 0; i < H; ++i)
        {
            for (int j = 0; j < W; ++j)
            {
                bfs_search[i, j] = short.MaxValue;
            }
        }

        List <Pos> queue = new List <Pos>();

        Func func = (Pos cur, int ox, int oy) =>
        {
            if (map[cur.y + oy, cur.x + ox] == END)
            {
                bfs_search[cur.y + oy, cur.x + ox] = (short)(bfs_search[cur.y, cur.x] + 1);
                Debug.Log("寻路完成");
                return(true);
            }
            if (map[cur.y + oy, cur.x + ox] == 0)
            {
                if (bfs_search[cur.y + oy, cur.x + ox] > bfs_search[cur.y, cur.x] + 1)
                {
                    bfs_search[cur.y + oy, cur.x + ox] = (short)(bfs_search[cur.y, cur.x] + 1);
                    queue.Add(new Pos(cur.x + ox, cur.y + oy));
                }
            }
            return(false);
        };

        bfs_search[startPos.y, startPos.x] = 0;
        queue.Add(startPos);

        while (queue.Count > 0)
        {
            int   min_i    = 0;
            Pos   cur      = queue[min_i];
            float min_dist = Pos.AStarDistance(cur, endPos);
            for (int i = 0; i < queue.Count; ++i)
            {
                float d = Pos.AStarDistance(queue[i], endPos);
                if (d < min_dist)
                {
                    min_i    = i;
                    cur      = queue[i];
                    min_dist = d;
                }
            }

            queue.RemoveAt(min_i);

            int last_count = queue.Count;
            // 上
            bool flag = false;
            if (cur.y > 0)
            {
                if (func(cur, 0, -1))
                {
                    break;
                }
            }
            // 下
            if (cur.y < H - 1)
            {
                if (func(cur, 0, 1))
                {
                    break;
                }
            }
            // 左
            if (cur.x > 0)
            {
                if (func(cur, -1, 0))
                {
                    break;
                }
            }
            // 右
            if (cur.x < W - 1)
            {
                if (func(cur, 1, 0))
                {
                    break;
                }
            }

            RefreshPath(bfs_search);
            yield return(new WaitForSeconds(0.05f));
        }

        gameState = GameState.ShowPath;
        yield return(null);
    }
Beispiel #6
0
    IEnumerator initDFS()
    {
        for (int i = 0; i < Height; i++)
        {
            for (int j = 0; j < Width; j++)
            {
                dfs[i, j] = short.MaxValue;
            }
        }
        dfs[mapInstance.startPos.y, mapInstance.startPos.x] = 0;
        quene.Add(mapInstance.startPos);
        while (quene.Count > 0)
        {
            int   min_i    = 0;
            Pos   cur      = quene[min_i];
            float min_dist = Pos.AStarDistance(cur, mapInstance.endPos);
            for (int i = 0; i < quene.Count; i++)
            {
                float d = Pos.AStarDistance(quene[i], mapInstance.endPos);
                if (d < min_dist)
                {
                    min_i    = i;
                    cur      = quene[i];
                    min_dist = d;
                }
            }

            quene.RemoveAt(min_i);

            int last_Count = quene.Count;
            if (cur.y > 0)
            {
                if (checkPos(cur, 0, -1, 0))
                {
                    break;
                }
            }
            if (cur.y < Height - 1)
            {
                if (checkPos(cur, 0, 1, 1))
                {
                    break;
                }
            }
            if (cur.x > 0)
            {
                if (checkPos(cur, -1, 0, 2))
                {
                    break;
                }
            }
            if (cur.x < Width - 1)
            {
                if (checkPos(cur, 1, 0, 3))
                {
                    break;
                }
            }
            Refresh();
            yield return(new WaitForSeconds(0.05f));
        }
        yield return(null);

        for (int i = 0; i < Height; i++)
        {
            for (int j = 0; j < Width; j++)
            {
                allbfs += dfs[i, j].ToString() + ' ';
            }
            allbfs += '\n';
        }
        // Refresh();
        System.IO.File.WriteAllText(Application.dataPath + "//" + "dfsMap.txt", allbfs, Encoding.UTF8);
        StartCoroutine(visualPath());
    }