Пример #1
0
 // Update And Re-Issue PathQuery From Start
 public PathQuery ReissuePathQuery(PathQuery query, Vector2 start, Vector2 goal, int teamIndex)
 {
     if (query != null)
     {
         query.IsOld = true;
     }
     query = new PathQuery(start, goal, teamIndex);
     Add(query);
     return(query);
 }
 public SquadQuery(RTSSquad s, PathQuery q)
 {
     Squad = s;
     Query = q;
 }
Пример #3
0
 public void Add(PathQuery q)
 {
     queries.Enqueue(q);
 }
Пример #4
0
        // Run A* Search, Given This Pathfinder's World And A Query
        private void Pathfind(PathQuery q)
        {
            // Initialization
            isThoughtCollidable = new bool[World.numCells.X, World.numCells.Y];
            start = HashHelper.Hash(q.Start, World.numCells, World.size);
            end = HashHelper.Hash(q.End, World.numCells, World.size); ;
            for(int y = 0; y < World.numCells.Y; y++) {
                for(int x = 0; x < World.numCells.X; x++) {
                    fScore[x, y] = int.MaxValue;
                    gScore[x, y] = int.MaxValue;
                }
            }
            // Precondition: Any Buildings In World Have Valid Centers
            var viewedBuildings = gameState.teams[q.FOWIndex].ViewedEnemyBuildings;
            foreach(var vb in viewedBuildings) {
                var vbData = gameState.teams[vb.Team].Race.Buildings[vb.Type];
                Point p = vb.CellPoint;
                for(int y = 0; y < vbData.GridSize.Y; y++) {
                    for(int x = 0; x < vbData.GridSize.X; x++) {
                        isThoughtCollidable[p.X + x, p.Y + y] = true;
                    }
                }
            }
            gScore[start.X, start.Y] = 0;
            fScore[start.X, start.Y] = Estimate(start.X, start.Y);
            var openSet = new MinHeap<Point>(Comparison, 30);
            openSet.Insert(start);

            // A* Loop
            List<Point> path = null;
            while(openSet.Count > 0) {
                Point p = openSet.Pop();
                if(p.X == end.X && p.Y == end.Y) {
                    path = new List<Point>();
                    BuildPath(path, end);
                    break;
                }
                bool canMove = false;
                foreach(Point n in NeighborhoodAlign(p).Where(InGrid)) {
                    int tgs = gScore[p.X, p.Y] + 10;
                    canMove = CanMoveFrom(p, n, q.FOWIndex);
                    if(canMove && tgs < gScore[n.X, n.Y]) {
                        prev[n.X, n.Y] = p;
                        gScore[n.X, n.Y] = tgs;
                        fScore[n.X, n.Y] = gScore[n.X, n.Y] + Estimate(n.X, n.Y);
                        if(!openSet.Contains(n)) {
                            openSet.Insert(n);
                        }
                    }
                }
                foreach(Point n in NeighborhoodDiag(p).Where(InGrid)) {
                    int tgs = gScore[p.X, p.Y] + 14;
                    // To Move Diagonally, Destination Must Be Reachable By Horizontal & Vertical Moves As Well
                    canMove = CanMoveFrom(p, n, q.FOWIndex);
                    foreach(Point d in DiagDecomp(p, n)) {
                        canMove &= CanMoveFrom(p, d, q.FOWIndex);
                    }
                    if(canMove && tgs < gScore[n.X, n.Y]) {
                        prev[n.X, n.Y] = p;
                        gScore[n.X, n.Y] = tgs;
                        fScore[n.X, n.Y] = gScore[n.X, n.Y] + Estimate(n.X, n.Y);
                        if(!openSet.Contains(n)) {
                            openSet.Insert(n);
                        }
                    }
                }
            }

            // Check If We Need To Find The Nearest Point
            if(path == null) {
                int s;
                bool[,] ch = new bool[World.numCells.X, World.numCells.Y];
                Array.Clear(ch, 0, ch.Length);
                Point cg = FindClosestGoal(end, fScore, ch, out s, 0);
                if(s == int.MaxValue) {
                    // Impossible
                }
                else {
                    path = new List<Point>();
                    BuildPath(path, cg);
                }
            }

            // A* Conclusion
            if(path != null) {
                foreach(Point wp in path) {
                    q.waypoints.Add(new Vector2(((float)wp.X + 0.5f) * World.cellSize, ((float)wp.Y + 0.5f) * World.cellSize));
                }
            }
            q.IsComplete = true;
        }
Пример #5
0
 // Update And Re-Issue PathQuery From Start
 public PathQuery ReissuePathQuery(PathQuery query, Vector2 start, Vector2 goal, int teamIndex)
 {
     if(query != null)
         query.IsOld = true;
     query = new PathQuery(start, goal, teamIndex);
     Add(query);
     return query;
 }
Пример #6
0
 public void Add(PathQuery q)
 {
     queries.Enqueue(q);
 }
Пример #7
0
        // Run A* Search, Given This Pathfinder's World And A Query
        private void Pathfind(PathQuery q)
        {
            // Initialization
            isThoughtCollidable = new bool[World.numCells.X, World.numCells.Y];
            start = HashHelper.Hash(q.Start, World.numCells, World.size);
            end   = HashHelper.Hash(q.End, World.numCells, World.size);;
            for (int y = 0; y < World.numCells.Y; y++)
            {
                for (int x = 0; x < World.numCells.X; x++)
                {
                    fScore[x, y] = int.MaxValue;
                    gScore[x, y] = int.MaxValue;
                }
            }
            // Precondition: Any Buildings In World Have Valid Centers
            var viewedBuildings = gameState.teams[q.FOWIndex].ViewedEnemyBuildings;

            foreach (var vb in viewedBuildings)
            {
                var   vbData = gameState.teams[vb.Team].Race.Buildings[vb.Type];
                Point p      = vb.CellPoint;
                for (int y = 0; y < vbData.GridSize.Y; y++)
                {
                    for (int x = 0; x < vbData.GridSize.X; x++)
                    {
                        isThoughtCollidable[p.X + x, p.Y + y] = true;
                    }
                }
            }
            gScore[start.X, start.Y] = 0;
            fScore[start.X, start.Y] = Estimate(start.X, start.Y);
            var openSet = new MinHeap <Point>(Comparison, 30);

            openSet.Insert(start);

            // A* Loop
            List <Point> path = null;

            while (openSet.Count > 0)
            {
                Point p = openSet.Pop();
                if (p.X == end.X && p.Y == end.Y)
                {
                    path = new List <Point>();
                    BuildPath(path, end);
                    break;
                }
                bool canMove = false;
                foreach (Point n in NeighborhoodAlign(p).Where(InGrid))
                {
                    int tgs = gScore[p.X, p.Y] + 10;
                    canMove = CanMoveFrom(p, n, q.FOWIndex);
                    if (canMove && tgs < gScore[n.X, n.Y])
                    {
                        prev[n.X, n.Y]   = p;
                        gScore[n.X, n.Y] = tgs;
                        fScore[n.X, n.Y] = gScore[n.X, n.Y] + Estimate(n.X, n.Y);
                        if (!openSet.Contains(n))
                        {
                            openSet.Insert(n);
                        }
                    }
                }
                foreach (Point n in NeighborhoodDiag(p).Where(InGrid))
                {
                    int tgs = gScore[p.X, p.Y] + 14;
                    // To Move Diagonally, Destination Must Be Reachable By Horizontal & Vertical Moves As Well
                    canMove = CanMoveFrom(p, n, q.FOWIndex);
                    foreach (Point d in DiagDecomp(p, n))
                    {
                        canMove &= CanMoveFrom(p, d, q.FOWIndex);
                    }
                    if (canMove && tgs < gScore[n.X, n.Y])
                    {
                        prev[n.X, n.Y]   = p;
                        gScore[n.X, n.Y] = tgs;
                        fScore[n.X, n.Y] = gScore[n.X, n.Y] + Estimate(n.X, n.Y);
                        if (!openSet.Contains(n))
                        {
                            openSet.Insert(n);
                        }
                    }
                }
            }

            // Check If We Need To Find The Nearest Point
            if (path == null)
            {
                int s;
                bool[,] ch = new bool[World.numCells.X, World.numCells.Y];
                Array.Clear(ch, 0, ch.Length);
                Point cg = FindClosestGoal(end, fScore, ch, out s, 0);
                if (s == int.MaxValue)
                {
                    // Impossible
                }
                else
                {
                    path = new List <Point>();
                    BuildPath(path, cg);
                }
            }

            // A* Conclusion
            if (path != null)
            {
                foreach (Point wp in path)
                {
                    q.waypoints.Add(new Vector2(((float)wp.X + 0.5f) * World.cellSize, ((float)wp.Y + 0.5f) * World.cellSize));
                }
            }
            q.IsComplete = true;
        }