public Chromosome(int barNumber) { Length = 0; // Length 는 음 길이를 알리는 용도로만. 일단 공간은 최대로 확보해 놓는다. Note = new GeneNote[StaticRepo.ConfigRepository.MaxNumOfNote]; for (int i = 0; i < StaticRepo.ConfigRepository.MaxNumOfNote; i++) { Note[i] = new GeneNote(); } BarNumber = barNumber; Fitness_Detail = new double[Enum.GetNames(typeof(GA_AnalEnum)).Length]; }
/// <summary> /// 한 마디에 있는 노트들이 변이한다. /// 각 노트가 변이할 확률 /// </summary> /// <param name="Percentage">각 노트가 변이할 확률</param> /// <param name="Valiation">현재 pitch 에서 변동 폭</param> public void Mutate(double Percentage, int Valiation) { for (int i = 0; i < Length; i++) { // 피치 변조 if (StaticRepo.ConfigRepository.GlobalRandom.Next(1, 100) < Percentage * 100) { if (Note[i].pitch != 0) { int change = StaticRepo.ConfigRepository.GlobalRandom.Next(-Valiation, Valiation); if ((int)GeneticPitch.C3.GeneticPitchToMidiPitch(false) <= Note[i].pitch + change && (int)GeneticPitch.B6.GeneticPitchToMidiPitch(false) >= Note[i].pitch + change) { Note[i].pitch += change; if (!StaticRepo.ConfigRepository.thisSclae.Contains((Pitch)Note[i].pitch)) { Note[i].pitch += 1; } } else { Note[i].pitch -= change; if (!StaticRepo.ConfigRepository.thisSclae.Contains((Pitch)Note[i].pitch)) { Note[i].pitch -= 1; } } } } if (Note[i].pitch != 0) { // 노트 삭제 if (StaticRepo.ConfigRepository.GlobalRandom.Next(1, 100) < Percentage * 50) { if (i != 0 && Length > 12) { Note[i - 1].duration += Note[i].duration; for (int j = i; j < Length - 1; j++) // 앞으로 하나씩 땡긴다 { Note[j] = Note[j + 1]; } Note[Length - 1] = new GeneNote(); // 없앴으니 맨 마지막 노트는 그냥 땜빵용 노트로 Length--; } } } // 리페어링 if (StaticRepo.ConfigRepository.GlobalRandom.Next(1, 100) < Percentage * 100) { // 20%확률로 앞이 변경 if (StaticRepo.ConfigRepository.GlobalRandom.Next(1, 5) == 1) { if (BarNumber != 0) { if (Note[0].pitch != 0 && (int)StaticRepo.ScoreRepository.GABarList[BarNumber - 1].Notes.Last().ToPitch != 0) { // 앞에 끝 노트가 내 노트보다 작거나 크다면 내 노트를 낮추거나 높인다. 앞의 노트는 매우 중요하니 이 확률은 25%로.. int between = (int)StaticRepo.ScoreRepository.GABarList[BarNumber - 1].Notes.Last().ToPitch - Note[0].pitch; Note[0].pitch += between / 2; } } //if(Note[i].pitch != 0) //{ // if (!StaticRepo.ConfigRepository.thisSclae.Contains((Pitch)Note[i].pitch)) // { // Note[0].pitch -= 1; // } //} } else { if (BarNumber != StaticRepo.ScoreRepository.GABarList.Count() - 1) { if (Note[Length - 1].pitch != 0 && (int)StaticRepo.ScoreRepository.GABarList[BarNumber + 1].Notes[0].ToPitch != 0) { // 뒤에 끝 노트가 내 노트보다 작거나 크다면 내 노트를 낮추거나 높인다. int between = (int)StaticRepo.ScoreRepository.GABarList[BarNumber + 1].Notes[0].ToPitch - Note[Length - 1].pitch; Note[Length - 1].pitch += between / 2; } } //if(Note[Length - 1].pitch != 0) //{ // if (!StaticRepo.ConfigRepository.thisSclae.Contains((Pitch)Note[Length - 1].pitch)) // { // Note[Length - 1].pitch += 1; // } //} } } } }