Esempio n. 1
0
    public static bool CanWalkToSquare(Unit unit, PathSquare pathSquare, bool checkUnitCollision = false)
    {
        var sqr = pathSquare.square;

        if (sqr.obstacles.Count == 0)
        {
            return(sqr.isWalkable);
        }
        else
        {
            if (checkUnitCollision)
            {
                foreach (var obj in sqr.obstacles.Values)
                {
                    if (obj != unit)
                    {
                        //Debug.Log(obj.name);
                        return(false);
                    }
                }
            }
        }

        return(true);
    }
 public PathSquareNeighbourInfo(PathSquare neighbour, double dist, PathSquare[] check)
 {
     this.neighbour     = neighbour;
     this.distance      = dist;
     this.diagonalCheck = check;
     this.isDiagonal    = true;
 }
Esempio n. 3
0
    public static PathInfo GetStraightPath(Unit unit, PathSquare start, PathSquare end)
    {
        HashSet <PathSquare> closedSet = new HashSet <PathSquare>();

        ResetPathSquare();

        bool reachedGoal = false;

        var direction = (end.pos.ToVector() - start.pos.ToVector()).normalized;

        var current = start;

        while (current != null)
        {
            if (current == end)
            {
                //return PathInfo.GenerateWaypoints(start, current);
                reachedGoal = true;
            }

            closedSet.Add(current);

            var next = current.pos.ToVector() + direction;

            PathSquareNeighbourInfo nextNeighbour;
            if (current.neighbours.TryGetValue(next.ConvertToIPosition(), out nextNeighbour))
            {
                if (!closedSet.Contains(nextNeighbour.neighbour))
                {
                    if (nextNeighbour.neighbour == end || CanWalkToSquare(unit, nextNeighbour))
                    {
                        nextNeighbour.neighbour.parent = current;
                        current = nextNeighbour.neighbour;
                        continue;
                    }
                }
            }

            break;
        }

        if (reachedGoal)
        {
            return(PathInfo.GenerateWaypoints(start, current));
        }

        return(null);
    }
Esempio n. 4
0
    public static PathInfo GenerateWaypoints(PathSquare start, PathSquare end)
    {
        var newPath = new PathInfo(start.pos, end.pos);

        var current = end;

        var     lastSqr = end;
        Vector3 dir     = Vector3.zero;

        while (current != null)
        {
            /*if(lastSqr != end)
             * {
             *  var lastVec = lastSqr.pos.ToVector();
             *  var curVec = current.pos.ToVector();
             *
             *  var tDir = (curVec - lastVec).normalized;
             *
             *  Debug.Log(tDir);
             *
             *  if(tDir != dir)
             *  {
             *      newPath.waypoints.Add(current.pos);
             *      dir = tDir;
             *  }
             * }
             * else
             * {
             *  newPath.waypoints.Add(current.pos);
             * }*/

            newPath.points.Add(current.pos);

            lastSqr = current;
            current = current.parent;
        }

        newPath.points.Reverse();
        newPath.waypoints.Reverse();

        return(newPath);
    }
Esempio n. 5
0
    public static PathInfo GetPath(Unit unit, Vector3 start, Vector3 end, PathType type = PathType.Shortest)
    {
        PathSquare startSqr = GetPathSquare(start);
        PathSquare endSqr   = GetPathSquare(end);

        //Debug.Log(end.x);

        if (startSqr != null && endSqr != null)
        {
            switch (type)
            {
            case PathType.Shortest:
                return(GetShortestPath(unit, startSqr, endSqr));

            case PathType.Straight:
                return(GetStraightPath(unit, startSqr, endSqr));

            default:
                return(null);
            }
        }

        return(null);
    }
Esempio n. 6
0
 public bool Equals(PathSquare obj)
 {
     return(obj.square.position == this.square.position);
 }
Esempio n. 7
0
 public double Distance(PathSquare sqr)
 {
     return(sqr.square.position.Distance(this.square.position));
 }
Esempio n. 8
0
        /// <summary>
        /// Update my "map" of all permanent objects (rocks and destroyed tanks) and empty GridSquares I have seen so far.
        /// </summary>
        private void UpdateMyMap()
        {
            int x, y;

            // initialise mygrid if it hasn't yet been created
            if (MyMap == null)
            {
                MyMap = new PathSquare[MyWorldState.GridWidthInSquares, MyWorldState.GridHeightInSquares];
                for (x = 0; x < MyWorldState.GridWidthInSquares; x++)
                {
                    for (y = 0; y < MyWorldState.GridHeightInSquares; y++)
                    {
                        MyMap[x, y] = new PathSquare(x, y); // set each unseen grid square to null
                    }
                }
            }

            // remove previous tank location from MyMap
            foreach (var square in MyMap)
            {
                if (
                    square.GridSq.Contents == GridSquare.ContentType.TankUp ||
                    square.GridSq.Contents == GridSquare.ContentType.TankRight ||
                    square.GridSq.Contents == GridSquare.ContentType.TankLeft ||
                    square.GridSq.Contents == GridSquare.ContentType.TankDown
                    )
                {
                    if (square.GridSq.Player != MyWorldState.ID)
                    {
                        square.HasBeenSeen = false;
                    }
                    square.GridSq    = new GridSquare(square.X, square.Y, GridSquare.ContentType.Empty);
                    square.IsBlocked = false;
                }
            }

            // update the map in mygrid
            foreach (GridSquare gs in MyWorldState.MyVisibleSquares)
            {
                if (MyMap[gs.X, gs.Y].HasBeenSeen == false) // not yet seen GridSquare gs
                {
                    MyMap[gs.X, gs.Y].HasBeenSeen = true;

                    // record fixed objects - rocks, destroyed tanks and empty squares
                    if (gs.Contents == GridSquare.ContentType.Rock)
                    {
                        MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.Rock);
                        MyMap[gs.X, gs.Y].IsBlocked = true;
                    }
                    else if (gs.Contents == GridSquare.ContentType.DestroyedTank)
                    {
                        MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.DestroyedTank);
                        MyMap[gs.X, gs.Y].IsBlocked = true;
                    }
                    else if (gs.Contents == GridSquare.ContentType.Empty)
                    {
                        MyMap[gs.X, gs.Y].GridSq = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.Empty);
                    }
                    // record moving objects - tanks
                    else if (gs.Contents == GridSquare.ContentType.TankDown)
                    {
                        MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankDown, gs.Player);
                        MyMap[gs.X, gs.Y].IsBlocked = true;
                    }
                    else if (gs.Contents == GridSquare.ContentType.TankLeft)
                    {
                        MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankLeft, gs.Player);
                        MyMap[gs.X, gs.Y].IsBlocked = true;
                    }
                    else if (gs.Contents == GridSquare.ContentType.TankRight)
                    {
                        MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankRight, gs.Player);
                        MyMap[gs.X, gs.Y].IsBlocked = true;
                    }
                    else if (gs.Contents == GridSquare.ContentType.TankUp)
                    {
                        MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankUp, gs.Player);
                        MyMap[gs.X, gs.Y].IsBlocked = true;
                    }
                }
                else if (gs.Contents == GridSquare.ContentType.DestroyedTank && MyMap[gs.X, gs.Y].GridSq.Contents != GridSquare.ContentType.DestroyedTank)
                {
                    MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.DestroyedTank); // record new destroyed tanks even if seen before.
                    MyMap[gs.X, gs.Y].IsBlocked = true;
                }
                else if (gs.Contents == GridSquare.ContentType.TankDown)
                {
                    MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankDown, gs.Player);
                    MyMap[gs.X, gs.Y].IsBlocked = true;
                }
                else if (gs.Contents == GridSquare.ContentType.TankLeft)
                {
                    MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankLeft, gs.Player);
                    MyMap[gs.X, gs.Y].IsBlocked = true;
                }
                else if (gs.Contents == GridSquare.ContentType.TankRight)
                {
                    MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankRight, gs.Player);
                    MyMap[gs.X, gs.Y].IsBlocked = true;
                }
                else if (gs.Contents == GridSquare.ContentType.TankUp)
                {
                    MyMap[gs.X, gs.Y].GridSq    = new GridSquare(gs.X, gs.Y, GridSquare.ContentType.TankUp, gs.Player);
                    MyMap[gs.X, gs.Y].IsBlocked = true;
                }
            }
        }
Esempio n. 9
0
    public static PathInfo GetShortestPath(Unit unit, PathSquare start, PathSquare end)
    {
        HashSet <PathSquare> closedSet = new HashSet <PathSquare>();
        HashSet <PathSquare> openSet   = new HashSet <PathSquare>();

        PathSquare closestSquare   = null;
        double     closestDistance = 9999;

        openSet.Add(start);

        ResetPathSquare();

        start.gScore = 0;
        start.fScore = start.Distance(end);

        double bestRouteDist = start.Distance(end);

        while (openSet.Count > 0)
        {
            var current = openSet.OrderBy(n => n.fScore).FirstOrDefault();

            if (current == end)
            {
                return(PathInfo.GenerateWaypoints(start, current));
            }

            openSet.Remove(current);
            closedSet.Add(current);

            foreach (var pair in current.neighbours)
            {
                var neighbourInfo = pair.Value;
                var neighbour     = neighbourInfo.neighbour;
                var distance      = neighbourInfo.distance;


                if (closedSet.Contains(neighbour))
                {
                    continue;
                }

                if (!CanWalkToSquare(unit, neighbourInfo))
                {
                    continue;
                }

                var alternativeDistance = current.gScore + distance;

                /*if(alternativeDistance > bestRouteDist * 2)
                 * {
                 *  continue; //stop searching for route that's longer than 2x the optimal path
                 * }*/

                if (!openSet.Contains(neighbour))
                {
                    openSet.Add(neighbour);
                }
                else if (alternativeDistance >= neighbour.gScore)
                {
                    continue;
                }

                var estimatedDistance = neighbour.Distance(end);

                neighbour.parent = current;
                neighbour.gScore = alternativeDistance;
                neighbour.fScore = alternativeDistance + estimatedDistance;

                if (closestDistance > estimatedDistance)
                {
                    closestSquare   = neighbour;
                    closestDistance = estimatedDistance;
                }
            }
        }

        if (closestSquare == null)
        {
            return(null);
        }

        if (closestSquare.Distance(end) < start.Distance(end))
        {
            var path = PathInfo.GenerateWaypoints(start, closestSquare);
            path.reachable = false;

            return(path);
        }
        else
        {
            return(null);
        }
    }
Esempio n. 10
0
    public static void InitPathSquares(Level level)
    {
        pathSquares = new Dictionary <IPosition, PathSquare>();

        List <IPosition> neighbourPositions = new List <IPosition>()
        {
            new IPosition(-1, 0, 0), //4, left
            new IPosition(1, 0, 0),  //6, right
            new IPosition(0, 0, -1), //8, up
            new IPosition(0, 0, 1),  //2, down
        };

        Dictionary <IPosition, IPosition[]> neighbourDiagonalPositions = new Dictionary <IPosition, IPosition[]>()
        {
            { new IPosition(-1, 0, 1),
              new IPosition[2] {
                  new IPosition(-1, 0, 0), //4, left
                  new IPosition(0, 0, 1),  //2, down
              } },                         //1
            { new IPosition(-1, 0, -1), new IPosition[2] {
                  new IPosition(-1, 0, 0), //4, left
                  new IPosition(0, 0, -1), //8, up
              } },                         //7
            { new IPosition(1, 0, -1), new IPosition[2] {
                  new IPosition(0, 0, -1), //8, up
                  new IPosition(1, 0, 0),  //6, right
              } },                         //9
            { new IPosition(1, 0, 1), new IPosition[2] {
                  new IPosition(1, 0, 0),  //6, right
                  new IPosition(0, 0, 1),  //2, down
              } },                         //3
        };



        foreach (var sqr in level.map.Values)
        {
            var newPathSqr = new PathSquare(sqr);

            pathSquares.Add(sqr.position, newPathSqr);

            sqr.CheckWalkable();
        }

        foreach (var pathSqr in pathSquares.Values)
        {
            var sqrPosition = pathSqr.pos;

            foreach (var dir in neighbourPositions)
            {
                var pos = sqrPosition + dir;

                PathSquare square;
                if (pathSquares.TryGetValue(pos, out square))
                {
                    pathSqr.neighbours.Add(square.pos, new PathSquareNeighbourInfo(square, square.Distance(pathSqr)));
                }
            }

            foreach (var diagonal in neighbourDiagonalPositions)
            {
                var pos = sqrPosition + diagonal.Key;

                PathSquare square;
                if (pathSquares.TryGetValue(pos, out square))
                {
                    var diagPos1 = sqrPosition + diagonal.Value[0];
                    var diagPos2 = sqrPosition + diagonal.Value[1];

                    PathSquare sqr1;
                    PathSquare sqr2;

                    if (pathSquares.TryGetValue(diagPos1, out sqr1) &&
                        pathSquares.TryGetValue(diagPos2, out sqr2))
                    {
                        pathSqr.neighbours.Add(square.pos,
                                               new PathSquareNeighbourInfo(square, square.Distance(pathSqr),
                                                                           new PathSquare[] { sqr1, sqr2 }));
                    }
                }
            }
        }
    }
 public PathSquareNeighbourInfo(PathSquare neighbour, double dist)
 {
     this.neighbour  = neighbour;
     this.isDiagonal = false;
     this.distance   = dist;
 }