Beispiel #1
0
 public Line <FiringDistance> this[int x, int y, Direction outwardDirection, EdgeOffset edgeOffset = EdgeOffset.Centre]
 {
     get
     {
         return(this[new Point((short)x, (short)y), outwardDirection, edgeOffset]);
     }
 }
        // TODO: Cache these offsets
        public static Point GetOffsetToPointOnTankEdge(Direction edge, EdgeOffset edgeOffset)
        {
            Point     offsetToCentreOfEdge = Constants.TANK_EXTENT_OFFSET * edge.GetOffset();
            Direction perpendicular        = Direction.NONE;
            int       multiplier           = 1;

            switch (edgeOffset)
            {
            case EdgeOffset.Centre:
                return(offsetToCentreOfEdge);

            case EdgeOffset.OffCentreAntiClockwise:
                perpendicular = edge.AntiClockwise();
                break;

            case EdgeOffset.OffCentreClockwise:
                perpendicular = edge.Clockwise();
                break;

            case EdgeOffset.CornerAntiClockwise:
                perpendicular = edge.AntiClockwise();
                multiplier    = 2;
                break;

            case EdgeOffset.CornerClockwise:
                perpendicular = edge.Clockwise();
                multiplier    = 2;
                break;
            }
            return(offsetToCentreOfEdge + multiplier * perpendicular.GetOffset());
        }
Beispiel #3
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;
            }
        }
        public Node(ActionType actionType, Direction dir, int x, int y,
                    byte firingLineIndex = 0, EdgeOffset edgeOffset = EdgeOffset.Centre) : this()
        {
            MobilityId
                = (byte)x
                  | ((byte)y << YBitShift)
                  | ((byte)dir << DirBitShift)
                  | ((byte)actionType << ActionTypeBitShift)
                  | ((byte)edgeOffset << EdgeOffsetBitShift)
                  | (firingLineIndex << FiringLineIndexBitShift);

            /* Slows down algorithm too much...
             * Debug.Assert(ActionType == actionType, "ActionType wrong");
             * Debug.Assert(Dir == dir, "Dir wrong");
             * Debug.Assert(X == x, "X wrong");
             * Debug.Assert(Y == y, "Y wrong");
             * Debug.Assert(FiringLineIndex == firingLineIndex, "FiringLineIndex wrong");
             * Debug.Assert(EdgeOffset == edgeOffset, "EdgeOffset wrong");
             */
        }
 public static Point GetPointOnTankEdge(int centreX, int centreY, Direction edge, EdgeOffset edgeOffset)
 {
     return(GetPointOnTankEdge(new Point((short)centreX, (short)centreY), edge, edgeOffset));
 }
 public static Point GetPointOnTankEdge(Point centreOfTank, Direction edge, EdgeOffset edgeOffset)
 {
     return(centreOfTank + GetOffsetToPointOnTankEdge(edge, edgeOffset));
 }
 public Node(ActionType actionType, MobileState mobileState,
             byte firingLineIndex = 0, EdgeOffset edgeOffset = EdgeOffset.Centre)
     : this(actionType, mobileState.Dir, mobileState.Pos, firingLineIndex, edgeOffset)
 {
 }
 public Node(ActionType actionType, Direction dir, Point pos,
             byte firingLineIndex = 0, EdgeOffset edgeOffset = EdgeOffset.Centre)
     : this(actionType, dir, pos.X, pos.Y, firingLineIndex, edgeOffset)
 {
 }
Beispiel #9
0
        public Line <FiringDistance> this[Point targetPoint, Direction outwardDirection, EdgeOffset edgeOffset = EdgeOffset.Centre]
        {
            get
            {
                Debug.Assert((int)edgeOffset < FiringLineArraySize, "An unsupported edge offset has been requested of a firing line matrix");
                Line <FiringDistance>[] firingLinesByEdgeOffset
                    = directionalMatrixOfFiringLinesByEdgeOffset[outwardDirection, targetPoint];
                if (firingLinesByEdgeOffset == null)
                {
                    firingLinesByEdgeOffset = new Line <FiringDistance> [FiringLineArraySize];
                }

                Line <FiringDistance> firingLine = firingLinesByEdgeOffset[(int)edgeOffset];
                if (firingLine == null)
                {
                    Cell targetCell;
                    switch (ExtentType)
                    {
                    case ElementExtentType.TankBody:
                        targetCell
                            = TurnCalcationCache.TankLocationMatrix[targetPoint]
                              .CellsOnEdgeByDirectionAndEdgeOffset[(int)outwardDirection, (int)edgeOffset];
                        break;

                    default:
                        // case ElementExtentType.Point:
                        targetCell = TurnCalcationCache.CellMatrix[targetPoint];
                        break;
                    }
                    firingLine = FiringDistanceCalculator.GetFiringDistancesToPoint(
                        targetCell, outwardDirection.GetOpposite() /*movement direction*/,
                        TurnCalcationCache, GameStateCalculationCache);
                }
                return(firingLine);
            }
        }