示例#1
0
文件: Mutators.cs 项目: cwelt/Soloist
        /// <summary>
        /// Swaps the positions of two chord notes in the given bar,
        /// or in a randomly selected bar if <paramref name="barIndex"/> is null.
        /// <para>A random chord in the selected bar is selected, and two randomly
        /// selected notes which are played under this chord's time span are swapped
        /// by their positions.</para>
        /// </summary>
        /// <param name="melody"> The candidate melody to operate on.</param>
        /// <param name="barIndex"> Index of the bar to do the swap in. If no bar index supplied, then a random bar would be selected. </param>
        private protected virtual void SwapTwoNotesMutation(MelodyCandidate melody, int?barIndex = null)
        {
            // initialization
            INote       note1, note2;
            IList <int> noteIndices;
            Random      random = new Random();
            int         note1Index, note2Index, randomIndex1, randomIndex2, chordIndex;

            // if no specific bar has been requested then set it randomly
            int  selectedBarIndex = barIndex ?? random.Next(melody.Bars.Count);
            IBar bar = melody.Bars[selectedBarIndex];

            chordIndex = random.Next(bar.Chords.Count);
            bar.GetOverlappingNotesForChord(chordIndex, out noteIndices);

            // assure selected chord in bar contains at least two notes
            if (noteIndices.Count < 2)
            {
                return;
            }

            // select two random notes from withing the selected chord notes
            randomIndex1 = random.Next(1, noteIndices.Count);
            randomIndex2 = random.Next(0, randomIndex1);
            note1Index   = noteIndices[randomIndex1];
            note2Index   = noteIndices[randomIndex2];
            note1        = bar.Notes[note1Index];
            note2        = bar.Notes[note2Index];

            // swap the notes positions in the bar
            bar.Notes.RemoveAt(note1Index);
            bar.Notes.Insert(note1Index, note2);
            bar.Notes.RemoveAt(note2Index);
            bar.Notes.Insert(note2Index, note1);
        }