示例#1
0
 public static EncounterPath BuildArcingPath(EncounterPosition start, EncounterPosition target)
 {
     return(new EncounterPath(new List <EncounterPosition>()
     {
         start, target
     }));
 }
示例#2
0
        // PERF: If this ends up being slow, we can mark with a dirty bit

        /**
         * Returns a path from start to end, exclusive - that is, the start and end nodes are *not* listed in the path. Does a full
         * naive search every time.
         */
        public static List <EncounterPosition> AStarWithNewGrid(
            EncounterPosition start,
            EncounterPosition end,
            EncounterState state,
            int maxAreaToExplore = 950
            )
        {
            SimplePriorityQueue <EncounterPosition> frontier = new SimplePriorityQueue <EncounterPosition>();

            frontier.Enqueue(start, 0f);

            var cameFrom = new Dictionary <EncounterPosition, EncounterPosition>();

            var costSoFar = new Dictionary <EncounterPosition, float>();

            costSoFar[start] = 0f;

            while (frontier.Count > 0 && cameFrom.Count < maxAreaToExplore)
            {
                var currentPosition   = frontier.Dequeue();
                var adjacentPositions = state.AdjacentPositions(currentPosition);

                if (currentPosition == end || (state.IsPositionBlocked(end) && adjacentPositions.Contains(end)))
                {
                    var path = new List <EncounterPosition>()
                    {
                        currentPosition
                    };

                    EncounterPosition cameFromPos;
                    while (cameFrom.TryGetValue(path[path.Count - 1], out cameFromPos) && (cameFromPos != start))
                    {
                        path.Add(cameFromPos);
                    }
                    path.Reverse();

                    return(path);
                }

                var adjacentUnblocked = adjacentPositions.Where(adjacent => !state.IsPositionBlocked(adjacent)).ToList();
                adjacentUnblocked.ForEach(adjacent => {
                    var newNextPositionCost = costSoFar[currentPosition] + 1f;
                    if (!costSoFar.ContainsKey(adjacent) || newNextPositionCost < costSoFar[adjacent])
                    {
                        costSoFar[adjacent] = newNextPositionCost;
                        // Uses straight-line distance as heuristic
                        float priority = newNextPositionCost + adjacent.DistanceTo(end);
                        frontier.Enqueue(adjacent, priority);
                        cameFrom[adjacent] = currentPosition;
                    }
                });
            }
            return(null);
        }
示例#3
0
        public static EncounterPath BuildReverseLinePath(EncounterPosition start, EncounterPosition target, int overshoot)
        {
            var distance = (int)Math.Ceiling(start.DistanceTo(target));

            var outwardPath = StraightLine(start, target, numSteps: distance + overshoot, endsAtTarget: false);
            var reversePath = StraightLine(outwardPath[outwardPath.Count - 2], start, numSteps: distance + overshoot, endsAtTarget: false);

            reversePath.RemoveAt(reversePath.Count - 1);
            outwardPath.AddRange(reversePath);
            return(new EncounterPath(outwardPath));
        }
示例#4
0
        private static List <EncounterPosition> StraightLine(EncounterPosition start, EncounterPosition end, int numSteps, bool endsAtTarget)
        {
            List <EncounterPosition> acc = new List <EncounterPosition>();

            acc.Add(start);

            bool  isVertical = start.X == end.X;
            float dError     = isVertical ? float.MaxValue : Math.Abs(((float)end.Y - (float)start.Y) / ((float)end.X - (float)start.X));

            int yErr  = end.Y - start.Y > 0 ? 1 : -1;
            int xDiff = end.X - start.X > 0 ? 1 : -1;

            float error = 0.0f;
            int   cX    = start.X;
            int   cY    = start.Y;
            int   steps = 0;

            while (steps < numSteps)
            {
                EncounterPosition newPosition;
                if (isVertical)
                {
                    cY         += yErr;
                    newPosition = new EncounterPosition(cX, cY);
                }
                else if (error >= 0.5f)
                {
                    cY         += yErr;
                    error      -= 1f;
                    newPosition = new EncounterPosition(cX, cY);
                }
                else
                {
                    cX         += xDiff;
                    error      += dError;
                    newPosition = new EncounterPosition(cX, cY);
                }

                acc.Add(newPosition);
                if (endsAtTarget && newPosition == end)
                {
                    break;
                }

                steps += 1;
            }

            return(acc);
        }
示例#5
0
 public Unit(string unitId, FactionName unitFaction, EncounterPosition rallyPoint, UnitOrder standingOrder,
             FormationType unitFormation, FormationFacing unitFacing)
 {
     this.UnitId                    = unitId;
     this.UnitFaction               = unitFaction;
     this.LeftFlank                 = true;
     this.RightFlank                = true;
     this.RallyPoint                = rallyPoint;
     this.AverageTrackerX           = new AverageTracker();
     this.AverageTrackerY           = new AverageTracker();
     this.StandingOrder             = standingOrder;
     this.UnitFormation             = unitFormation;
     this.UnitFacing                = unitFacing;
     this.EntityIdInForPositionZero = null;
     this.OriginalUnitStrength      = 0;
     this._BattleReadyEntityIds     = new List <string>();
     this._RoutedEntityIds          = new List <string>();
     this._DeadEntityIds            = new List <string>();
 }
示例#6
0
 public void NotifyEntityMoved(EncounterPosition oldPosition, EncounterPosition newPosition)
 {
     this.AverageTrackerX.ReplaceInAverage(newPosition.X, oldPosition.X);
     this.AverageTrackerY.ReplaceInAverage(newPosition.Y, oldPosition.Y);
 }
示例#7
0
 public List <EncounterPosition> AStar(EncounterPosition start, EncounterPosition end, EncounterState state)
 {
     return(AStarWithNewGrid(start, end, state));
 }
示例#8
0
 public static EncounterPath BuildStraightLinePath(EncounterPosition start, EncounterPosition target, int maxSteps = 100, bool endsAtTarget = false)
 {
     return(new EncounterPath(StraightLine(start, target, maxSteps, endsAtTarget)));
 }