Ejemplo n.º 1
0
        public CombinedMovementAndFiringDistanceCalculation(
            DistanceCalculation movementDistanceToFiringLine,
            FiringDistance firingDistance, Direction finalMovementDirectionTowardsTarget)
        {
            MovementDistanceToFiringLine = movementDistanceToFiringLine;
            FiringDistance = firingDistance;
            FinalMovementDirectionTowardsTarget = finalMovementDirectionTowardsTarget;

            // Calculate ticks until the target is shot:
            int ticksTillTargetShot = MovementDistanceToFiringLine.Distance + FiringDistance.TicksTillTargetShot;

            if (ticksTillTargetShot > Constants.UNREACHABLE_DISTANCE)
            {
                ticksTillTargetShot = Constants.UNREACHABLE_DISTANCE;
            }
            TicksTillTargetShot = ticksTillTargetShot;

            // Calculate ticks until the last shot is fired:
            int ticksTillLastShotFired = MovementDistanceToFiringLine.Distance + FiringDistance.TicksTillLastShotFired;

            if (ticksTillLastShotFired > Constants.UNREACHABLE_DISTANCE)
            {
                ticksTillLastShotFired = Constants.UNREACHABLE_DISTANCE;
            }
            TicksTillLastShotFired = ticksTillLastShotFired;
        }
        public static Node[] GetIncomingNodesOnShortestPath(
            DirectionalMatrix <DistanceCalculation> distances,
            Direction dir, int fromX, int fromY, int toX, int toY,
            FiringLineMatrix firingLineMatrix       = null,
            bool keepMovingCloserOnFiringLastBullet = false)
        {
            DistanceCalculation distanceCalc = distances[dir, fromX, fromY];

            if (distanceCalc.Distance == Constants.UNREACHABLE_DISTANCE)
            {
                return(new Node[0]);
            }

            int length = distanceCalc.Distance;

            Node[] nodes = new Node[length];
            int    nodeIndex;
            Node   node;

            nodeIndex = 0;
            node      = distanceCalc.AdjacentNode;
            while (nodeIndex != length)
            {
                if (node.ActionType == ActionType.FiringLine)
                {
                    Line <FiringDistance> firingLine     = firingLineMatrix[toX, toY, node.Dir.GetOpposite(), node.EdgeOffset];
                    FiringDistance        firingDistance = firingLine[node.FiringLineIndex];
                    FiringDistanceCalculator.AddFiringLineNodesToRoute(firingDistance,
                                                                       firingLine.DirectionOfLine.GetOpposite(), nodes, ref nodeIndex, keepMovingCloserOnFiringLastBullet);
                    break;
                }

                // Add the node:
                nodes[nodeIndex] = node;
                nodeIndex++;
                if (node.ActionType == ActionType.Firing)
                {
                    // Add a moving node - the only reason to fire is to move...
                    node             = new Node(ActionType.Moving, node.Dir, node.X + node.Dir.GetXOffset(), node.Y + node.Dir.GetYOffset());
                    nodes[nodeIndex] = node;
                    nodeIndex++;
                }
                distanceCalc = distances[node.Dir, node.X, node.Y];
                node         = distanceCalc.AdjacentNode;
            }
            if (nodeIndex < length)
            {
                Array.Resize(ref nodes, nodeIndex);
            }
            return(nodes);
        }
Ejemplo n.º 3
0
        public CombinedMovementAndFiringDistanceCalculation GetShortestAttackDistanceGivenTheSourcePointsMovementMatrix(
            DirectionalMatrix <DistanceCalculation> movementDistanceMatrix, Cell target)
        {
            int bestCombinedTicksUntilTargetShot = Constants.UNREACHABLE_DISTANCE;
            CombinedMovementAndFiringDistanceCalculation bestCombinedDistance = null;

            foreach (Direction attackDir in MovementDirections)
            {
                foreach (EdgeOffset edgeOffset in EdgeOffsets)
                {
                    Direction             outwardDir = attackDir.GetOpposite();
                    Line <FiringDistance> firingLine = FiringLineMatrix[target.Position, outwardDir, edgeOffset];

                    for (int i = 0; i < firingLine.Length; i++)
                    {
                        FiringDistance firingDist = firingLine[i];

                        // Ignore firing line points that start off with a normal movement,
                        // as that path can be found by moving to the closer point in a non-firing line way:
                        if (firingDist.CanMoveOrFire)
                        {
                            continue;
                        }

                        // Ignore invalid starting points on the firing line:
                        if (!(GameStateCalculationCache.GameState.Walls.BoardBoundary.ContainsPoint(firingDist.StartingTankPosition) &&
                              TurnCalculationCache.TankLocationMatrix[firingDist.StartingTankPosition].IsValid))
                        {
                            break;
                        }

                        DistanceCalculation movementDist = movementDistanceMatrix[attackDir, firingDist.StartingTankPosition];

                        int combinedTicks = movementDist.Distance + firingDist.TicksTillTargetShot;
                        if (combinedTicks < bestCombinedTicksUntilTargetShot)
                        {
                            bestCombinedTicksUntilTargetShot = combinedTicks;
                            bestCombinedDistance
                                = new CombinedMovementAndFiringDistanceCalculation(movementDist, firingDist, attackDir);
                        }
                    }
                }
            }

            return(bestCombinedDistance);
        }
Ejemplo n.º 4
0
        private void AddNextFiringLineNodesToQueueForMovementDirAndEdgeOffset(
            TwoValuedCircularBuffer <Node> bfsQueue, Direction movementDir, EdgeOffset edgeOffset,
            FiringLineSummary firingLineSummary, int distanceToAdd)
        {
            Line <FiringDistance> firingLine = firingLineSummary.FiringLine;
            int nextFiringLineIndex;

            for (nextFiringLineIndex = firingLineSummary.IndexOfNextFiringLinePoint;
                 nextFiringLineIndex < firingLine.Length;
                 nextFiringLineIndex++)
            {
                if (nextFiringLineIndex == -1)
                {
                    return;
                }
                FiringDistance firingDist        = firingLine[nextFiringLineIndex];
                int            nextEdgeWeighting = firingDist.TicksTillTargetShot - 1;
                // This distance is the edge weight in the graph.
                // The -1 is because we need to compensate for the weight 1 edge added from
                // the tank's position + direction on the firing line, to the firing line node.

                if (nextEdgeWeighting > distanceToAdd)
                {
                    firingLineSummary.NextEdgeWeighting          = nextEdgeWeighting;
                    firingLineSummary.IndexOfNextFiringLinePoint = nextFiringLineIndex;
                    return;
                }

                if (!TurnCalculationCache.CellMatrix[firingDist.StartingTankPosition].IsValid)
                {
                    firingLineSummary.NextEdgeWeighting          = Constants.UNREACHABLE_DISTANCE;
                    firingLineSummary.IndexOfNextFiringLinePoint = -1;
                    return;
                }

                Node firingLineNode = new Node(ActionType.FiringLine, movementDir, firingDist.StartingTankPosition,
                                               (byte)nextFiringLineIndex, edgeOffset);
                bfsQueue.Add(firingLineNode, nextEdgeWeighting);
            }
            if (nextFiringLineIndex == firingLine.Length)
            {
                firingLineSummary.NextEdgeWeighting          = Constants.UNREACHABLE_DISTANCE;
                firingLineSummary.IndexOfNextFiringLinePoint = -1;
            }
        }