public List <List <WordPathNode> > FindWords() { var results = new List <List <WordPathNode> >(); var visitorTracker = new HashSet <int>(); var foundWords = new HashSet <DigitalTreeNode>(); for (int row = 0; row < BoggleBoard.RowCount; row++) { for (int col = 0; col < BoggleBoard.ColumnCount; col++) { var currChar = BoggleBoard.GetCharacter(row, col); if (!WordDictionary.RootTreeNode.NextNodes.ContainsKey(currChar)) { continue; } var startPath = new List <WordPathNode>(); startPath.Add(new WordPathNode(row, col, currChar)); visitorTracker.Add(GetIndex(row, col)); // Find all the words that start with this letter FindWords(row, col, results, WordDictionary.RootTreeNode.NextNodes[currChar], startPath, visitorTracker, foundWords); visitorTracker.Remove(GetIndex(row, col)); } } return(results); }
public List <List <WordPathNode> > FindWords(int currRow, int currCol, List <List <WordPathNode> > results, DigitalTreeNode currNode, List <WordPathNode> currPath, HashSet <int> visitorTracker, HashSet <DigitalTreeNode> foundWords) { if (currNode.IsCompleteWord && !foundWords.Contains(currNode)) { if (currPath.Count >= MinimumWordLength) { AddPathToList(results, currPath); } // Keep track of found words so we don't add duplicates foundWords.Add(currNode); } foreach (int nextIndex in GetNeighbors(currRow, currCol)) { if (visitorTracker.Contains(nextIndex)) { continue; // We've already visited this node } int nextRow = GetRow(nextIndex); int nextCol = GetColumn(nextIndex); char nextChar = BoggleBoard.GetCharacter(nextRow, nextCol); DigitalTreeNode nextNode = null; if (!currNode.NextNodes.ContainsKey(nextChar)) { continue; } nextNode = currNode.NextNodes[nextChar]; // TODO: Account for the "U" that follows "Q" on the "QU" dices currPath.Add(new WordPathNode(nextRow, nextCol, nextChar)); visitorTracker.Add(nextIndex); // Recurse into neighbors with viable prefixes FindWords(GetRow(nextIndex), GetColumn(nextIndex), results, nextNode, currPath, visitorTracker, foundWords); visitorTracker.Remove(nextIndex); currPath.RemoveAt(currPath.Count - 1); } return(results); }
static void Main(string[] args) { var wordDictionary = new WordDictionary(); wordDictionary.LoadWords(Assembly.GetExecutingAssembly().GetManifestResourceStream("App.Problems.BoggleWords.Dictionary.txt")); // Have fun with it and try different board sizes var boggleBoard = new BoggleBoard(4, 4); boggleBoard.Print(); Console.WriteLine(); var finder = new BoggleWordFinder(boggleBoard, wordDictionary); var results = finder.FindWords(); Console.WriteLine("Found {0} words", results.Count); Console.WriteLine(); int index = 1; foreach (var pathList in results) { Console.Write("Word {0} : ", index++); foreach (var wordPathNode in pathList) { Console.Write(wordPathNode.Character); } Console.Write(" "); foreach (var wordPathNode in pathList) { Console.Write("({0}, {1}) = {2} ", wordPathNode.Row, wordPathNode.Column, wordPathNode.Character); } Console.WriteLine(); } }
public BoggleWordFinder(BoggleBoard boggleBoard, WordDictionary wordDictionary) { BoggleBoard = boggleBoard; WordDictionary = wordDictionary; MinimumWordLength = 3; }