private void Behave() { var contexts = ContextBehaviors.Select(b => b.Behave(Steps)).ToList(); (var finalRing, var angle, var boost) = ContextRingBlending.Blend(contexts, false); BlendedRing = finalRing; SteerAngle(angle); }
public (ContextRing, float, bool) Blend(IEnumerable<ContextRing> contexts, bool doBoost) { var finalSteps = Robot.Steps * BlurResolutionMultiplier; var combined = new ContextRing(finalSteps); if (BlurResolutionMultiplier > 1) contexts = contexts.Select(c => c.ResolutionMultiply(BlurResolutionMultiplier)).ToList(); if (contexts.Any()) { // blur foreach (var context in contexts) BlurRing(context); for (var i = 0; i < finalSteps; i++) combined.Weights[i] = contexts.Sum(c => c.Weights[i] * c.RingWeight); for (var i = 0; i < finalSteps; i++) combined.WeightsBoost[i] = contexts.Sum(c => c.WeightsBoost[i] * c.RingWeight); var maxIndex = 0; for (var i = 0; i < finalSteps; i++) { if (combined.Weights[i] > combined.Weights[maxIndex]) maxIndex = i; } var maxBoostIndex = 0; for (var i = 0; i < finalSteps; i++) { if (combined.WeightsBoost[i] > combined.WeightsBoost[maxBoostIndex]) maxBoostIndex = i; } bool willBoost = false; var bestIndex = maxIndex; if (combined.Weights[maxIndex] < combined.WeightsBoost[maxBoostIndex] - 0.5 && doBoost) { willBoost = true; bestIndex = maxBoostIndex; } return (combined, combined.Angle(bestIndex), willBoost); } else { return (null, 0, false); // going east a lot ? } }
private void BlurRing(ContextRing ring) { // blur the values in the ring for (var blurStep = 0; blurStep < BlurSteps; blurStep++) for (var i = 0; i < ring.Weights.Length; i++) { var previousIndex = i - 1; if (previousIndex < 0) previousIndex = ring.Weights.Length - 1; var prev = ring.Weights[previousIndex]; var next = ring.Weights[(i + 1) % ring.Weights.Length]; var thisScore = ring.Weights[i]; ring.Weights[i] += (prev - thisScore) * BlurAmount + (next - thisScore) * BlurAmount; } }
protected virtual void OnFinalRing(ContextRing ring) { }
protected override Task AliveAsync() { foreach (var sensor in Sensors) { sensor.Sense(); } if (SensorCTF.CTFModeEnabled) { if (SensorCTF.IsCarryingFlag) { // I'm carrying the flag if (SensorCTF.OurTeam.FlagIsHome) { // our flag is home, head to base to score Navigation.TargetPoint = SensorCTF.OurTeam.BasePosition; } else { // our flag is not home, attack the guy who stole it // this seems required for 1v1, we might get trickier and // change behavior here if we have a teammate Navigation.TargetPoint = SensorCTF.OurTeam.FlagPosition; } } else { // I'm not carrying a flag if (!SensorCTF.TheirTeam.FlagIsHome) { // our teammate is carrying a flag if (!SensorCTF.OurTeam.FlagIsHome) { // our flag is not home, attack it Navigation.TargetPoint = SensorCTF.OurTeam.FlagPosition; } else { // our flag is home, defend teammate Navigation.TargetPoint = SensorCTF.TheirTeam.FlagPosition; } } else { // their flag is home Navigation.TargetPoint = SensorCTF.TheirTeam.BasePosition; } } } var contexts = ContextBehaviors.Select(b => b.Behave(Steps)).ToList(); var bangle = 0.0f; if (SensorFleets.MyFleet != null) { bangle = MathF.Atan2(this.SensorFleets.MyFleet.Momentum.Y, this.SensorFleets.MyFleet.Momentum.X); } (var finalRing, var angle, var boost) = ContextRingBlending.Blend(contexts, false); var combined = new ContextRing(this.Steps); // blur // lock (typeof(ContextRingBlendingWeighted)) // { // Console.SetCursorPosition(0, 0); // Console.WriteLine("RingDump"); // foreach (var context in contexts) // { // var name = context.Name; // while (name.Length < 20) // name += ' '; // Console.WriteLine($"{name}\t{string.Join(',', context.Weights.Select(w => (w * context.RingWeight).ToString("+0.0;-0.0")))}"); // } // } if (contexts.Any()) { for (var i = 0; i < this.Steps; i++) { combined.Weights[i] = contexts.Sum(c => c.Weights[i] * c.RingWeight); } var maxIndex = 0; var minIndex = 0; for (var i = 0; i < this.Steps; i++) { if (combined.Weights[i] > combined.Weights[maxIndex]) { maxIndex = i; } if (combined.Weights[i] < combined.Weights[minIndex]) { minIndex = i; } } if (CanBoost && (SensorFleets.MyFleet?.Ships.Count ?? 0) > BoostThreshold && (combined.Weights[maxIndex] < BoostDangerThreshold || (SensorFleets.MyFleet?.Ships.Count ?? 0) > 108)) { Boost(); } this.MidBad = combined.Weights[maxIndex] / 2.0f + combined.Weights[minIndex] / 2.0f; if (CanShoot) { var target = FleetTargeting.ChooseTarget() ?? AbandonedTargeting.ChooseTarget() ?? FishTargeting.ChooseTarget(); if (target != null) { var fff = target; Vector2 sp = fff.Position - this.Position; var angleg = (int)(MathF.Atan2(sp.Y, sp.X) / MathF.Atan2(0.0f, -1.0f) / 2.0f * Steps); if (true)//combined.Weights[((angleg)%Steps+Steps)%Steps]>combined.Weights[minIndex]) { ShootAt(sp + this.Position); } } else { if (SensorFleets.MyFleet != null) { ShootAt(SensorFleets.MyFleet.Momentum); } } } } SteerAngle(angle); return(Task.FromResult(0)); }