internal void AddElementToContainer(IElement element) { // Because we can't tell ahead of time if there will be // more than one element added to an element container, // we need to check at run-time. // // If the provided element is the first in the chain, we // assume it's the only one, and simply add it to the // container (whatever type that may be). // If a second element comes along, and it needs to go // in that container, then that means there is a // "sequence" of elements. Remove the first element // that was added earlier, add it and the new element // to a new sequence object, and put the sequence // into the container. // // Example of a "chain" (probably not the best term): // // |-- 0 --|------------ 1 ------------|-- 2 --| // <-- Chain # // Say("X").Optionally(r => r.Say("Y")).Say("Z") if (_countInChain == 1) { ISequence sequence = new Sequence(); sequence.AddElement(_container.Pop()); sequence.AddElement(element); _container.AddElement(sequence); _currentSequence = sequence; } else if (_countInChain > 1) { _currentSequence.AddElement(element); } else { _container.AddElement(element); } _countInChain++; }
public static void GenerateSequence(Random randomGenerator, ISong song, Difficulty difficulty) { var r = randomGenerator; Sequence sequence = new Sequence(); if (song.Sequences.ContainsKey(difficulty)) { song.Sequences.Remove(difficulty); } song.Sequences.Add(difficulty, sequence); int notesCount = 3; switch (difficulty) { case Difficulty.Easy: notesCount = 2; break; case Difficulty.Medium: notesCount = 2; break; case Difficulty.Hard: notesCount = 3; break; } for (int i = 2; i < song.Duration.TotalSeconds - 2; i++) { if (difficulty == Difficulty.Medium) { notesCount = r.Next(2, 4); } for (int j = 0; j < notesCount; j++) { SeqElemType elemType = (SeqElemType)r.Next(0, 4); sequence.AddElement(new SequenceElement() { Type = elemType, IsBomb = r.Next(0, 100) < 10, Time = new TimeSpan(0, 0, 0, i, r.Next(200, 1000)) }); } } }
private bool ProcessSpokenWords( IElementContainer elementContainer, Stack <String> spokenWordsStack, List <KeyValuePair <IGrammarAction, IEnumerable <String> > > callbacks, List <String> aw = null ) { if (callbacks == null) { throw new ArgumentNullException(nameof(callbacks)); } var sc = StringComparison.CurrentCultureIgnoreCase; var actionWords = new List <String>(); foreach (var element in elementContainer.Elements) { if (element is IWordElement) { var wordElement = element as IWordElement; var spokenWord = spokenWordsStack.FirstOrDefault(); // If the words don't match, then this sub-rule doesn't match. if (spokenWord == null || String.Equals(spokenWord, element.ToString(), sc) == false) { return(false); } // Add word to callback stack spokenWordsStack.Pop(); actionWords.Add(spokenWord); continue; } // This rule refers to another rule, so we need to // look it up and traverse it as well...a if (element is IRuleElement) { var ruleElement = element as IRuleElement; var nestedRule = _rules[ruleElement.ToString()]; var nestedResult = ProcessSpokenWords( nestedRule.Elements, spokenWordsStack, callbacks, actionWords ); if (nestedResult == false) { return(false); } continue; } // Check if we need to descend into a sub-rule (Optional, Repeats, Alternatives...) if (element is IElementContainer) { var subRule = (element as IElementContainer); var subRuleResult = false; if (subRule is IOptionals) { ProcessSpokenWords(subRule, spokenWordsStack, callbacks, actionWords); subRuleResult = true; } else if (subRule is IAlternatives) { var alternatives = (subRule as IAlternatives)?.Elements; foreach (var alternative in alternatives) { // Encapsulate in a sequence var s = new Sequence(); s.AddElement(alternative); subRuleResult = ProcessSpokenWords(s, spokenWordsStack, callbacks, actionWords); if (subRuleResult == true) { break; } } } else if (subRule is IRepeats) { var repeatable = (subRule as IRepeats)?.Elements; while (ProcessSpokenWords(subRule, spokenWordsStack, callbacks, actionWords)) { subRuleResult = true; } } else // Must be an ISequence { subRuleResult = ProcessSpokenWords(subRule, spokenWordsStack, callbacks, actionWords); } if (subRuleResult == false) { return(false); } continue; } if (element is IGrammarAction) { callbacks.Add( new KeyValuePair <IGrammarAction, IEnumerable <string> >( element as IGrammarAction, actionWords ) ); actionWords = new List <String>(); } } aw?.AddRange(actionWords); // If we get here, the rule matches the spoken words return(true); }