Example #1
0
        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))
                    });
                }
            }
        }
Example #3
0
        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);
        }