/// <summary>
        /// Calculate the value of total force exherted at the location by the gravity points. 
        /// </summary>
        /// <param name="location">The current location.</param>
        /// <param name="gravityPoints">Points representing gravity/anti-gravity sources</param>
        /// <returns></returns>
        private Force GetNetForce(Point location, List<GravityPoint> gravityPoints)
        {
            var netForce = new Force() { X = 0.0, Y = 0.0 };

            foreach (var gravityPoint in gravityPoints)
            {
                var distance = Point.Distance(gravityPoint.Location, location);

                var force = gravityPoint.Power / Math.Pow(distance, gravityPoint.DistanceDecay);
                var angle = Utils.NormalAbsoluteAngle(Math.Atan2(gravityPoint.Location.X - location.X, gravityPoint.Location.Y - location.Y));

                netForce.X += Math.Sin(angle) * force;
                netForce.Y += Math.Cos(angle) * force;
            }

            return netForce;
        }
        /// <summary>
        /// Gets the gravity/anti-gravity force working on the robot.
        /// For more information, see Anti-Gravity Movement.
        /// </summary>
        /// <param name="currentLocation">The current location.</param>
        /// <param name="enemyLocations">Enemy locations.</param>
        /// <param name="enemyBullets">Predicted enemy bullets.</param>
        /// <param name="time">The time.</param>
        /// <param name="fieldWidth">Width of the field.</param>
        /// <param name="fieldHeight">Height of the field.</param>
        /// <returns></returns>
        private Force GetAntiGravityForce(Point currentLocation, List<Point> enemyLocations, List<WaveBullet> enemyBullets, long time, double fieldWidth, double fieldHeight)
        {
            var enemyGravityPoints = new List<GravityPoint>();
            var fieldGravityPoints = new List<GravityPoint>();

            var powerPerEnemy = -3000 / this.Others;

            // gravity points from enemies
            enemyGravityPoints.AddRange(enemyLocations.Select(point =>
                new GravityPoint()
                {
                    Location = point,
                    Power = powerPerEnemy,
                    DistanceDecay = 2
                }));

            // gravity points from walls (should minimise the risk of hitting them under normal circumstances)
            fieldGravityPoints.AddRange(new List<GravityPoint>()
            {
                new GravityPoint()
                {
                    Location = new Point() { X = 0, Y = currentLocation.Y },
                    Power = -5000,
                    DistanceDecay = 3
                },
                new GravityPoint() {
                    Location = new Point() { X = fieldWidth, Y = currentLocation.Y },
                    Power = -5000,
                    DistanceDecay = 3
                },
                new GravityPoint() {
                    Location = new Point() { X = currentLocation.X, Y = 0 },
                    Power = -5000,
                    DistanceDecay = 3
                },
                new GravityPoint() {
                    Location = new Point() { X =currentLocation.X, Y = fieldHeight },
                    Power = -5000,
                    DistanceDecay = 3
                },
            });

            // meant to add a perpendicular force from predicted enemy bullets that would push the robot aside, allowing to dodge them
            // never got around to get it to work though
            var enemyBulletGravityPoints = new List<GravityPoint>();
            if (this.Others <= 2)
            {
                var bulletsToTerminate = new List<WaveBullet>();

                foreach (var bullet in enemyBullets)
                {
                    double guessFactor = 0;
                    if (bullet.CheckHit(this.Name, currentLocation, this.Time + 10, out guessFactor))
                    {
                        enemyBulletGravityPoints.Add(new GravityPoint()
                        {
                            Power = 3000,
                            DistanceDecay = 0,
                            Location = bullet.StartPoint
                        });

                        bulletsToTerminate.Add(bullet);
                    }

                    if (this.Time - bullet.Time > 100)
                    {
                        bulletsToTerminate.Add(bullet);
                    }
                }

                foreach (var bullet in bulletsToTerminate)
                {
                    enemyBullets.Remove(bullet);
                }
            }

            var forceFromEnemies = GetNetForce(currentLocation, enemyGravityPoints);
            var forceFromField = GetNetForce(currentLocation, fieldGravityPoints);
            var forceFromEnemyBullets = GetNetForce(currentLocation, enemyBulletGravityPoints);

            // a dodge direction that would fluctuate with time
            var perpendicularDirection = ((this.Time / 20) % 2 == 0) ? 1 : -1;

            forceFromEnemyBullets = new Force()
            {
                X = perpendicularDirection * forceFromEnemyBullets.X,
                Y = -perpendicularDirection * forceFromEnemyBullets.Y
            };

            return new Force()
            {
                X = forceFromEnemies.X + forceFromField.X + forceFromEnemyBullets.X,
                Y = forceFromEnemies.Y + forceFromField.Y + forceFromEnemyBullets.Y
            };
        }