// To make things fast, I should break down all the words in the dictionary in sequence of letters, as an indication there is a word I want, for example:
        // each entry should tellme whether there is a word that ends at that entry and whether there are subwords
        // if the dictionary contains the word: bread, then I need the following:
        //	entry	| IsWord	| HasChildren
        //	b		  n			  y
        //	br		  n			  y
        //	bre		  n			  y
        //	brea	  n			  y
        //	bread	  y			  y

        // if the dictionary contains bread and bred then:
        //	entry	| IsWord	| HasChildren
        //	b		  n			  y
        //	br		  n			  y
        //	bre		  n			  y
        //	brea	  n			  y
        //	bred	  y			  y
        //	bread	  y			  y
        public static DictionaryLookupInfo BuildLookupInfo(Dictionary dictionary)
        {
            DictionaryLookupInfo result = new DictionaryLookupInfo();

            foreach (string w in dictionary.Words)
            {
                // only words MinWordLength char or more.
                if (w.Length < dictionary.MinWordLength)
                {
                    continue;
                }

                StringBuilder sb = new StringBuilder();

                for (int i = 0; i < w.Length; i++)
                {
                    sb.Append(w[i]);

                    WordLookupInfoData id  = new WordLookupInfoData();
                    string             key = sb.ToString();
                    if (result.LookupInfo.ContainsKey(key))
                    {
                        id = result.LookupInfo[key];
                    }

                    id.IsWord      |= (i == (w.Length - 1));
                    id.HasChildren |= (i < (w.Length - 1));

                    result.LookupInfo[key] = id;
                }
            }

            return(result);
        }
Exemple #2
0
        // main function: depth first search in the board, using the lookup map and a temp string
        private static List <string> FindWordsFromCell(GameBoard board, DictionaryLookupInfo lookup, int i, int j, bool[,] boardVisitedInfo, StringBuilder tempword)
        {
            List <string> result = new List <string>();

            // we need to look if the char concatenated with the optional string in the recursive call has an entry.
            char cellChar = board.Board[i, j];

            tempword.Append(cellChar);
            string tempwordstring = tempword.ToString();

            // if the word is in the lookup map
            if (lookup.LookupInfo.ContainsKey(tempwordstring))
            {
                WordLookupInfoData map_entry = lookup.LookupInfo[tempwordstring];

                // if so, if it is a word, add it to the colletion.
                if (map_entry.IsWord)
                {
                    // we have found a word!
                    result.Add(tempwordstring);
                }

                // if it has possible children
                if (map_entry.HasChildren)
                {
                    // mark the cell as used.
                    boardVisitedInfo[i, j] = true;

                    // for all the non marked children
                    foreach (var neigh in board.Neighbors[i, j])
                    {
                        if (!boardVisitedInfo[neigh.Item1, neigh.Item2])
                        {
                            // recursion call
                            result.AddRange(FindWordsFromCell(board, lookup, neigh.Item1, neigh.Item2, boardVisitedInfo, tempword));
                        }
                    }
                    // unmark the current cell
                    boardVisitedInfo[i, j] = false;
                }
            }

            // backtrack the temp string
            tempword.Remove(tempword.Length - 1, 1);
            return(result);
        }
Exemple #3
0
        // Note: it will return words in lower case, as input is normalized to be lower case
        static public HashSet <string> FindWords(GameBoard board, Dictionary dictionary)
        {
            HashSet <string> result = new HashSet <string>();

            // fill up the map with the info in the dictionary
            DictionaryLookupInfo lookup = DictionaryLookupInfo.BuildLookupInfo(dictionary);

            // for each cell in the board
            for (int i = 0; i < board.Size; i++)
            {
                for (int j = 0; j < board.Size; j++)
                {
                    bool[,] boardVisitedInfo = InitVisitedInfo(board.Size);
                    result.UnionWith(FindWordsFromCell(board, lookup, i, j, boardVisitedInfo, new StringBuilder()));
                }
            }

            return(result);
        }