예제 #1
0
        public static List <PointF> LinearMovement(PointF currentLocation, PointF targetLocation)
        {
            var result = new List <PointF>();

            var distance = SpaceMapTools.GetDistance(currentLocation, targetLocation);

            for (var i = 0; i < distance; i++)
            {
                var x = (float)(currentLocation.X * (1 - (i / distance)) + targetLocation.X * (i / distance));
                var y = (float)(currentLocation.Y * (1 - (i / distance)) + targetLocation.Y * (i / distance));

                result.Add(new PointF(x, y));
            }

            return(result);
        }
예제 #2
0
        private Hashtable EnqueueMovementHistory(ICelestialObject mapCelestialObject, Hashtable allObjectsHistory)
        {
            var previousIteration = new SpaceMapObjectLocation
            {
                Distance    = SpaceMapTools.GetDistance(mapCelestialObject.GetLocation(), mapCelestialObject.GetLocation()),
                Direction   = mapCelestialObject.Direction,
                Status      = MovementType.Linear,
                Coordinates = mapCelestialObject.GetLocation()
            };

            if (allObjectsHistory.ContainsKey(mapCelestialObject.Id) == false)
            {
                // New celestial object in history collection
                var initialIteration = new SpaceMapObjectLocation
                {
                    Distance    = SpaceMapTools.GetDistance(mapCelestialObject.GetLocation(), mapCelestialObject.GetLocation()),
                    Direction   = mapCelestialObject.Direction,
                    Status      = MovementType.Linear,
                    Coordinates = Coordinates.MoveObject(mapCelestialObject.GetLocation(), 2000,
                                                         (mapCelestialObject.Direction - 180).To360Degrees())
                };

                var initialHistory = new FixedSizedQueue <SpaceMapObjectLocation>(_historyBufferSize);

                initialHistory.Enqueue(initialIteration);

                initialHistory.Enqueue(previousIteration);

                allObjectsHistory.Add(mapCelestialObject.Id, initialHistory);

                return(allObjectsHistory);
            }

            // Add new history point to exist celestial object movement history

            if (!(allObjectsHistory[mapCelestialObject.Id] is FixedSizedQueue <SpaceMapObjectLocation> currentObjectMovementHistory))
            {
                return(allObjectsHistory);
            }

            currentObjectMovementHistory.Enqueue(previousIteration);

            allObjectsHistory[mapCelestialObject.Id] = currentObjectMovementHistory;

            return(allObjectsHistory);
        }
예제 #3
0
        public CommandExecuteResult Execute(GameSession gameSession, Command command)
        {
            gameSession.AddHistoryMessage($"started.", GetType().Name, true);

            var explosion = gameSession.GetCelestialObject(command.CelestialObjectId).ToExplosion();

            var destroyedSpaceships = new List <ICelestialObject>();

            foreach (var celestialObject in gameSession.SpaceMap.CelestialObjects)
            {
                if (celestialObject.IsSpaceship() == false)
                {
                    continue;
                }

                var spaceShip = celestialObject.ToSpaceship();

                var distance = SpaceMapTools.GetDistance(celestialObject.GetLocation(), explosion.GetLocation());

                if (distance < explosion.Radius * 2)
                {
                    spaceShip.Damage(explosion.Damage);

                    gameSession.AddHistoryMessage($"Spaceship {spaceShip.Name} get damage '{explosion.Damage}' from '{explosion.Name}'", GetType().Name);

                    if (spaceShip.IsDestroyed)
                    {
                        destroyedSpaceships.Add(celestialObject);
                    }
                }

                foreach (var destroyedSpaceship in destroyedSpaceships)
                {
                    gameSession.RemoveCelestialObject(destroyedSpaceship);

                    gameSession.AddHistoryMessage($"Spaceship {destroyedSpaceship.Name} was destroyed.", GetType().Name);
                }
            }

            return(new CommandExecuteResult {
                Command = command, IsResume = false
            });
        }
예제 #4
0
        public static List <SpaceMapObjectLocation> Calculate(PointF location, PointF center, double direction, int maxIterations = 500)
        {
            const int radius = 30;
            var       result = new List <SpaceMapObjectLocation>();

            var orbitInformation = SpaceMapTools.GetRadiusPoint(location, center, radius, direction);

            var orbitPoint       = orbitInformation.StartLocation;
            var movementRotation = orbitInformation.Rotation;

            var distance = SpaceMapTools.GetDistance(center, location);

            if (distance > radius + 2)
            {
                var resultApproachMovement = Approach.Calculate(location, orbitPoint, direction, 10);

                foreach (var objectLocation in resultApproachMovement.Trajectory)
                {
                    result.Add(objectLocation);
                }
            }
            else
            {
                var previousIteration = new SpaceMapObjectLocation
                {
                    Distance    = SpaceMapTools.GetDistance(center, location),
                    Direction   = direction,
                    Status      = MovementType.Orbit,
                    Coordinates = new PointF(location.X, location.Y)
                };
                result.Add(previousIteration);
            }

            // Here we on orbit of celestial object
            for (var iteration = 0; iteration < 500; iteration++)
            {
                var currentIteration = result[result.Count - 1];
                distance = SpaceMapTools.GetDistance(center, currentIteration.Coordinates);


                float speedOrbit     = 1;
                var   directionDelta = 0;

                switch (movementRotation)
                {
                case OrbitRotation.Right:
                    speedOrbit     = 0.5f;
                    directionDelta = +90;
                    break;

                case OrbitRotation.Left:
                    speedOrbit     = -0.5f;
                    directionDelta = -90;
                    break;
                }

                var r = OrbitPrototype.Execute(center.ToVector2(), currentIteration.Coordinates.ToVector2(), speedOrbit, 1);

                var attackAzimuth = SpaceMapTools.GetAngleBetweenPoints(center.ToVector2(), r) + directionDelta;

                if (attackAzimuth < 0)
                {
                    attackAzimuth = 360 + attackAzimuth;
                }
                if (attackAzimuth > 360)
                {
                    attackAzimuth = attackAzimuth - 360;
                }


                result.Add(new SpaceMapObjectLocation
                {
                    Distance    = distance,
                    Direction   = attackAzimuth,
                    Iteration   = result.Count,
                    Coordinates = r.ToPointF()
                });
            }

            return(result);
        }
예제 #5
0
        public static List <SpaceMapObjectLocation> CalculateIteration(PointF currentLocation, PointF targetLocation, double direction, double speed, int maxIterations = 2000)
        {
            const int agility = 5;

            var result = new List <SpaceMapObjectLocation>();

            // In this case first iteration - start position for calculation.
            var previousIteration = new SpaceMapObjectLocation
            {
                Distance    = SpaceMapTools.GetDistance(targetLocation, currentLocation),
                Direction   = direction,
                Status      = MovementType.Default,
                Coordinates = new PointF(currentLocation.X, currentLocation.Y)
            };

            var currentStepInTurn = speed;

            for (var iteration = 0; iteration < maxIterations; iteration++)
            {
                var location = SpaceMapTools.Move(previousIteration.Coordinates.ToVector2(), 1, previousIteration.Direction);

                var iterationResult = new SpaceMapObjectLocation
                {
                    Direction   = previousIteration.Direction,
                    Iteration   = iteration,
                    Coordinates = location.PointTo,
                    Distance    = SpaceMapTools.GetDistance(targetLocation, location.PointTo)
                };

                // 0 - 360 degree
                var attackAzimuth = SpaceMapTools.GetAngleBetweenPoints(location.PointTo.ToVector2(), targetLocation.ToVector2());
                // Turn angle
                var attackAngle = (int)SpaceMapTools.GetRotateDirection(iterationResult.Direction, attackAzimuth);

                var currentAgility = 0;

                if (speed == currentStepInTurn)
                {
                    currentAgility = agility;
                }

                currentStepInTurn++;

                if (currentStepInTurn > speed)
                {
                    currentStepInTurn = 0;
                }

                switch (attackAngle)
                {
                case var _ when attackAngle > 0:
                    // > 0 left turn
                    iterationResult.Direction -= currentAgility;
                    iterationResult.Status     = MovementType.Turn;
                    break;

                case var _ when attackAngle < 0:
                    // < 0 right turn
                    iterationResult.Direction += currentAgility;
                    iterationResult.Status     = MovementType.Turn;
                    break;

                case var _ when attackAngle == 0:
                    // = 0 forward
                    iterationResult.Status = MovementType.Linear;
                    break;
                }

                if (iterationResult.Distance >= 2)
                {
                    result.Add(iterationResult);
                }
                else
                {
                    result.Add(iterationResult);
                    break;
                }

                result.Add(iterationResult);

                previousIteration = iterationResult;
            }

            //result.Add(new SpaceMapObjectLocation { ScanRange = 0, Direction = direction, Iteration = result.Count, Coordinates = targetLocation });

            return(result);
        }
예제 #6
0
        public static Result Calculate(PointF currentLocation, PointF targetLocation, double direction, double speed, int maxIterations = 2000)
        {
            const int agility = 5;

            var result = new Result();

            // In this case first iteration - start position for calculation.
            var previousIteration = new SpaceMapObjectLocation
            {
                Distance    = SpaceMapTools.GetDistance(targetLocation, currentLocation),
                Direction   = direction,
                Status      = MovementType.Default,
                Coordinates = new PointF(currentLocation.X, currentLocation.Y)
            };

            var currentStepInTurn = speed;

            for (var iteration = 0; iteration < maxIterations; iteration++)
            {
                var location = SpaceMapTools.Move(previousIteration.Coordinates.ToVector2(), 1, previousIteration.Direction);

                var iterationResult = new SpaceMapObjectLocation
                {
                    Direction   = previousIteration.Direction,
                    Iteration   = iteration,
                    Coordinates = location.PointTo,
                    Distance    = SpaceMapTools.GetDistance(targetLocation, location.PointTo)
                };

                // 0 - 360 degree
                var attackAzimuth = SpaceMapTools.GetAngleBetweenPoints(location.PointTo.ToVector2(), targetLocation.ToVector2());
                // Turn angle
                var attackAngle = SpaceMapTools.GetRotateDirection(iterationResult.Direction, attackAzimuth);

                var currentAgility = 0;

                if ((int)speed == (int)currentStepInTurn)
                {
                    currentAgility = agility;

                    if (Math.Abs(attackAngle) < agility)
                    {
                        attackAngle = 0;
                        iterationResult.Direction = attackAzimuth;
                    }
                }

                currentStepInTurn++;

                if (currentStepInTurn > speed)
                {
                    currentStepInTurn = 0;
                }

                switch (attackAngle)
                {
                case var _ when attackAngle > 1:
                    // > 0 left turn
                    iterationResult.Direction -= currentAgility;
                    iterationResult.Status     = MovementType.Turn;
                    break;

                case var _ when attackAngle < -1:
                    // < 0 right turn
                    iterationResult.Direction += currentAgility;
                    iterationResult.Status     = MovementType.Turn;
                    break;

                case var _ when attackAngle == 0:
                    // = 0 forward
                    iterationResult.Status = MovementType.Linear;
                    break;

                case var _ when attackAngle == 1:
                    // = 0 forward
                    iterationResult.Status = MovementType.Linear;
                    break;
                }

                if (iterationResult.Distance >= 2)
                {
                    result.Trajectory.Add(iterationResult);
                }
                else
                {
                    result.Trajectory.Add(iterationResult);
                    break;
                }

                iterationResult.Direction = iterationResult.Direction.To360Degrees();

                result.Trajectory.Add(iterationResult);

                previousIteration = iterationResult;

                if (iterationResult.Status == MovementType.Linear)
                {
                    var linearIteration = 0;

                    foreach (var points in LinearMovement(iterationResult.Coordinates, targetLocation))
                    {
                        linearIteration++;

                        result.Trajectory.Add(new SpaceMapObjectLocation
                        {
                            Coordinates = points,
                            Distance    = SpaceMapTools.GetDistance(targetLocation, points),
                            Direction   = iterationResult.Direction.To360Degrees(),
                            Status      = MovementType.Linear,
                            Iteration   = iterationResult.Iteration + linearIteration
                        });
                    }

                    break;
                }
            }


            return(result);
        }