/// <summary> /// Merges a given composition strategy with this composition strategy by merging each strategy dictionary together. /// </summary> /// <param name="compositionStrategy">The CompositionStrategy to be used when merging</param> /// <returns>A CompositionStrategy containing attributes from both this CompositionStrategy and the passed one</returns> public CompositionStrategy CreateMergedCompositionStrategy(CompositionStrategy compositionStrategy) { var strategyDictionary = new Dictionary <CompositionContext, List <NoteChoiceWeightNoteChoice> >(); var i = 0; foreach (var keyValuePair in StrategyDictionary) { var context = keyValuePair.Key; var noteChoiceWeightsNoteChoices = keyValuePair.Value; strategyDictionary.Add( context, i % 2 == 0 ? noteChoiceWeightsNoteChoices : compositionStrategy.StrategyDictionary[context] ); i++; } var newCompositionStrategy = new CompositionStrategy(_noteChoices, _noteChoiceWeightGenerator, _compositionContexts) { StrategyDictionary = strategyDictionary }; return(newCompositionStrategy); }
/// <summary> /// The composer generates a composition using its unique CompositionStrategy. The composition is initialized /// with the default starting notes (defined above) and then iteratively built by identifying the current /// composition context, retrieving the next NoteChoice by giving the CompositionStrategy that context, and /// applying that NoteChoice to the current NotePair in order to create the next NotePair. /// </summary> /// <param name="totalNotes"></param> public void Compose(int totalNotes = TrainingNoteCount) { Composition.Reset(); var context = Composition.GetCurrentCompositionContext(); Composition.AddNotes( StartingCantusFirmusNote + StartingNoteModifier, StartingCounterPointNote + StartingNoteModifier, context, new NoteChoice() ); for (var i = 0; i < totalNotes - 1; ++i) { context = Composition.GetCurrentCompositionContext(); var noteChoice = CompositionStrategy.GetNextNoteChoice(context); var currentNotes = Composition.GetCurrentNotes(); var nextCantusFirmusNote = noteChoice.CantusFirmusNoteMotion == NoteMotion.Ascending ? currentNotes.CantusFirmusNote + noteChoice.CantusFirmusScaleDegreeChange : currentNotes.CantusFirmusNote - noteChoice.CantusFirmusScaleDegreeChange; var nextCounterPointNote = noteChoice.CounterPointNoteMotion == NoteMotion.Ascending ? currentNotes.CounterPointNote + noteChoice.CounterPointScaleDegreeChange : currentNotes.CounterPointNote - noteChoice.CounterPointScaleDegreeChange; Composition.AddNotes(nextCantusFirmusNote, nextCounterPointNote, context, noteChoice); } }
/// <summary> /// Optimizes this composer's CompositionStrategy by minimizing the NoteChoiceWeights which /// led to note choices which were detrimental to the composition. /// </summary> public void OptimizeCompositionStrategy() { foreach (var detrimentalNotePair in Composition.GetDetrimentalNotePairs()) { CompositionStrategy.MinimizeDetrimentalNoteChoiceWeight( detrimentalNotePair.ArrivedFromCompositionContext, detrimentalNotePair.ArrivedFromNoteChoice ); } }
/// <summary> /// Creates two child composers by mating this composer with the passed composer and merging /// their composition strategies together. /// </summary> /// <param name="mate">The other composer to mate this composer with</param> /// <returns>A list which consists of two composer children.</returns> public IList <Composer> CreateComposerChildren(Composer mate) { var firstChild = _factory.CreateComposer(); var secondChild = _factory.CreateComposer(); firstChild.CompositionStrategy = mate.CompositionStrategy.CreateMergedCompositionStrategy( CompositionStrategy ); secondChild.CompositionStrategy = CompositionStrategy.CreateMergedCompositionStrategy( mate.CompositionStrategy ); return(new List <Composer> { firstChild, secondChild }); }
/// <summary> /// Initializes this composers CompositionStrategy. /// </summary> public void InitializeCompositionStrategy() { CompositionStrategy.InitializeStrategyDictionary(); }
/// <summary> /// Mutates this composer's CompositionStrategy. /// </summary> /// <param name="mutationRate">The rate at which to mutate this composer's CompositionStrategy</param> /// <seealso cref="CompositionStrategy"/> public void Mutate(double mutationRate = MutationRate) { CompositionStrategy.Mutate(mutationRate); }