private static bool EvaluateModeAnswer(DiatonicMode mode, Guitar guitar, int stringNumber, int position, int[][] fretNumbers, string answer) { var pitch = guitar.GetPitch(stringNumber, position + fretNumbers[0][0]); var combinations = from keyNote in new[] { pitch.Note, pitch.Note.Invert() }.Distinct() from modeName in new[] { mode.GetName(), mode.GetAlternativeName() }.Distinct() select $"{keyNote.ToString().ToLowerInvariant()} {modeName.ToLowerInvariant()}"; return(combinations.Contains(answer)); }
private static void PrintExcercise(Guitar guitar, int stringNumber, int[][] fretNumbers, int maxFretNumber, int questionStringIndex, int questionFretIndex, int position) { var questionStringNumber = stringNumber + questionStringIndex; var sb = new StringBuilder(); var stringFrets = new bool[maxFretNumber + 1]; for (var i = guitar.NumberOfStrings - 1; i >= 0; i--) { sb.Clear(); Array.Clear(stringFrets, 0, stringFrets.Length); int fretNumberIndex = i - stringNumber; int[] stringFretNumbers; if (0 <= fretNumberIndex && fretNumberIndex < fretNumbers.Length) { stringFretNumbers = fretNumbers[fretNumberIndex]; for (var j = 0; j < stringFretNumbers.Length; j++) { stringFrets[stringFretNumbers[j]] = true; } } else { stringFretNumbers = null; } sb.Append(guitar.GetPitch(i, 0).Note.ToString().PadRight(3)).Append('-').Append('|'); for (var j = 0; j < stringFrets.Length; j++) { sb.Append('-'); if (!stringFrets[j]) { sb.Append('-'); } else if (i == questionStringNumber && j == stringFretNumbers[questionFretIndex]) { sb.Append('?'); } else { sb.Append('O'); } sb.Append('-').Append('|'); } sb.Append('-'); Console.WriteLine(sb.ToString()); } Console.WriteLine(new string(' ', 5) + position.ToString().PadLeft(2)); }
private static int FillFretNumbers(int[][] fretNumbers, Guitar guitar, int stringNumber, DiatonicScale scale) { int fretNumber = 0; int minFretNumber = fretNumber; int maxFretNumber = fretNumber; using (IEnumerator <Interval> intervalEnumerator = scale.GetIntervalsAscending().GetEnumerator()) { for (var i = 0; i < fretNumbers.Length; i++) { for (var j = 0; j < fretNumbers[i].Length; j++) { fretNumbers[i][j] = fretNumber; if (fretNumber > maxFretNumber) { maxFretNumber = fretNumber; } intervalEnumerator.MoveNext(); fretNumber += intervalEnumerator.Current.Semitones; } if (stringNumber < guitar.StringIntervals.Count) { fretNumber -= guitar.StringIntervals[stringNumber].Semitones; if (fretNumber < minFretNumber) { minFretNumber = fretNumber; } } stringNumber++; } } if (minFretNumber < 0) { ShiftFretNumbers(fretNumbers, -minFretNumber); maxFretNumber -= minFretNumber; } return(maxFretNumber); }
private static void Practice() { s_practiceStats = new PracticeStats(); Console.CancelKeyPress += (s, e) => PrintPracticeStats(); var guitar = new Guitar(); var random = new Random(); for (; ;) { var mode = (DiatonicMode)random.Next(DiatonicScale.NumberOfDegrees); var scale = new DiatonicScale(Note.C, mode); var pattern = (Pattern)random.Next(numberOfPatterns); int[][] fretNumbers = CreateFretNumbers(pattern); int stringNumber = random.Next(guitar.NumberOfStrings - fretNumbers.Length + 1); int maxFretNumber = FillFretNumbers(fretNumbers, guitar, stringNumber, scale); int questionStringIndex; int questionFretIndex; if (random.Next(10) != 0) { questionStringIndex = random.Next(fretNumbers.Length); questionFretIndex = random.Next(fretNumbers[questionStringIndex].Length); } else { questionStringIndex = questionFretIndex = -1; } int position = random.Next(guitar.NumberOfFrets - maxFretNumber + 1); PrintExcercise(guitar, stringNumber, fretNumbers, maxFretNumber, questionStringIndex, questionFretIndex, position); Console.WriteLine(); Console.Write(questionStringIndex >= 0 ? "Enter scale degree: " : "Enter scale name: "); Console.WriteLine($"({s_practiceStats.Stopwatch.Elapsed:hh':'mm':'ss})"); for (; ;) { var answer = Console.ReadLine()?.ToLowerInvariant(); if (answer == null || answer == "q" || answer == "quit") { PrintPracticeStats(); return; } bool isCorrectAnswer; if (questionStringIndex >= 0) { DiatonicMode degree = mode; for (var i = 0; i < fretNumbers.Length; i++) { for (var j = 0; j < fretNumbers[i].Length; j++) { if (i < questionStringIndex || j < questionFretIndex) { degree++; if (degree - Ionian >= DiatonicScale.NumberOfDegrees) { degree -= DiatonicScale.NumberOfDegrees; } } else { goto EndOfLoop; } } } EndOfLoop: isCorrectAnswer = EvaluateDegreeAnswer(degree, answer); } else { isCorrectAnswer = EvaluateModeAnswer(mode, guitar, stringNumber, position, fretNumbers, answer); } if (isCorrectAnswer) { s_practiceStats.NumberOfCorrectAnswers++; Console.WriteLine("Correct!"); break; } else { s_practiceStats.NumberOfWrongAnswers++; Console.WriteLine("Wrong!"); } } Console.WriteLine(); } }