/// <summary> /// This method fills our Crozzle with words. /// </summary> public void Fill() { foreach (var a in WordList.Table) { Words.Add(a.Key); } TemporaryArray = new char[Rows, Columns]; TemporaryCrozzleWords = new List <Word>(); TemporaryWords = new List <string>(); TemporaryPaddedArray = GetPaddedArray(TemporaryArray); TemporaryWordsAlreadyInCrozzle = new List <string>(); ListOfNodes = new List <Node>(); Random rndm = new Random(); var myfavWords = costSortedAlphabets; var alphabet = myfavWords[0]; TemporaryWords = Words.OrderByDescending(xm => int.Parse(xm.Split(alphabet).Count().ToString())).ToList(); var list = new List <string>(); foreach (string str in Words) { if (str.ToUpper().Contains("Z") || str.ToUpper().Contains("Y") || str.ToUpper().Contains("X") || str.ToUpper().Contains("W") || str.ToUpper().Contains("V")) { TemporaryWords.Add(str); } var indexofZ = FindIndexes(str, 'Z'); if (indexofZ.Count() >= 2) { list.Add(str); } } if (list.Count == 0) { list = TemporaryWords; } bool successful = false; while (successful == false) { int x = rndm.Next(1, Rows); int y = rndm.Next(1, Columns); int index = rndm.Next(0, list.Count - 1); if (TryFitFirstHorizontalWord(x, y, 0, list[index])) { if (TemporaryWordsAlreadyInCrozzle.Contains(list[index]) == false) { Insert(list[index], "Horizontal", x, y); TemporaryCrozzleWords.Add(new Word(list[index], "Horizontal", x, y, false)); TemporaryWords.Remove(list[index]); TemporaryWordsAlreadyInCrozzle.Add(list[index]); if (TemporaryCrozzleWords.Count == Config.MAXIMUM_NUMBER_OF_GROUPS) { successful = true; } } } } if (Config.INTERSECTING_POINTS_PER_LETTER["Z"] == 0) { RootNode = new Node(TemporaryArray, TemporaryCrozzleWords); BestNode = RootNode; InsertChildren(RootNode); if (BestNode.GetScore(Config) > Score) { Array = BestNode.Array; CrozzleWords = BestNode.CrozzleWords; Score = BestNode.Score; } } else { for (int i = 0; i < 10; i++) { DoFillingWork(alphabet); } char fav = 'Z'; if (Config.INTERSECTING_POINTS_PER_LETTER[fav.ToString()] != 0) { for (int i = 0; i < 10; i++) { DoSimpleFilling(); } } int TemporaryArrayScore = GetScore(TemporaryArray); Score = GetScore(Array); if (Score < TemporaryArrayScore) { Array = TemporaryArray; CrozzleWords = TemporaryCrozzleWords.ToList(); Score = TemporaryArrayScore; } } }
/// <summary> /// This method accepts a node and tries to forms its children by inserting new words one at a time. /// This is a recursive depth first built algorithm. The memory impact is very low because local variables are used. /// </summary> /// <param name="node"></param> private void InsertChildren(Node node) { foreach (Word w in node.CrozzleWords) { if (w.IsProcessed == false && w.Type == "Horizontal") { int x = w.Startx; int y = w.Starty; foreach (Char c in costSortedAlphabets) { if (w.Value.Contains(c)) { var allindexes = FindIndexes(w.Value, c); foreach (int index in allindexes) { if (node.CheckIfIntersection(x, y + index) == false) { var listOfIntersections = WordList.GetIntersections(w.Value, c).Except(node.Words).ToList(); foreach (string word in listOfIntersections) { var allIndexesInChosenWord = FindIndexes(word, c); foreach (int chosenindex in allIndexesInChosenWord) { if (node.TryFitVerticalWord(x, y + index, chosenindex, word, Rows, Columns) && TemporaryWordsAlreadyInCrozzle.Contains(word) == false) { node.SubSolutions.Add(new Word(word, "Vertical", x - chosenindex, y + index, false), GetCost(word)); } } } } } } } } } foreach (Word w in node.CrozzleWords) { if (w.IsProcessed == false && w.Type == "Vertical") { int x = w.Startx; int y = w.Starty; foreach (Char c in costSortedAlphabets) { if (w.Value.Contains(c)) { var allindexes = FindIndexes(w.Value, c); foreach (int index in allindexes) { if (node.CheckIfIntersection(x + index, y) == false) { var listOfIntersections = WordList.GetIntersections(w.Value, c).Except(node.Words).ToList(); foreach (string word in listOfIntersections) { var allIndexesInChosenWord = FindIndexes(word, c); foreach (int chosenindex in allIndexesInChosenWord) { if (node.TryFitHorizontalWord(x + index, y, chosenindex, word, Rows, Columns) && TemporaryWordsAlreadyInCrozzle.Contains(word) == false) { node.SubSolutions.Add(new Word(word, "Horizontal", x + index, y - chosenindex, false), GetCost(word)); } } } } } } } } } if (node.SubSolutions.Count == 0) { if (node.GetScore(Config) > BestNode.GetScore(Config)) { BestNode = node.Copy(); BestNode.Score = GetScore(node.Array); } } else { var sorted = node.SubSolutions.OrderByDescending(k => k.Value).ToList(); var first10sorted = sorted.Take(2); foreach (KeyValuePair <Word, Int32> pair in first10sorted) { Node childnode = new Node(); //childnode.SubSolutions = new List<Word>(); childnode.SubSolutions = new Dictionary <Word, int>(); childnode.ListOfChildren = new List <Node>(); childnode.CrozzleWords = node.CrozzleWords.ToList(); childnode.Words = node.Words.ToList(); childnode.PaddedArray = new char[Rows + 2, Columns + 2]; childnode.Array = new char[Rows, Columns]; foreach (Word w in childnode.CrozzleWords) { childnode.Insert(w.Value, w.Type, w.Startx, w.Starty); } childnode.GetPaddedArray(); childnode.Insert(pair.Key.Value, pair.Key.Type, pair.Key.Startx, pair.Key.Starty); //childnode.SubSolutions.Remove(word); childnode.CrozzleWords.Add(pair.Key); childnode.Words.Add(pair.Key.Value); //node.addChild(childnode); InsertChildren(childnode); } } }