예제 #1
0
        public override void OnHitByBullet(HitByBulletEvent e)
        {
            // If the _enemyWaves collection is empty, we must have missed the
            // detection of this wave somehow.

            BulletWave hitWave = null;

            foreach (var ew in enemyBullets)
            {
                if (Math.Abs(ew.GetTraveledDistance(Time) - Helper.GetDistance(X, Y, ew.StartX, ew.StartY)) <= _radius &&
                    Math.Abs(Helper.GetBulletVelocity(e.Bullet.Power) - ew.Velocity) < 0.001)
                {
                    hitWave = ew;
                    break;
                }
            }

            if (hitWave != null)
            {
                LogHit(hitWave, e.Bullet.X, e.Bullet.Y);
                enemyBullets.Remove(hitWave);
            }

            if (medKitLocked)
            {
                SetBackAsFront(HeadingRadians + Math.PI, rnd.Next(50, 100));
            }
        }
예제 #2
0
        public override void OnBulletHitBullet(BulletHitBulletEvent e)
        {
            BulletWave hitWave = null;

            foreach (var ew in enemyBullets)
            {
                if (Math.Abs(ew.GetTraveledDistance(Time) -
                             Helper.GetDistance(e.HitBullet.X, e.HitBullet.Y, ew.StartX, ew.StartY)) < 0.001 &&
                    Math.Abs(Helper.GetBulletVelocity(e.HitBullet.Power) - ew.Velocity) < 0.001)
                {
                    hitWave = ew;
                    break;
                }
            }

            if (hitWave != null)
            {
                LogHit(hitWave, e.HitBullet.X, e.HitBullet.Y);
                enemyBullets.Remove(hitWave);
            }

            foreach (var bullet in myBullets)
            {
                if (Math.Abs(bullet.GetTraveledDistance(Time) - Helper.GetDistance(e.HitBullet.X, e.HitBullet.Y, bullet.StartX, bullet.StartY)) < 0.001 &&
                    Math.Abs(e.HitBullet.Power - bullet.Power) < 0.001 && Math.Abs(e.Bullet.HeadingRadians - bullet.Angle) < 0.001)
                {
                    bullet.CheckHit(e.HitBullet.X, e.HitBullet.Y, Time); //maybe add more weight
                    break;
                }
            }
        }
예제 #3
0
        // Given the EnemyWave that the bullet was on, and the point where we
        // were hit, calculate the index into our stat array for that factor.
        private static int GetFactorIndex(BulletWave ew, double targetX, double targetY)
        {
            double offsetAngle = Helper.GetAbsBearingInRadian(ew.StartX, ew.StartY, targetX, targetY) - ew.TargetAngle;
            double factor      = Utils.NormalRelativeAngle(offsetAngle) / ew.MaxEscapeAngleRadian * ew.TargetDirection;

            return((int)Helper.Limit(0, 0.5 * (1 + factor) * (StatsCount - 1), StatsCount - 1));
        }
예제 #4
0
        private double CheckDanger(BulletWave surfWave, int direction, out PointF predictPosition)
        {
            predictPosition = PredictPosition(surfWave, direction);
            int index = GetFactorIndex(surfWave, predictPosition.X, predictPosition.Y);

            return(_surfStats[index]);
        }
예제 #5
0
        private double CalculateDistanceToBullet(BulletWave ew)
        {
            var traveledDistance = ew.GetTraveledDistance(Time);
            var curDistance      = Helper.GetDistance(ew.StartX, ew.StartY, X, Y);

            return(curDistance - traveledDistance);
        }
예제 #6
0
        private void DoSurfing()
        {
            BulletWave surfWave = GetClosestBullet();

            if (surfWave == null)
            {
                if (!WalkAwayFromEnemy())
                {
                    SetTurnAwayFromWall();
                    SetAhead(rnd.Next(50, 150));
                }
                return;
            }

            PointF predictPoint1, predictPoint2;
            double dangerLeft  = CheckDanger(surfWave, -1, out predictPoint1);
            double dangerRight = CheckDanger(surfWave, 1, out predictPoint2);

            double goAngle = Helper.GetAbsBearingInRadian(surfWave.StartX, surfWave.StartY, X, Y);

            if (dangerLeft < dangerRight)
            {
                goAngle       = WallSmoothing(X, Y, goAngle - (Math.PI * 0.5), -1);
                _predictPoint = predictPoint2;
            }
            else
            {
                goAngle       = WallSmoothing(X, Y, goAngle + (Math.PI * 0.5), 1);
                _predictPoint = predictPoint1;
            }

            SetBackAsFront(goAngle, rnd.Next(50, 150));
        }
예제 #7
0
        // CREDIT: mini sized predictor from Apollon, by rozu
        // http://robowiki.net?Apollon
        private PointF PredictPosition(BulletWave surfWave, int direction)
        {
            PointF predictedPosition = new PointF((float)X, (float)Y);
            double predictedVelocity = Velocity;
            double predictedHeading = HeadingRadians;
            double maxTurning, moveAngle, moveDir;

            int  counter     = 0; // number of ticks in the future
            bool intercepted = false;

            do
            {    // the rest of these code comments are rozu's
                var angleInRadian = Helper.GetAbsBearingInRadian(surfWave.StartX, surfWave.StartY, predictedPosition.X, predictedPosition.Y) + (direction * (Math.PI / 2));
                moveAngle = WallSmoothing(predictedPosition.X, predictedPosition.Y, angleInRadian, direction) - predictedHeading;
                moveDir   = 1;

                if (Math.Cos(moveAngle) < 0)
                {
                    moveAngle += Math.PI;
                    moveDir    = -1;
                }

                moveAngle = Utils.NormalRelativeAngle(moveAngle);

                // maxTurning is built in like this, you can't turn more then this in one tick
                maxTurning       = Math.PI / 720d * (40d - 3d * Math.Abs(predictedVelocity));
                predictedHeading = Utils.NormalRelativeAngle(predictedHeading + Helper.Limit(-maxTurning, moveAngle, maxTurning));

                // this one is nice ;). if predictedVelocity and moveDir have
                // different signs you want to breack down
                // otherwise you want to accelerate (look at the factor "2")
                predictedVelocity += (predictedVelocity * moveDir < 0 ? 2 * moveDir : moveDir);
                predictedVelocity  = Helper.Limit(-8, predictedVelocity, 8);

                // calculate the new predicted position
                predictedPosition = Helper.GetProjection(predictedPosition.X, predictedPosition.Y, predictedHeading, predictedVelocity);

                counter++;

                //todo: check if we can add _radius
                if (Helper.GetDistance(predictedPosition.X, predictedPosition.Y, surfWave.StartX, surfWave.StartY) + _radius <
                    surfWave.GetTraveledDistance(Time) + (counter + 1) * surfWave.Velocity)
                {
                    intercepted = true;
                }
            } while (!intercepted && counter < 500);

            return(predictedPosition);
        }
예제 #8
0
        //todo: get most dangerous wave
        private BulletWave GetClosestBullet()
        {
            double     closestDistance = double.MaxValue;
            BulletWave surfWave        = null;

            foreach (var ew in enemyBullets)
            {
                var distance = CalculateDistanceToBullet(ew);
                if (distance > ew.Velocity && distance < closestDistance)
                {
                    surfWave        = ew;
                    closestDistance = distance;
                }
            }

            return(surfWave);
        }
예제 #9
0
        private void UpdateEnemyWave(ScannedRobotEvent e)
        {
            var lateralVelocity = Velocity * Math.Sin(e.BearingRadians);
            var absBearing      = e.BearingRadians + HeadingRadians;

            _surfDirections.Insert(0, lateralVelocity >= 0 ? 1 : -1);
            _surfAbsBearings.Insert(0, absBearing + Math.PI);

            double energyDrop = _lastEnemyEnergy - e.Energy;

            if (energyDrop < Rules.MAX_BULLET_POWER + 0.0001 && energyDrop > Rules.MIN_BULLET_POWER - 0.0001 && _surfDirections.Count > 2)
            {
                BulletWave ew = new BulletWave()
                {
                    StartX          = _lastEnemyLocation.X,
                    StartY          = _lastEnemyLocation.Y,
                    FireTime        = Time - 1,
                    Power           = energyDrop,
                    TargetAngle     = _surfAbsBearings[2],
                    TargetDirection = _surfDirections[2],
                };
                enemyBullets.Add(ew);
            }
            _lastEnemyEnergy   = e.Energy;
            _lastEnemyLocation = Helper.GetProjection(X, Y, absBearing, e.Distance);

            //update enemy waves
            for (var i = 0; i < enemyBullets.Count; i++)
            {
                if (enemyBullets[i].CheckHit(X, Y, Time, 2 * _radius))
                {
                    enemyBullets.RemoveAt(i);
                    i--;
                }
            }
        }
예제 #10
0
        // Given the EnemyWave that the bullet was on, and the point where we
        // were hit, update our stat array to reflect the danger in that area.
        private void LogHit(BulletWave ew, double targetX, double targetY)
        {
            int index = GetFactorIndex(ew, targetX, targetY);

            Helper.UpdateStats(index, _surfStats);
        }
예제 #11
0
        private void Fire(ScannedRobotEvent e)
        {
            // Enemy absolute bearing
            double absBearing = HeadingRadians + e.BearingRadians;

            // enemy's location:
            double ex = X + Math.Sin(absBearing) * e.Distance;
            double ey = Y + Math.Cos(absBearing) * e.Distance;

            //update bullet waves
            for (int i = 0; i < myBullets.Count; i++)
            {
                var currentWave = myBullets[i];
                if (currentWave.CheckHit(ex, ey, Time))
                {
                    myBullets.Remove(currentWave);
                    i--;
                }
            }
            //update virtual bullet waves
            for (int i = 0; i < virtualBullets.Count; i++)
            {
                var currentWave = virtualBullets[i];
                if (currentWave.CheckHit(ex, ey, Time))
                {
                    virtualBullets.Remove(currentWave);
                    i--;
                }
            }

            double power          = GetBulletPower(e);
            var    enemyDirection = 1;

            // don't try to figure out the direction they're moving
            // they're not moving, just use the direction we had before
            if (Math.Abs(e.Velocity) > 0)
            {
                if (Math.Sin(e.HeadingRadians - absBearing) * e.Velocity < 0)
                {
                    enemyDirection = -1;
                }
                else
                {
                    enemyDirection = 1;
                }
            }
            var distanceIndex = (int)(e.Distance / 100);

            double[] currentStats = _fireStats[distanceIndex];
            var      newWave      = new BulletWave()
            {
                StartX          = X,
                StartY          = Y,
                FireTime        = Time,
                Power           = power,
                TargetAngle     = absBearing,
                TargetDirection = enemyDirection,
                Stats           = currentStats
            };

            double angleOffset = enemyDirection * newWave.MaxEscapeAngleRadian * GetGuessfactor(currentStats);

            //handle easy case
            if (e.Energy < 0.1)
            {
                angleOffset = 0;
                power       = Math.Min(3, 0.5 * Energy);
            }

            double gunAdjust = Utils.NormalRelativeAngle(absBearing - GunHeadingRadians + angleOffset);

            SetTurnGunRightRadians(gunAdjust);

            Bullet fireBullet = null;

            if (GunHeat <= 0 && gunAdjust < Math.Atan2(0.5 * _radius, e.Distance))
            {
                fireBullet = SetFireBullet(power);
                if (fireBullet != null)
                {
                    myBullets.Add(newWave);
                    newWave.Power = power;
                    newWave.Angle = fireBullet.HeadingRadians;
                }
            }
            //virtual bullet
            if (fireBullet == null)
            {
                virtualBullets.Add(newWave);
                newWave.Power = power;
                newWave.Angle = absBearing;
            }
        }