/* * 1. Choosing which pattern to fill (i.e. which variable to solve for). * 2. Picking a suitable word (i.e. which value to select). * 3. Choosing where to backtrack to when we reach an impasse. */ public IEnumerable <ICrossBoard> Generate() { var history = new List <int>(); var historyTrans = new List <List <CrossTransformation> >(); var matchingWords = new List <string>(); var usedWords = new HashSet <string>(); CrossPattern patt = _board.GetMostConstrainedPattern(_dict); while (true) { DoCommands(); if (patt != null) { matchingWords.Clear(); _dict.GetMatch(patt.Pattern, matchingWords); var succTrans = new List <CrossTransformation>(); foreach (string t in matchingWords) { if (usedWords.Contains(t)) { continue; } var trans = patt.TryFill(t, t.AsSpan(), _dict); if (trans != null) { succTrans.Add(trans); trans.Pattern = patt; } } if (succTrans.Count > 0) { succTrans.Sort(new CrossTransformationComparer()); var trans = succTrans[0]; usedWords.Add(trans.Word); trans.Transform(patt); historyTrans.Add(succTrans); history.Add(0); patt = _board.GetMostConstrainedPattern(_dict); } else { patt = BackTrack(history, historyTrans, usedWords); if (patt == null) { yield break; } } } else { yield return(_board.Clone()); patt = BackTrack(history, historyTrans, usedWords); if (patt == null) { yield break; } } } }
/* * 1. Choosing which pattern to fill (i.e. which variable to solve for). * 2. Picking a suitable word (i.e. which value to select). * 3. Choosing where to backtrack to when we reach an impasse. */ public IEnumerable <ICrossBoard> Generate() { var history = new List <int>(); var historyTrans = new List <List <CrossTransformation> >(); var matchingWords = new List <string>(); var usedWords = new HashSet <string>(); CrossPattern pattern = _board.GetMostConstrainedPattern(_dict); Random rnd = new Random(); while (true) { DoCommands(); if (pattern != null) { matchingWords.Clear(); _dict.GetMatch(pattern.Pattern, matchingWords); var succTrans = new List <CrossTransformation>(); foreach (string t in matchingWords) { if (usedWords.Count > 0 && usedWords.Contains(t)) { continue; } // checking if there exist words in the dictionary matching each of the adjacent patterns var trans = pattern.TryFill(t, t.AsSpan(), _dict); if (trans != null) { succTrans.Add(trans); trans.Pattern = pattern; } } if (succTrans.Count > 0) { succTrans.Sort(new CrossTransformationComparer()); // using the successfull transform with most ?! // always use the first index (i.e. the one with the most possible adjacent hits) var trans = succTrans[0]; history.Add(0); // don't always use the "best" match to randomize the crossword better // var lowestIndexToUse = 0; // var highestIndexToUse = succTrans.Count > 10 ? 10 : succTrans.Count; // int index = rnd.Next(lowestIndexToUse, highestIndexToUse); // var trans = succTrans[index]; // history.Add(index); usedWords.Add(trans.Word); trans.Transform(pattern); historyTrans.Add(succTrans); pattern = _board.GetMostConstrainedPattern(_dict); } else { pattern = BackTrack(history, historyTrans, usedWords); if (pattern == null) { yield break; } } } else { yield return(_board.Clone()); pattern = BackTrack(history, historyTrans, usedWords); if (pattern == null) { yield break; } } } }