/// <summary> /// Randomly select a triad type, then a card to keep the distribution even between types. /// </summary> public override Flashcard Next() { var typeArray = Enum.GetValues(typeof(TriadType)).Cast<TriadType>().Where(t => t != TriadType.All).ToArray(); var selectedTypes = typeArray.Where(t => TriadTypes.HasFlag(t)).ToArray(); if (selectedTypes.Count() > 1) { // if there's more than one selected type, we want an even distribution of triad types, not // weighted toward the types that have more cards. create an array of single-type generators // and randomly select one each time Next is called. if (_generators == null) { _generators = new TriadFlashcardGenerator[selectedTypes.Count()]; for (int i = 0; i < _generators.Length; i++) { var args = new TradFlashcardGeneratorArgs(); args.TriadTypes = selectedTypes[i]; args.TriadInversions = TriadInversions; args.Accidentals = Accidentals; args.Staffs = Staffs; _generators[i] = new TriadFlashcardGenerator(args); } } var randomType = r.Next(selectedTypes.Length); return _generators[randomType].Next(); } // only one selected type - call base which will randomly select a flashcard. return base.Next(); }
/// <summary> /// Creates a new TriadFlashcardGenerator. /// </summary> /// <param name="triadTypes">This flags value indicates which types of triads to include.</param> /// <param name="triadInversions">This flags value indicates which triad inversions to include.</param> /// <param name="staffs">This flags value indicates which staffs to include.</param> public TriadFlashcardGenerator(TradFlashcardGeneratorArgs args) : base(args) { if(args.TriadInversions == 0) throw new ArgumentException("Need at least one triad inversion to construct a triad flashcard generator."); if (args.TriadTypes == 0) throw new ArgumentException("Need at least one triad type to construct a triad flashcard generator."); TriadInversions = args.TriadInversions; TriadTypes = args.TriadTypes; if (Accidentals == AccidentalType.Natural) { // there just aren't enough diminished and augmented triads representable without accidentals, so skip them. TriadTypes &= ~TriadType.Augmented; TriadTypes &= ~TriadType.Diminished; } }