Exemplo n.º 1
0
        public void PrepareToCompute(GridCell[][] map)
        {
            this.map = map;

            if (mapData == null || mapData.Length != map.Length)
            {
                mapData = new GridCellData[map.Length][];
            }

            for (int i = 0; i < mapData.Length; i++)
            {
                if (mapData[i] == null)
                {
                    mapData[i] = new GridCellData[map.Length];
                }

                for (int j = 0; j < mapData.Length; j++)
                {
                    if (mapData[i][j] == null)
                    {
                        mapData[i][j] = new GridCellData();
                    }

                    mapData[i][j].cell        = map[i][j];
                    mapData[i][j].computed    = false;
                    mapData[i][j].nextInQueue = null;
                    mapData[i][j].prevInQueue = null;
                    mapData[i][j].prev        = null;
                    mapData[i][j].foward      = null;
                }
            }

            startCellData = mapData[start.y][start.x];
            startCellData.distanceFromEnd   = PathFindingManager.GetDistanceFromEnd(start, end);
            startCellData.distanceFromStart = 0;
            startCellData.weightDijkstra    = startCellData.distanceFromStart + startCellData.cell.traverseWeight;
            startCellData.weightGreedyFirst = startCellData.distanceFromEnd + startCellData.cell.traverseWeight;
            startCellData.weightAStar       = startCellData.distanceFromEnd + startCellData.distanceFromStart + startCellData.cell.traverseWeight;
            startCellData.computed          = true;

            if (analizedCells == null)
            {
                analizedCells = new List <GridCellData>();
            }
            if (path == null)
            {
                path = new List <GridCell>();
            }
            if (queue == null)
            {
                queue = new List <GridCellData>();
            }

            analizedCells.Clear();
            path.Clear();
            queue.Clear();
            queue.Add(startCellData);
        }
Exemplo n.º 2
0
 public void PreparePath(PathData pathData, GridCellData headPathData)
 {
     while (headPathData != null)
     {
         pathData.path.Add(headPathData.cell);
         headPathData = headPathData.prev;
         if (headPathData != null && (headPathData.cell == pathData.start || headPathData.cell == pathData.end))
         {
             break;
         }
     }
 }
Exemplo n.º 3
0
        public bool ComputeCell(PathData path, GridCellData computingCell, GridCellData current, float transitionWeight)
        {
            if (!current.computed)
            {
                current.prev              = computingCell;
                current.distanceFromEnd   = GetDistanceFromEnd(current.cell, path.end) * 8;
                current.distanceFromStart = computingCell.distanceFromStart + current.cell.traverseWeight * transitionWeight;
                current.weightDijkstra    = current.distanceFromStart;
                current.weightGreedyFirst = current.distanceFromEnd + current.cell.traverseWeight * 40;
                current.weightAStar       = current.distanceFromEnd + current.distanceFromStart;

                current.computed = true;
                path.analizedCells.Add(current);

                AddGridCellDataToQueue(path, current);
            }
            {
                //else
                //{
                //    float distanceFromStart = computingCell.distanceFromStart + current.cell.traverseWeight * transitionWeight;
                //    if (current.distanceFromStart > distanceFromStart)
                //    {
                //        current.prev = computingCell;
                //        current.distanceFromStart = distanceFromStart;
                //        current.weightDijkstra = current.distanceFromStart;
                //        current.weightGreedyFirst = current.distanceFromEnd + current.cell.traverseWeight * 40;
                //        current.weightAStar = current.distanceFromEnd + distanceFromStart;
                //        AddGridCellDataToQueue(path, current);
                //    }
                //}
            }



            if (current.cell == path.end)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 4
0
        private void AddGridCellDataToQueue(PathData path, GridCellData data)
        {
            LinkedList <GridCellData> datas = new LinkedList <GridCellData>();

            int start = 0;
            int end   = path.queue.Count;
            int index = 0;

            while (start < end)
            {
                index = (start + end) / 2;

                PathType type = path.pathType;
                if (data.GetWeight(type) < path.queue[index].GetWeight(type))
                {
                    start = index + 1;
                }
                else
                {
                    end = index;
                }
            }
            path.queue.Insert(index, data);
        }
Exemplo n.º 5
0
        public void ComputePath(GridCell[][] map, PathData pathData, Action <bool> finishCallback)
        {
            lock (pathData) { pathData.state = PathState.Computing; }
            pathData.PrepareToCompute(map);

            GridCellData computingCell = pathData.startCellData;

            if (pathData.start.traverseWeight == -1 || pathData.end.traverseWeight == -1 || pathData.end == pathData.startCellData.cell)
            {
                pathData.queue.Clear();
            }

            int loops = 0;

            while (pathData.state == PathState.Computing && pathData.queue.Count > 0)
            {
                loops++;
                if (pathData.waitThread && loops % 3 == 0)
                {
                    Thread.Sleep(1);
                }


                computingCell = pathData.queue[pathData.queue.Count - 1];
                pathData.queue.RemoveAt(pathData.queue.Count - 1);

                for (int i = 0; i < computations.Length; i++)
                {
                    int weight = i != 0 && i % 2 == 1 ? UnityEngine.Random.Range(14, 17) : 10;
                    int x      = computingCell.cell.x + computations[i][1];
                    int y      = computingCell.cell.y + computations[i][0];

                    if (map.Length > y && y >= 0 && map.Length > x && x >= 0 && /*map[y][x].traverseWeight >= 0 */ IsTraversable(map, computingCell.cell, map[y][x]))
                    {
                        GridCellData current = pathData.mapData[y][x];
                        if (ComputeCell(pathData, computingCell, current, weight))
                        {
                            pathData.queue.Clear();
                            computingCell = current;
                            break;
                        }
                    }
                }
            }

            if (computingCell.cell == pathData.end)
            {
                PreparePath(pathData, computingCell);
                if (pathData.waitThread)
                {
                    Thread.Sleep(1000);
                }
            }

            lock (pathData)
            {
                if (pathData.state == PathState.Computing)
                {
                    pathData.state = PathState.Idle;
                    ThreadManager.instance.RunOnMainThread(() => finishCallback(computingCell.cell == pathData.end));
                }
            }
            if (pathData.state == PathState.ReadyToCompute)
            {
                ComputePath(map, pathData, finishCallback);
            }
        }
Exemplo n.º 6
0
        IEnumerator DelayedComputePath(GridCell[][] map, PathData pathData, Action <bool> finishCallback)
        {
            yield return(null);

            //System.Random rnd = new System.Random();
            pathData.state = PathState.Computing;
            pathData.PrepareToCompute(map);
            GridCellData computingCell = pathData.startCellData;

            if (pathData.start.traverseWeight == -1 || pathData.end.traverseWeight == -1 || pathData.end == pathData.startCellData.cell)
            {
                pathData.queue.Clear();
            }

            int loops = 0;

            while (pathData.state == PathState.Computing && pathData.queue.Count > 0)
            {
                loops++;
                if (pathData.waitThread && loops % 20 == 0)
                {
                    yield return(null);
                }

                computingCell = pathData.queue[pathData.queue.Count - 1];
                pathData.queue.RemoveAt(pathData.queue.Count - 1);
                //computations = computations.OrderBy((x) => rnd.Next()).ToArray();
                for (int i = 0; i < computations.Length; i++)
                {
                    var   comp   = computations[(i + Time.frameCount) % computations.Length];
                    float weight = comp[1] == comp[1] || comp[1] == -comp[1] ? 1.45f : 1;
                    int   x      = computingCell.cell.x + comp[1];
                    int   y      = computingCell.cell.y + comp[0];

                    if (map.Length > y && y >= 0 && map.Length > x && x >= 0 && IsTraversable(map, computingCell.cell, map[y][x]))
                    {
                        GridCellData current = pathData.mapData[y][x];
                        if (ComputeCell(pathData, computingCell, current, weight))
                        {
                            pathData.queue.Clear();
                            computingCell = current;
                            break;
                        }
                    }
                }
            }

            if (computingCell.cell == pathData.end)
            {
                PreparePath(pathData, computingCell);
                if (pathData.waitThread)
                {
                    yield return(new WaitForSeconds(1));
                }
            }

            if (pathData.state == PathState.Computing)
            {
                pathData.state = PathState.Idle;
                finishCallback(computingCell.cell == pathData.end);
            }
            else if (pathData.state == PathState.ReadyToCompute)
            {
                StartCoroutine(DelayedComputePath(map, pathData, finishCallback));
            }
        }