Revert "Removing byte order...
Dev Ghai authored 11 years ago
|
2) using System.Collections.Generic;
3) using System.IO;
4)
5) namespace Boggle
6) {
7) /// <summary>
8) /// Supported lists.
9) /// </summary>
10) public enum BoggleLists
11) {
12) /// <summary>
13) /// Scrabble dictionary for USA, Canada and Thailand
14) /// </summary>
15) TWS,
16)
17) /// <summary>
18) /// Scrabble dictionary used world wide except in USA, Canada and Thailand.
19) /// </summary>
20) //SOWPODS,
21)
22) /// <summary>
23) /// A huge dictionary found on official Internet Scrabble Club's website (http://www.isc.ro/en/commands/lists.html)
24) /// </summary>
25) ZINGARELLI
26) }
27)
28) public class BoggleList
29) {
30) /// <summary>
31) /// Contains a hybrid tree that has been optimized for recursive search.
32) /// </summary>
33) private Dictionary<string, ListWord> _WordList = new Dictionary<string, ListWord>(27); //top level will store only 3 letter words or substrings. Declaring proper size makes insertion operation O(1)
34) public Dictionary<string, ListWord> Wordlist
35) {
36) get
37) {
38) return _WordList;
39) }
40) }
41)
42) /// <summary>
43) /// Contains a list of dictionaries that have been loaded, indexed by enum that contains dictionaries we support.
44) /// </summary>
45) private Dictionary<BoggleLists, Dictionary<string, ListWord>> _LoadedDictionaries;
46)
47) /// <summary>
48) /// Determines if we have an absolute path
49) /// </summary>
50) /// <param name="filePath">File that contains the list SORTED list of words. Path can be relative or absolute.</param>
51) /// <returns>The absolute file path that we can use to access it.</returns>
52) private string GetAbsoluteFilePath(string filePath)
53) {
54) //check if the absolute file path exists.
55) if (!File.Exists(filePath))
56) {
57) //try checking if this is a relative file path and prepend current directory's path.
58) filePath = string.Format("{0}\\{1}", Directory.GetCurrentDirectory(), filePath);
59) if (!File.Exists(filePath))
60) {
61) filePath = string.Empty;
62) }
63) }
64)
65) return filePath;
66) }
67)
68) /// <summary>
69) /// Curates the list for use by this solver. Basically culls out words that do not meet the criteria.
70) /// Criteria: Min_word_length < word_length < Max_word_length. Max_word_length = sideLength^2 + 1.
71) /// </summary>
72) /// <param name="filePath"> Path to file that contains the SORTED list of words.
73) /// It can be relative to current execution directory or absolute.</param>
74) /// <param name="boardSideLength">Length of the side of board in number of tiles.</param>
75) /// <param name="minWordLength">Number of alphabets that can be there in the shortest word on the board.</param>
76) private void CurateList(string filePath, int boardSideLength, int minWordLength)
77) {
78) //filePath = GetAbsoluteFilePath(filePath);
79) //true tells stream reader to auto detect encoding of the file.
80) StreamReader rawList = new StreamReader(filePath, true);
81) //Create a new file. Do not append anything.
82) string curatedFilePath = string.Format("{0}.{1}.{2}", filePath, Constants.CURATED_FILE_SUFFIX, minWordLength.ToString());
83) StreamWriter curatedList = new StreamWriter(curatedFilePath, false);
84)
85) string word;
86) //write out the words whose number of characters are between the shortest and largest provided length.
87) while ((word = rawList.ReadLine()) != null)
88) {
89) if (word.Length >= minWordLength && word.Length <= boardSideLength * boardSideLength + 1)
90) {
91) curatedList.WriteLine(word);
92) }
93) }
94)
95) curatedList.Flush();
96) curatedList.Close();
97) rawList.Close();
98) }
99)
100) public BoggleList()
101) {
102) //Initialize the dictionary containing the lists.
103) _LoadedDictionaries = new Dictionary<BoggleLists, Dictionary<string, ListWord>>(Enum.GetNames(typeof(BoggleLists)).Length);
104) }
105)
106) /// <summary>
107) /// Loads the list depending on the selected dictionary.
108) /// </summary>
109) /// <param name="dict">Type of dictionary to load.</param>
110) /// <param name="boardSideLength"></param>
111) /// <param name="minWordLength"></param>
112) /// <returns>A hybird tree containing the words with each level containing one alphabet (or QU)</returns>
113) public Dictionary<string, ListWord> LoadList(BoggleLists dict, int boardSideLength, int minWordLength, string listRootPath)
114) {
115) if (_LoadedDictionaries.ContainsKey(dict))
116) return _LoadedDictionaries[dict];
117)
118) string filePath = string.Empty;
119)
120) if (NeedsCuration(dict, minWordLength, listRootPath, ref filePath))
121) CurateList(filePath, boardSideLength, minWordLength);
122)
123) _WordList = new Dictionary<string, ListWord>(27);
124)
125) //true tells stream reader to auto detect encoding of the file.
126) StreamReader rawList = new StreamReader(filePath, true);
127) string word, substring;
128) ListWord prevListWord;
129) int startIndex;
|
Revert "Removing byte order...
Dev Ghai authored 11 years ago
|
137) //First deal with the head node and then deal with following letters.
138) startIndex = 0;
139) word = word.ToUpper();
140) substring = word.Substring(0, 1);
141) //if the string starts with Q and there is a 'U' following it, then put QU on tile and increment starting index accordingly.
142) if (substring == "Q" && word[1] == 'U')
143) {
144) substring += "U";
145) startIndex++;
146) }
147)
148) //If there is no space allocated for this letter at root level, allocate some.
149) if (!_WordList.ContainsKey(substring))
150) {
151) _WordList.Add(substring, new ListWord());
152) }
153) prevListWord = _WordList[substring];
154)
155) //fit the word in the tree structure
156) for (int i = startIndex + 1; i < word.Length; i++)
157) {
158) //We are dealing with one letter at each level
159) substring = word.Substring(i, 1);
160) //But if the letter is Q and there is a U following it, then treat this as one letter.
161) if (substring == "Q" && i + 1 < word.Length && word[i + 1] == 'U')
162) {
163) substring += "U";
164) //also increment the index as we have consumed the next letter.
165) i++;
166) }
167) //Has this combination of letters appeared before?
168) if (prevListWord.Next == null)
169) {
170) //if not, then make some space to store this combination
171) prevListWord.Next = new Dictionary<string, ListWord>(27);
172) //and store it.
173) prevListWord.Next.Add(substring, new ListWord());
174) }
175) //if it has,
176) else if (!prevListWord.Next.ContainsKey(substring))
177) {
178) //then just store it.
179) prevListWord.Next.Add(substring, new ListWord());
180) }
181)
182) //Update the dictionary to point to current substring's last character/entry in the tree.
183) prevListWord = prevListWord.Next[substring];
184) }
185) //set the value of the leaf node to be true to point that we have completed the word.
186) prevListWord.IsWord = true;
187) }
188)
189) //Store it in the collection
190) _LoadedDictionaries.Add(dict, _WordList);
191) return _WordList;
|
Removed an old artifact tha...
Dev Ghai authored 11 years ago
|
192) }
193)
194) private void SaveDictToDisk(Dictionary<string, ListWord> hierarchicalDict, string filename)
195) {
196) }
197)
198) private Dictionary<string, ListWord> LoadDictFromDisk(string filename)
199) {
200) }
201)
202) private bool DictExistsOnDisk(string filename)
203) {
204) }
205)
206) private string DictFilenameOnDisk(int boardSideLength, int minWordLength)
207) {
|