상속: MonoBehaviour
예제 #1
0
        public TableLayout(PaintedTiles paintedTiles, int tileCountOnTable, int columnCount)
        {
            if (paintedTiles == null)
            {
                throw new ArgumentNullException("paintedTiles");
            }

            if (paintedTiles.Count < tileCountOnTable)
            {
                throw new ArgumentOutOfRangeException("tileCountOnTable", tileCountOnTable, "Number of places on the table must smaller or equal than number of available tiles (paintedTiles)!");
            }

            this.paintedTiles = paintedTiles;
            this.tileCountOnTable = tileCountOnTable;
            this.columnCount = columnCount;

            this.physicalLayout = this.BuildPhysicalLayout();

            // preallocating arrays to store available tiles at every single recursion level independently
            this.availableTilesInLevels = new int[this.tileCountOnTable][];
            for (int i = 0; i < this.tileCountOnTable; i++)
            {
                // number of available tiles = number of paintedTiles - already placed tiles on table at the level of recursion
                this.availableTilesInLevels[i] = new int[this.PaintedTileCount - i];
            }

            this.actualTileSequence = new TileSequence(this.tileCountOnTable);
            this.resultTileSequences = new List<TileSequence>();
        }
        public void BoldlyGoTest()
        {
            var model = new ApplicationModel(new TracingWriterEnvironment());

            var script = new[]
            {
                "space",
                "the final frontier",
                "these are the voyages of the starship enterprise",
                "its five year mission",
                "to explore strange new worlds",
                "to seek out new life",
                "and new civilizations",
                "to boldly go where no man has gone before"
            };

            for (var line = 0; line < script.Length - 1; line++)
            {
                var lineSequence = TileSequence.FromRaw(script[line]);

                ApplicationRobotAction action;
                do
                {
                    action = ApplicationRobot.GetNextCompletionAction(model, lineSequence);
                    action.ExecuteItem(model);
                }while (!action.IsComplete);
            }

            var sequence = TileSequence.FromRaw(script[^ 1]);
        private static void SequenceSanityCheck(TileSequence sequence)
        {
            var encoded        = sequence.ToHybridEncoded();
            var sequenceRemade = TileSequence.FromEncoded(encoded);

            Assert.AreEqual(sequence, sequenceRemade);
        }
        private static void CheckRoundTrip(string expected)
        {
            var collection = TileSequence.FromEncoded(expected);
            var actual     = collection.ToHybridEncoded();

            Assert.AreEqual(expected, actual);
        }
        private static void MultiTest(TileSequence words, int expectedFirstClicks, int expectedSecondClicks, int expectedEmptyClicks, int expectedClicksWithRandomErrors, [CallerMemberName] string caller = null)
        {
            var model = new ApplicationModel(new TracingWriterEnvironment())
            {
                DisplayRows = 9
            };

            var actualFirstClicks = CountClicks(model, words, caller + ".first");

            Assert.AreEqual(expectedFirstClicks, actualFirstClicks, "first pass");

            var actualSecondClicks = CountClicks(model, words, caller + ".second");

            Assert.AreEqual(expectedSecondClicks, actualSecondClicks, "second pass");

            var emptyEnvironment = new EmptyEnvironment();
            var emptyModel       = new ApplicationModel(emptyEnvironment);

            var actualEmptyClicks = CountClicks(emptyModel, words, caller + ".empty");

            Assert.AreEqual(expectedEmptyClicks, actualEmptyClicks, "from empty");

            var errorModel = new ApplicationModel(new TracingWriterEnvironment())
            {
                DisplayRows = 9
            };
            var actualClicksWithRandomErrors = CountClicks(errorModel, words, 0.2, caller + ".erred");

            Assert.AreEqual(expectedClicksWithRandomErrors, actualClicksWithRandomErrors, "with errors");
        }
        private static void RawSanityCheck(string raw)
        {
            var sequence = TileSequence.FromRaw(raw);

            SequenceSanityCheck(sequence);

            var rawRemade = sequence.ToRaw();

            Assert.AreEqual(raw, rawRemade);
        }
예제 #7
0
        private static ApplicationRobotAction CreateExtendedSuggestedWordAction(ApplicationModel model,
                                                                                bool complete,
                                                                                TileSequence words,
                                                                                int wordsMatchLim,
                                                                                int index,
                                                                                int subIndex,
                                                                                CultureInfo culture)
        {
            ApplicationRobotAction action;

            var list = model.SuggestionLists[index];

            using (var enumerator = list.GetEnumerator())
            {
                for (var i = 0; i < subIndex; i++)
                {
                    var moved = enumerator.MoveNext();
                    Debug.Assert(moved);
                }

                // See what words match exactly.
                var subLim = 0;
                while (enumerator.MoveNext() &&
                       wordsMatchLim + subLim < words.Count &&
                       !(enumerator.Current is ExtendedSuggestedWordItem) &&
                       IsItemMatchExact <SuggestedWordItem>(enumerator.Current, words[wordsMatchLim + subLim], culture))
                {
                    subLim++;
                }

                if (complete &&
                    wordsMatchLim + subLim == words.Count &&
                    enumerator.Current is TailStopItem)
                {
                    // We can complete the action.
                    action = ApplicationRobotAction.CreateSuggestionAndComplete(index, subIndex + subLim);
                }
                else
                {
                    if (wordsMatchLim + subLim < words.Count &&
                        !(enumerator.Current is ExtendedSuggestedWordItem) &&
                        IsItemMatch <SuggestedWordItem>(enumerator.Current, words[wordsMatchLim + subLim], culture))
                    {
                        subLim++;
                    }

                    // We can advance a word or more.
                    action = ApplicationRobotAction.CreateSuggestion(index, subIndex + subLim);
                    AssertGoodAction(model, action);
                }
            }

            return(action);
        }
        private void OnTextChanged(object sender, RoutedEventArgs e)
        {
            var box  = (TextBox)sender;
            var text = box.Text;

            var sequence = TileSequence.FromRaw(text);

            ItemsContainer.Items.Clear();
            foreach (var child in sequence)
            {
                ItemsContainer.Items.Add(new TileVisualizationElement(child.Type, child.Content, TileColor.Text, TileColor.HeadBackground));
            }
        }
        public void GetDefaultEncodedFromRawTest()
        {
            var helloWorldEncoded = TileSequence.RawToDefaultSimpleEncoded("Hello World");

            Assert.AreEqual("Hello World", helloWorldEncoded);
            CheckRoundTrip(helloWorldEncoded);

            var elementEncoded = TileSequence.RawToDefaultSimpleEncoded("<Element/>");

            Assert.AreEqual("&lt;Element/&gt;", elementEncoded);
            //CheckRoundTrip(elementEncoded);

            var jackAndJillEncoded = TileSequence.RawToDefaultSimpleEncoded("Jack & Jill");

            Assert.AreEqual("Jack &amp; Jill", jackAndJillEncoded);
            //CheckRoundTrip(jackAndJillEncoded);
        }
예제 #10
0
        static void Main(string[] args)
        {
            var path = args[0];

            using (var stream = File.OpenRead(path))
            {
                var sentences = EpubStreamHelper.StreamToSentences(stream);

                foreach (var sentence in sentences)
                {
                    var sequence  = TileSequence.FromRaw(sentence);
                    var utterance = new UtteranceData(sequence, true);
                    var line      = utterance.ToLine();
                    Console.WriteLine(line);
                }
            }
        }
        public void GoodAndBadXmlTest()
        {
            var texts = new[] { "<T>Hello</T><T>World</T>", "<T>Hello", "<!-- Comment -->" };

            foreach (var text in texts)
            {
                var good = true;
                try
                {
                    _ = TileSequence.FromEncoded(text);
                }
                catch
                {
                    good = false;
                }

                Assert.AreEqual(text == texts[0], good);
            }
        }
        public void JackAmpJillTest()
        {
            var sequence = TileSequence.FromRaw("Jack & Jill");
            var started  = new DateTimeOffset(1963, 12, 5, 12, 30, 45, 123, TimeSpan.FromMinutes(7 * 60));
            var duration = TimeSpan.FromSeconds(5 * 60);
            var keyCount = 42;

            var utterance = new UtteranceData(sequence, started, duration, keyCount);

            var line = utterance.ToLine();

            Assert.AreEqual("<U Started=\"1963-12-05T12:30:45.1230000+07:00\" Duration=\"300000\" KeyCount=\"42\"><T>Jack</T><T>&amp;</T><T>Jill</T></U>", line);

            var actual = UtteranceData.FromLine(line);

            Assert.AreEqual(sequence, actual.Sequence);
            Assert.AreEqual(started, actual.Started);
            Assert.AreEqual(duration, actual.Duration);
            Assert.AreEqual(keyCount, actual.KeyCount);
        }
        public void EqualsTest()
        {
            var a = TileData.Create("A");
            var b = TileData.Create("B");

            var sequences = new[]
            {
                TileSequence.FromData(),
                TileSequence.FromData(a, a),
                TileSequence.FromData(a, b),
                TileSequence.FromData(b, a)
            };

            for (var i = 0; i < sequences.Length; i++)
            {
                for (var j = 0; j < sequences.Length; j++)
                {
                    var lhs = sequences[i];
                    var rhs = sequences[j];

                    var equals  = lhs.Equals(rhs);
                    var lhsHash = lhs.GetHashCode();
                    var rhsHash = rhs.GetHashCode();

                    Assert.AreEqual(i == j, equals);
                    Assert.IsTrue(!equals || lhsHash == rhsHash);

                    var equalsUntyped   = lhs.Equals((object)rhs);
                    var unequalsUntyped = lhs.Equals(42);
                    Assert.AreEqual(equals, equalsUntyped);
                    Assert.IsFalse(unequalsUntyped);
                }
            }

            Assert.AreNotEqual(sequences[0], "Ethel the Aardvark");
        }
예제 #14
0
        /// <summary>
        /// Get the next action to achieve the given goal and press a Stop button to complete,
        /// </summary>
        /// <param name="model">The model to act against.</param>
        /// <param name="sequence">The words to be spoken.</param>
        /// <returns>The next action to take with IsComplete set true if this is the action to complete the goal.</returns>
        public static ApplicationRobotAction GetNextCompletionAction(ApplicationModel model, TileSequence sequence)
        {
            var action = FindNextAction(model, true, sequence);

            return(action);
        }
예제 #15
0
        private void OnCursedTextChanged(object sender, RoutedEventArgs e)
        {
            var box  = (TextBox)sender;
            var text = box.Text;

            var sequence = TileSequence.FromRaw(text);

            var start  = box.SelectionStart;
            var length = box.SelectionLength;

            Debug.WriteLine($"Selection is {start} for {length}");

            var list = new List <TileVisualizationElement>();

            var charPosition = 0;
            var tilePosition = 0;

            while (tilePosition < sequence.Count &&
                   charPosition + sequence[tilePosition].Content.Length <= start)
            {
                list.Add(new TileVisualizationElement(sequence[tilePosition].Type, sequence[tilePosition].Content, TileColor.Text, TileColor.HeadBackground));

                charPosition += sequence[tilePosition].Content.Length;
                tilePosition++;
                if (tilePosition < sequence.Count &&
                    !sequence[tilePosition - 1].IsPrefix &&
                    !sequence[tilePosition].IsSuffix)
                {
                    charPosition++;
                }
            }

            if (length == 0)
            {
                if (tilePosition < sequence.Count)
                {
                    if (charPosition < start)
                    {
                        var tile = sequence[tilePosition];
                        tilePosition++;

                        var prefix = TileData.Create(tile.Content.Substring(0, start - charPosition),
                                                     isPrefix: true,
                                                     isSuffix: tile.IsSuffix);
                        list.Add(new TileVisualizationElement(prefix.Type, prefix.Content, TileColor.Text, TileColor.HeadBackground));

                        var caret = TileData.Create("^");
                        list.Add(new TileVisualizationElement(caret.Type, caret.Content, TileColor.Text, TileColor.SuggestionPartBackground));

                        var suffix = TileData.Create(tile.Content.Substring(start - charPosition),
                                                     isPrefix: tile.IsPrefix,
                                                     isSuffix: true);
                        list.Add(new TileVisualizationElement(suffix.Type, suffix.Content, TileColor.Text, TileColor.HeadBackground));
                    }
                    else
                    {
                        var caret = TileData.Create("^",
                                                    isPrefix: start == charPosition,
                                                    isSuffix: start < charPosition);
                        list.Add(new TileVisualizationElement(caret.Type, caret.Content, TileColor.Text, TileColor.SuggestionPartBackground));
                    }
                }
                else
                {
                    var caret = TileData.Create("^", isSuffix: true);
                    list.Add(new TileVisualizationElement(caret.Type, caret.Content, TileColor.Text, TileColor.SuggestionPartBackground));
                }
            }
            else
            {
            }

            while (tilePosition < sequence.Count)
            {
                list.Add(new TileVisualizationElement(sequence[tilePosition].Type, sequence[tilePosition].Content, TileColor.Text, TileColor.HeadBackground));
                tilePosition++;
            }

            CursedContainer.Items.Clear();
            foreach (var child in list)
            {
                CursedContainer.Items.Add(child);
            }
        }
        public void SimpleConstructionTest()
        {
            var sequence = TileSequence.FromData();

            Assert.IsNotNull(sequence);
        }
        public void ComplexishConstructionTest()
        {
            var sequence = TileSequence.FromData(TileData.Create("hello"), TileData.Create("world"));

            Assert.IsNotNull(sequence);
        }
        private static int CountClicks(ApplicationModel model, TileSequence words, double errorRate, string traceName)
        {
            Assert.IsInstanceOf <TracingWriterEnvironment>(model.Environment);

            var random = new Random(0);

            var count      = 0;
            var errorCount = 0;

            var hasNotified        = false;
            var expectedIsComplete = false;

            var actionIsComplete = false;
            var isGood           = false;

            void OnNotifyCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                Assert.IsFalse(hasNotified, "No changes after model update notification");
            }

            void OnApplicationModelUpdated(object sender, ApplicationModelUpdateEventArgs e)
            {
                Assert.IsFalse(hasNotified, "No previous model update notification");
                hasNotified = true;

                Assert.AreEqual(isGood && actionIsComplete, isGood && e.IsComplete);

                if (e.IsComplete)
                {
                    expectedIsComplete = true;
                }
                else
                {
                    expectedIsComplete = false;
                }
            }

            var collections = new INotifyCollectionChanged[] { model.HeadItems, model.TailItems, model.SuggestionInterstitials, model.SuggestionLists };

            foreach (var collection in collections)
            {
                collection.CollectionChanged += OnNotifyCollectionChanged;
            }
            model.ApplicationModelUpdate += OnApplicationModelUpdated;

            bool done;

            do
            {
                ApplicationRobotAction action;

                if (errorCount < 100 && random.NextDouble() < errorRate)
                {
                    isGood = false;
                    action = ApplicationRobot.GetRandom(model, random);
                    errorCount++;
                }
                else if (random.NextDouble() < errorRate / 20.0)
                {
                    isGood = false;
                    action = ApplicationRobot.GetRandom(model, random);
                    errorCount++;
                }
                else
                {
                    isGood = true;
                    action = ApplicationRobot.GetNextCompletionAction(model, words);
                }

                var item = action.GetItem(model);
                if (item is InterstitialNonItem)
                {
                    Assert.IsNotInstanceOf <InterstitialNonItem>(item, "Should never click on a non-item");
                }

                hasNotified      = false;
                actionIsComplete = action.IsComplete;
                action.ExecuteItem(model);
                Assert.IsTrue(hasNotified, "We should have seen a notification");
                Assert.AreEqual(isGood && expectedIsComplete, isGood && action.IsComplete, "IsComplete in action and notification should match");

                CheckModelLinkage(model);

                count++;
                done = isGood && action.IsComplete;

#if false
                if (9900 <= count)
                {
                    if (Debugger.IsAttached)
                    {
                        var item = action.GetItem(model);
                        Debug.WriteLine($"{count}: {isGood} {action.Target} {action.Index}.{action.SubIndex} - {item.GetType().Name} - {item}");
                    }

                    if (9950 <= count)
                    {
                        Assert.IsTrue(count < 10000, "Clicking ends in reasonable time");
                    }
                }
#else
                Assert.IsTrue(count < 10000, "Clicking ends in reasonable time");
#endif
            }while (!done);

            foreach (var collection in collections)
            {
                collection.CollectionChanged -= OnNotifyCollectionChanged;
            }
            model.ApplicationModelUpdate -= OnApplicationModelUpdated;


            // Check there is but one action needed to re-establish text.
            var reestablishAction = ApplicationRobot.GetNextEstablishingAction(model, words);
            Assert.IsNotNull(reestablishAction);
            Assert.IsFalse(reestablishAction.IsComplete);
            reestablishAction.ExecuteItem(model);

            var nullAction = ApplicationRobot.GetNextEstablishingAction(model, words);
            Assert.IsNull(nullAction);

            // Check there is now a single action to complete the text.
            var completionAction = ApplicationRobot.GetNextCompletionAction(model, words);
            Assert.IsNotNull(completionAction);
            Assert.IsTrue(completionAction.IsComplete);
            completionAction.ExecuteItem(model);

            SaveTrace(model, traceName);

            return(count);
        }
        private static void SequenceSanityCheck(params TileData[] tiles)
        {
            var sequence = TileSequence.FromData(tiles);

            SequenceSanityCheck(sequence);
        }
예제 #20
0
        internal void Commit(ITile stopTile)
        {
            ParanoidAssertValid();

            // Find position from which to work backwards to rebirth ghost items.
            ITile position;

            if (_selectedIndex == 0 &&
                stopTile is GhostStopItem)
            {
                position = _headItems[_headItems.Count - 1].Predecessor;
            }
            else
            {
                position = stopTile.Predecessor;
            }

            var wordList = new List <string>();

            while (!ReferenceEquals(LastTile, position))
            {
                wordList.Insert(0, position.Content);
                position = position.Predecessor;
            }

            AddWords(wordList);

            if (_selectedIndex == 0 &&
                2 < _headItems.Count &&
                _headItems[_headItems.Count - 1] is GhostStopItem)
            {
                TransferRunOnToSuccessors(_headItems[_headItems.Count - 2]);
            }

            ParanoidAssertValid();

            var selection = new List <int>(Context)
            {
                0
            };

            RollbackAndAddSequence(selection, PersistedSequenceWeight);

            var predecessor = _headItems[0];

            for (var i = 1; i <= _selectedIndex; i++)
            {
                var selected = _headItems[i];
                var ghost    = CreateGhostWordItem(predecessor, selected.Content);
                _headItems[i] = ghost;
                predecessor   = ghost;
            }

            while (_selectedIndex + 1 < _headItems.Count)
            {
                _headItems.RemoveAt(_headItems.Count - 1);
            }

            selection.RemoveAt(0);
            selection.RemoveAt(selection.Count - 1);
            var tiles = new List <TileData>();

            foreach (var token in selection)
            {
                var tokenString = _tokens.GetString(token);
                var tile        = TileData.FromTokenString(tokenString);
                tiles.Add(tile);
            }
            var utterance = TileSequence.FromData(tiles);

            SetSelectedIndex(0);
            var tail = new GhostStopItem(predecessor, this);

            _headItems.Add(tail);

            Model.SaveUtterance(utterance);

            InitializeUtterance();
            SetSuggestionsViewComplete();

            ParanoidAssertValid();
        }
예제 #21
0
        /// <summary>
        /// Get the next action to achieve the given goal.
        /// </summary>
        /// <param name="model">The model to act against.</param>
        /// <param name="sequence">The words to be spoken.</param>
        /// <returns>The next action to take or null if no action is needed..</returns>
        public static ApplicationRobotAction GetNextEstablishingAction(ApplicationModel model, TileSequence sequence)
        {
            var action = FindNextAction(model, false, sequence);

            return(action);
        }
        private static int CountClicks(ApplicationModel model, TileSequence sequence, string traceName)
        {
            var clicks = CountClicks(model, sequence, 0.0, traceName);

            return(clicks);
        }
예제 #23
0
        private static ApplicationRobotAction GetSuggestionsAction(ApplicationModel model,
                                                                   bool complete,
                                                                   TileSequence words,
                                                                   int wordsMatchLim,
                                                                   CultureInfo culture)
        {
            ApplicationRobotAction action;

            var targetWord = words[wordsMatchLim];

            action = null;
            for (var index = 0; action == null && index < model.SuggestionLists.Count; index++)
            {
                var list      = model.SuggestionLists[index];
                var firstItem = list.First();

                if (IsItem <SuggestedWordItem>(firstItem, out var suggestedWordItem))
                {
                    var suggestedWord = suggestedWordItem.Tile.Content;

                    if (StringEquals(suggestedWord, targetWord.Content, culture))
                    {
                        // Found our word.
                        action = CreateSuggestedWordAction(model, complete, words, wordsMatchLim, index, culture);
                    }
                    else if (StringCompare(targetWord.Content, suggestedWord, culture) < 0)
                    {
                        // Need to step back.
                        action = ApplicationRobotAction.CreateInterstitial(index);
                    }
                    else
                    {
                        var subIndex = 1;
                        while (subIndex < list.Count &&
                               list[subIndex] is ExtendedSuggestedWordItem extensionWord &&
                               StringCompare(extensionWord.Content, targetWord.Content, culture) < 0)
                        {
                            subIndex++;
                        }

                        if (subIndex < list.Count &&
                            list[subIndex] is ExtendedSuggestedWordItem extensionWordFound &&
                            StringCompare(extensionWordFound.Content, targetWord.Content, culture) == 0)
                        {
                            action = CreateExtendedSuggestedWordAction(model, complete, words, wordsMatchLim, index, subIndex, culture);
                        }
                    }
                }
                else if (firstItem is SuggestedSpellingItem)
                {
                    var partial = firstItem.Content;

                    if (StartsWith(targetWord.Content, partial, culture))
                    {
                        var subIndex = 0;
                        using (var enumerator = list.GetEnumerator())
                        {
                            var more = enumerator.MoveNext();
                            Debug.Assert(more);
                            Debug.Assert(enumerator.Current is SuggestedSpellingItem);

                            more = enumerator.MoveNext();
                            while (more &&
                                   enumerator.Current is SuggestedSpellingSequenceItem &&
                                   StartsWith(targetWord.Content, enumerator.Current.Content, culture))
                            {
                                subIndex++;
                                more = enumerator.MoveNext();
                            }

                            if (complete &&
                                more &&
                                enumerator.Current is SuggestedWordItem &&
                                StringEquals(enumerator.Current.Content, targetWord.Content, culture))
                            {
                                action = ApplicationRobotAction.CreateSuggestion(index, subIndex + 1);
                                AssertGoodAction(model, action);
                            }
                            else
                            {
                                action = ApplicationRobotAction.CreateSuggestion(index, subIndex);
                            }
                        }
                    }
                    else if (!StartsWith(targetWord.Content, partial.Substring(0, partial.Length - 1), culture))
                    {
                        // Need to remove incorrectly spelled items.
                        if (targetWord.Content[0] != partial[0])
                        {
                            action = GetModeEscape(model);
                        }
                        else if (index != 0 && model.SuggestionLists[0].First() is SuggestedSpellingBackspaceItem)
                        {
                            action = ApplicationRobotAction.CreateSuggestion(0, 0);
                            AssertGoodAction(model, action);
                        }
                        else
                        {
                            // Need to erase unwanted letters, which means winding to top of spellings.
                            Debug.Assert(model.SuggestionLists[0].First() is InterstitialGapItem);
                            action = ApplicationRobotAction.CreateInterstitial(0);
                        }
                    }
                    else if (StringCompare(partial.Substring(partial.Length - 1, 1), targetWord.Content.Substring(partial.Length - 1, 1), culture) < 0)
                    {
                        // Look at next item.
                    }
                    else
                    {
                        action = ApplicationRobotAction.CreateInterstitial(index);
                    }
                }
                else if (firstItem is SuggestedSpellingWordItem)
                {
                    if (StringEquals(firstItem.Content, targetWord.Content, culture))
                    {
                        action = ApplicationRobotAction.CreateSuggestion(index, 0);
                        AssertGoodAction(model, action);
                    }
                }
                else if (firstItem is SuggestedSpellingBackspaceItem)
                {
                    if (!StartsWith(targetWord.Content, firstItem.Content, culture))
                    {
                        action = ApplicationRobotAction.CreateSuggestion(index, 0);
                    }
                }
                else if (firstItem is CommandItem)
                {
                    // TODO: We don't deal with these yet!
                }
                else if (firstItem is TailStopItem)
                {
                    // TODO: We don't deal with these, could use it or press the static stop!
                }
                else
                {
                    Debug.Assert(firstItem is SuggestedUnicodeItem);

                    var partial = firstItem.Content;

                    Debug.Assert(((SuggestedUnicodeItem)firstItem).Symbol.Length == 1);
                    Debug.Assert(((SuggestedUnicodeItem)firstItem).Symbol[0] == partial[partial.Length - 1]);

                    if (StartsWith(targetWord.Content, partial, culture))
                    {
                        action = ApplicationRobotAction.CreateSuggestion(index, 0);
                    }
                    else if (!StartsWith(targetWord.Content, partial.Substring(0, partial.Length - 1), culture))
                    {
                        action = GetModeEscape(model);
                    }
                    else if (partial[partial.Length - 1] < targetWord.Content[partial.Length - 1])
                    {
                        // Can just move along.
                    }
                    else
                    {
                        // Need to step back.
                        Debug.Assert(model.SuggestionInterstitials[index] is InterstitialGapItem);
                        action = ApplicationRobotAction.CreateInterstitial(index);
                    }
                }
            }

            if (action == null)
            {
                // Need to step forward.
                action = ApplicationRobotAction.CreateInterstitial(model.SuggestionLists.Count);
            }

            return(action);
        }
예제 #24
0
        /// <summary>
        /// Get the next action to achieve the given goal.
        /// </summary>
        /// <param name="model">The model to act against.</param>
        /// <param name="complete">Finish by presssing a Stop button and returning IsComplete true in the action, otherwise don't press Stop button and return null.</param>
        /// <param name="words">The words to be spoken.</param>
        /// <returns>The next action to take.</returns>
        private static ApplicationRobotAction FindNextAction(ApplicationModel model, bool complete, TileSequence words)
        {
            ApplicationRobotAction action;

            Debug.Assert(model.HeadItems[0] is HeadStartItem);

            var culture = model.HeadItems[0].Culture;

            // Find number of words already correctly entered.
            var wordsMatchLim = 0;

            while (wordsMatchLim < words.Count &&
                   wordsMatchLim + 1 < model.HeadItems.Count &&
                   IsItemMatchExact <HeadWordItem>(model.HeadItems[wordsMatchLim + 1], words[wordsMatchLim], culture))
            {
                wordsMatchLim++;
            }

            if (wordsMatchLim < words.Count &&
                wordsMatchLim + 1 < model.HeadItems.Count &&
                IsItemMatch <HeadWordItem>(model.HeadItems[wordsMatchLim + 1], words[wordsMatchLim], culture))
            {
                if (wordsMatchLim + 2 < model.HeadItems.Count && model.HeadItems[wordsMatchLim + 2] is HeadWordItem)
                {
                    // Make the miscased item the last current item.
                    action = ApplicationRobotAction.CreateHead(wordsMatchLim + 1);
                }
                else
                {
                    var headWordItem = (HeadWordItem)model.HeadItems[wordsMatchLim + 1];
                    action = GetCaseWordAction(model, headWordItem.Tile, words[wordsMatchLim], culture);
                }
            }
            else if (wordsMatchLim + 1 < model.HeadItems.Count &&
                     model.HeadItems[wordsMatchLim + 1] is HeadWordItem)
            {
                // We have a word we don't want, so truncate.
                action = ApplicationRobotAction.CreateHead(wordsMatchLim);
            }
            else if (wordsMatchLim == words.Count)
            {
                // We have all the words in the head we want.
                if (!complete)
                {
                    // We're done.
                    action = null;
                }
                else if (wordsMatchLim + 1 < model.HeadItems.Count &&
                         model.HeadItems[wordsMatchLim + 1] is GhostStopItem)
                {
                    // Click item in head to complete selection.
                    action = ApplicationRobotAction.CreateHeadAndComplete(wordsMatchLim + 1);
                }
                else
                {
                    // Click in tail to complete selection.

                    Debug.Assert(model.HeadItems.Count <= wordsMatchLim + 1 ||
                                 model.HeadItems[wordsMatchLim + 1] is GhostWordItem);
                    Debug.Assert(model.TailItems.Count == 1);
                    Debug.Assert(model.TailItems[0] is TailStopItem);

                    action = ApplicationRobotAction.CreateTailAndComplete(0);
                }
            }
            else
            {
                // See how many ghost items match.
                var ghostMatchLim = wordsMatchLim;
                while (ghostMatchLim < words.Count &&
                       ghostMatchLim + 1 < model.HeadItems.Count &&
                       IsItemMatchExact <GhostWordItem>(model.HeadItems[ghostMatchLim + 1], words[ghostMatchLim], culture))
                {
                    ghostMatchLim++;
                }

                // Have we got enough ghost words to complete?
                if (complete &&
                    ghostMatchLim == words.Count &&
                    ghostMatchLim + 1 < model.HeadItems.Count &&
                    model.HeadItems[ghostMatchLim + 1] is GhostStopItem)
                {
                    // Complete by clicking ghost tail item.
                    action = ApplicationRobotAction.CreateHeadAndComplete(ghostMatchLim + 1);
                }
                else
                {
                    // Click something in the suggestions to advance.
                    action = GetSuggestionsAction(model, complete, words, wordsMatchLim, culture);

                    if (!action.IsComplete && wordsMatchLim < ghostMatchLim)
                    {
                        if (action.Target != ApplicationRobotActionTarget.Suggestion ||
                            action.SubIndex <= ghostMatchLim - wordsMatchLim)
                        {
                            // See if we can snaffle one more ghost.
                            if (ghostMatchLim < words.Count &&
                                ghostMatchLim + 1 < model.HeadItems.Count &&
                                IsItemMatch <GhostWordItem>(model.HeadItems[ghostMatchLim + 1], words[ghostMatchLim], culture))
                            {
                                ghostMatchLim++;
                            }

                            // We would have been no better off than clicking in the ghost words, so do that.
                            action = ApplicationRobotAction.CreateHead(ghostMatchLim);
                        }
                    }
                }
            }

            return(action);
        }
        private static void MultiTest(string sentence, int expectedFirstClicks, int expectedSecondClicks, int expectedEmptyClicks, int expectedClicksWithRandomErrors, [CallerMemberName] string caller = null)
        {
            var words = TileSequence.FromRaw(sentence);

            MultiTest(words, expectedFirstClicks, expectedSecondClicks, expectedEmptyClicks, expectedClicksWithRandomErrors, caller);
        }
예제 #26
0
        public Size DrawTileSequence(Graphics graph, TileSequence tileSequenceToDraw)
        {
            var tileSize = new Size();

            for (int i = 0; i < tileSequenceToDraw.Count; i++)
            {
                var containerState = graph.BeginContainer();

                var paintedTile = this.paintedTiles[tileSequenceToDraw[i].TileId];
                tileSize = new Size(paintedTile.TileTemplate.FrameRectangle.Width, paintedTile.TileTemplate.FrameRectangle.Height);

                graph.TranslateTransform(
                    this.physicalLayout[i].X * tileSize.Width,
                    this.physicalLayout[i].Y * tileSize.Height);

                paintedTile.Rotation = tileSequenceToDraw[i].Rotation;
                paintedTile.DrawTile(graph);

                graph.EndContainer(containerState);
            }

            return new Size(
                tileSize.Width * this.columnCount,
                tileSize.Height * ((int)Math.Floor((double)tileSequenceToDraw.Count / (double)this.columnCount)));
        }