/// <summary> /// Creates the sparks from the explosion. /// </summary> /// <param name="explosion">The explosion that is the source of sparks.</param> /// <returns> /// A collection of sparks for the specified explosion. /// </returns> /// <exception cref="System.ArgumentNullException"> if <paramref name="explosion"/> /// is <c>null</c>.</exception> /// <exception cref="System.InvalidOperationException"> if <paramref name="explosion"/> /// does not match <typeparamref name="TExplosion"/>.</exception> public virtual IEnumerable <Firework> CreateSparks(ExplosionBase explosion) { if (explosion == null) { throw new ArgumentNullException(nameof(explosion)); } int desiredNumberOfSparks; if (!explosion.SparkCounts.TryGetValue(this.GeneratedSparkType, out desiredNumberOfSparks)) { return(Enumerable.Empty <Firework>()); } TExplosion typedExplosion = SparkGeneratorBase <TExplosion> .GetTypedExplosion(explosion); IList <Firework> sparks = new List <Firework>(desiredNumberOfSparks); for (int i = 0; i < desiredNumberOfSparks; i++) { sparks.Add(this.CreateSparkTyped(typedExplosion)); } return(sparks); }
/// <summary> /// Makes another iteration of the algorithm. /// </summary> public void MakeStepInternal() { Debug.Assert(this.state.StepNumber >= 0, "Negative step number"); Debug.Assert(this.state.StepNumber < int.MaxValue, "Updated step number is int.MaxValue, further steps will be incorrect"); Debug.Assert(this.state.Fireworks != null, "State firework collection is null"); Debug.Assert(this.Settings != null, "Settings is null"); Debug.Assert(this.Settings.SpecificSparksNumber >= 0, "Negative settings specific spark number"); Debug.Assert(this.Randomizer != null, "Randomizer is null"); Debug.Assert(this.Settings.LocationsNumber >= 0, "Negative settings locations number"); Debug.Assert(this.Exploder != null, "Exploder is null"); Debug.Assert(this.ExplosionSparkGenerator != null, "Explosion spark generator is null"); Debug.Assert(this.SpecificSparkGenerator != null, "Specific spark generator is null"); Debug.Assert(this.LocationSelector != null, "Location selector is null"); Debug.Assert(this.BestWorstFireworkSelector != null, "Best-Worst firework selector is null"); int stepNumber = this.state.StepNumber + 1; IEnumerable <int> specificSparkParentIndices = this.Randomizer.NextUniqueInt32s(this.Settings.SpecificSparksNumber, 0, this.Settings.LocationsNumber); IEnumerable <Firework> explosionSparks = new List <Firework>(); IEnumerable <Firework> specificSparks = new List <Firework>(this.Settings.SpecificSparksNumber); int currentFirework = 0; foreach (Firework firework in this.state.Fireworks) { Debug.Assert(firework != null, "Firework is null"); ExplosionBase explosion = this.Exploder.Explode(firework, this.state.Fireworks, stepNumber); Debug.Assert(explosion != null, "Explosion is null"); IEnumerable <Firework> fireworkExplosionSparks = this.ExplosionSparkGenerator.CreateSparks(explosion); Debug.Assert(fireworkExplosionSparks != null, "Firework explosion sparks collection is null"); explosionSparks = explosionSparks.Concat(fireworkExplosionSparks); if (specificSparkParentIndices.Contains(currentFirework)) { IEnumerable <Firework> fireworkSpecificSparks = this.SpecificSparkGenerator.CreateSparks(explosion); Debug.Assert(fireworkSpecificSparks != null, "Firework specific sparks collection is null"); specificSparks = specificSparks.Concat(fireworkSpecificSparks); } currentFirework++; } this.CalculateQualities(explosionSparks); this.CalculateQualities(specificSparks); IEnumerable <Firework> allFireworks = this.state.Fireworks.Concat(explosionSparks.Concat(specificSparks)); IEnumerable <Firework> selectedFireworks = this.LocationSelector.SelectFireworks(allFireworks); this.state.Fireworks = selectedFireworks; this.state.StepNumber = stepNumber; this.state.BestSolution = this.BestWorstFireworkSelector.SelectBest(selectedFireworks); }
/// <summary> /// Creates the spark from the explosion. /// </summary> /// <param name="explosion">The explosion that is the source of sparks.</param> /// <returns>A spark for the specified explosion.</returns> /// <exception cref="System.ArgumentNullException"> if <paramref name="explosion"/> /// is <c>null</c>.</exception> /// <exception cref="System.InvalidOperationException"> if <paramref name="explosion"/> /// does not match <typeparamref name="TExplosion"/>.</exception> public virtual Firework CreateSpark(ExplosionBase explosion) { if (explosion == null) { throw new ArgumentNullException(nameof(explosion)); } TExplosion typedExplosion = SparkGeneratorBase <TExplosion> .GetTypedExplosion(explosion); return(this.CreateSparkTyped(typedExplosion)); }
/// <summary> /// Casts <paramref name="explosion"/> to the <typeparamref name="TExplosion"/>. /// </summary> /// <param name="explosion">The firework explosion.</param> /// <returns>Typed firework explosion.</returns> /// <exception cref="System.InvalidOperationException"> if <paramref name="explosion"/> /// does not match <typeparamref name="TExplosion"/>.</exception> private static TExplosion GetTypedExplosion(ExplosionBase explosion) { Debug.Assert(explosion != null, "Explosion is null"); TExplosion typedExplosion = explosion as TExplosion; if (typedExplosion == null) { throw new InvalidOperationException(); } return(typedExplosion); }