private double generarBloquesRitmicos(IList <BloqueRitmico> bloques, double longitudActual, double longitudObjetivo) { // 1. Obtenemos la lista de bloques candidatos // 2. Eliminamos de la lista aquellos bloques cuya longitud exceda el límite // 3. Mientras queden bloques candidatos y longitudActual < longitudObjetivo // 3.1. Elegir al azar uno de los bloques candidatos de los que quedan y añadirlo a 'bloques' incrementando la 'longitudActual' // 3.2. Invocar recursivamente a 'generarBloquesRitmicos' // 3.3. Si longitudActual < longitudObjetivo // 3.3.1. Eliminamos de la lista de bloques candidatos y de bloques el último elegido, decrementando 'longitudActual' // 1. Obtenemos la lista de bloques candidatos IList <BloqueRitmico> bloquesCandidatos = new List <BloqueRitmico>(); for (int i = 0; i < bloquesRitmicosDisponibles.Length; i++) { bloquesCandidatos.Add(bloquesRitmicosDisponibles[i]); } // 2. Eliminamos de la lista aquellos bloques cuya longitud exceda el límite int j = 0; while (j < bloquesCandidatos.Count) { if (bloquesCandidatos[j].getLongitud() > longitudObjetivo - longitudActual) { bloquesCandidatos.RemoveAt(j); } else { j++; } } // 3. Mientras queden bloques candidatos y longitudActual < longitudObjetivo while (longitudActual < longitudObjetivo && bloquesCandidatos.Count > 0) { // 3.1. Elegir al azar uno de los bloques candidatos de los que quedan y añadirlo a 'bloques' incrementando la 'longitudActual' int idxBloque = MusicUtils.rnd.Next(bloquesCandidatos.Count); BloqueRitmico bloque = bloquesCandidatos[idxBloque]; bloques.Add(bloque); longitudActual += bloque.getLongitud(); if (longitudActual < longitudObjetivo) { // 3.2. Invocar recursivamente a 'generarBloquesRitmicos' longitudActual = generarBloquesRitmicos(bloques, longitudActual, longitudObjetivo); // 3.3. Si longitudActual < longitudObjetivo if (longitudActual < longitudObjetivo) { // 3.3.1. Eliminamos de la lista de bloques candidatos y de bloques el último elegido, decrementando 'longitudActual' bloquesCandidatos.RemoveAt(idxBloque); bloques.RemoveAt(bloques.Count - 1); longitudActual -= bloque.getLongitud(); } } } return(longitudActual); }
public Pentagrama(string tonalidad, string clave) { this.clave = clave; Configuracion cfg = Configuracion.obtenerConfiguracion(); // Leer el rango de notas string rango = "G".Equals(clave) ? cfg.pentagrama_rango_g : cfg.pentagrama_rango_f; string[] notas = rango.Split(','); if (notas.Length != 2) { throw new Exception("El rango de notas debe estar formado por dos notas. The range of notes must contain two notes"); } string notaIni = notas[0].Substring(0, 1); int octavaIni = int.Parse(notas[0].Substring(notas[0].Length - 1, 1)); string notaFin = notas[1].Substring(0, 1); int octavaFin = int.Parse(notas[1].Substring(notas[1].Length - 1, 1)); // calcular el número de notas int numNotas = MusicUtils.NOTAS.Count * (octavaFin - octavaIni + 1) - MusicUtils.NOTAS.IndexOf(notaIni) - (MusicUtils.NOTAS.Count - 1 - MusicUtils.NOTAS.IndexOf(notaFin)); notasDisponibles = new Nota[numNotas]; int idxNota = 0; for (int octava = octavaIni; octava <= octavaFin; octava++) { int idxNotaInicio = 0; int idxNotaFin = MusicUtils.NOTAS.Count - 1; if (octava == octavaIni) { idxNotaInicio = MusicUtils.NOTAS.IndexOf(notaIni); } if (octava == octavaFin) { idxNotaFin = MusicUtils.NOTAS.IndexOf(notaFin); } for (int i = idxNotaInicio; i <= idxNotaFin; i++) { notasDisponibles[idxNota] = new Nota(MusicUtils.NOTAS[i], octava, null); idxNota++; } } MusicUtils.aplicarAlteraciones(tonalidad, notasDisponibles); // Bloques rítmicos a utilizar string sRitmos = "G".Equals(clave) ? cfg.bloques_ritmicos_g : cfg.bloques_ritmicos_f; string[] sListaRimtos = sRitmos.Split(','); bloquesRitmicosDisponibles = new BloqueRitmico[sListaRimtos.Length]; for (int i = 0; i < sListaRimtos.Length; i++) { string[] duraciones = sListaRimtos[i].Split('+'); bloquesRitmicosDisponibles[i] = new BloqueRitmico(duraciones); } }