/// <summary> /// Adds the current word to the puzzle /// </summary> /// <param name="word"></param> void Add(Words word) { int indexX = word.StartIndex / 10; int indexY = word.StartIndex % 10; int currentWordLength = word.Word.Length; int direction = word.Direction; int count = 0; while (count < currentWordLength) { Puzzle[indexX, indexY] = word.Word.Substring(count, 1).ToCharArray()[0]; indexX += lookupX[direction]; indexY += lookupY[direction]; count++; } }
/// <summary> /// Save the current puzzle state /// </summary> /// <param name="word"></param> /// <returns>PuzzleState</returns> PuzzleState SaveState(Words word) { StringBuilder overlaps = new StringBuilder(); int count = 0; int indexX = word.StartIndex / 10; int indexY = word.StartIndex % 10; while (count < word.Word.Length) { if (overlaps.Length > 0) overlaps.Append(","); if (!Puzzle[indexX, indexY].Equals(' ')) { overlaps.Append(indexX).Append(indexY); } indexX += lookupX[word.Direction]; indexY += lookupY[word.Direction]; count++; } return new PuzzleState(word.StartIndex, word.Direction, word.Word.Length, overlaps.ToString()); }
/// <summary> /// Checks if the word can be arranged in the grid /// </summary> /// <param name="word"></param> /// <returns>bool</returns> bool isArrangable(Words word) { if (word == null) return true; PuzzleState currentState; string options = string.Empty; if (!string.IsNullOrEmpty(word.Options)) options = word.Options; else if (word.StartIndex == -1) options = FindAvaiableOptions(word); if (!string.IsNullOrEmpty(options)) { WordList[WordList.IndexOf(word)] = word = Initialize(word, options); currentState = SaveState(word); Add(word); if (isArrangable(FindNextWord())) return true; else { RetractState(currentState); if (isArrangable(word)) return true; else return false; } } return false; }
/// <summary> /// Initialize the word list /// </summary> void InitializeWordList() { WordList = new List<Words>(); Words currentWord; if (Dictionary == null) Dictionary = ReadDictionary(); int index = r.Next(0, Dictionary.Count); for (int i = 0; i < 10; i++) { currentWord = new Words(Dictionary[index % 15].Word, Dictionary[index % 15].Meaning); WordList.Add(currentWord); index += 2; } }
/// <summary> /// Set the index and direction of the word /// </summary> /// <param name="word"></param> /// <param name="options"></param> /// <returns>Words</returns> Words Initialize(Words word, string options) { int startIndex = -1; int direction = -1; int endIndex = -1; if (!string.IsNullOrEmpty(options)) { string[] optionArray = options.Split('|'); int currentOptionIndex = r.Next(optionArray.Length); string currentOption = optionArray[currentOptionIndex]; StringBuilder o = new StringBuilder(); int oIndex = options.IndexOf(currentOption); int oLength = currentOption.Length; string i = currentOption.Split(',')[0]; string d = currentOption.Split(',')[1]; string dir = d.Substring(r.Next(d.Length), 1); if (d.Length > 1) { d = d.Replace(dir, ""); options = options.Replace(currentOption, i + "," + d); } else { for (int c = 0; c < optionArray.Length; c++) { if (c == currentOptionIndex) continue; if (o.Length > 0) o.Append("|"); o.Append(optionArray[c]); } options = o.ToString(); } startIndex = Convert.ToInt32(i); direction = Convert.ToInt32(dir); endIndex = Convert.ToInt32((startIndex / 10 + lookupX[direction] * (word.Word.Length - 1)).ToString() + (startIndex % 10 + lookupY[direction] * (word.Word.Length - 1)).ToString()); } word.Direction = direction; word.StartIndex = startIndex; word.EndIndex = endIndex; word.Options = options; return word; }
/// <summary> /// Finds existing start indices or directions for a word /// </summary> /// <param name="currentWord"></param> /// <returns>string</returns> string FindAvaiableOptions(Words currentWord) { int randomDirection, wordCounter, xIndex, yIndex; bool isFit; StringBuilder options = new StringBuilder(); StringBuilder direction; for (int x = 0; x < 10; x++) { for (int y = 0; y < 10; y++) { direction = new StringBuilder(); randomDirection = 0; while (randomDirection < 8) { if (x + currentWord.Word.Length * lookupX[randomDirection] >= -1 && x + currentWord.Word.Length * lookupX[randomDirection] <= 10 && y + currentWord.Word.Length * lookupY[randomDirection] >= -1 && y + currentWord.Word.Length * lookupY[randomDirection] <= 10) { xIndex = x; yIndex = y; wordCounter = 0; isFit = true; while (wordCounter < currentWord.Word.Length) { if (Puzzle[xIndex, yIndex].Equals(' ') || Puzzle[xIndex, yIndex].Equals(currentWord.Word.Substring(wordCounter, 1))) { xIndex += lookupX[randomDirection]; yIndex += lookupY[randomDirection]; } else { isFit = false; break; } wordCounter++; } } else isFit = false; if (isFit) direction.Append(randomDirection); randomDirection++; } if (direction.Length > 0) { if (options.Length > 0) options.Append("|"); options.Append(x).Append(y).Append(",").Append(direction); } } } return options.ToString(); }