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)); } }
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; } } }
// 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)); }
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]); }
private double CalculateDistanceToBullet(BulletWave ew) { var traveledDistance = ew.GetTraveledDistance(Time); var curDistance = Helper.GetDistance(ew.StartX, ew.StartY, X, Y); return(curDistance - traveledDistance); }
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)); }
// 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); }
//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); }
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--; } } }
// 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); }
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; } }