private bool WordWillFit(WordSolution solution, PuzzleBoard board, PuzzlePoint directionOffsets, int x, int y) { var rc = true; // We may be finding another placement ... solution.Points.Clear(); for (int position = 0; position < solution.Word.Length; position++) { var thisChar = solution.Word[position].ToString(); var currX = x + (position * directionOffsets.X); var currY = y + (position * directionOffsets.Y); if (currX < 0 || currX > (board.Width - 1) || currY < 0 || currY > (board.Height - 1)) { rc = false; break; // outside the bounds of the grid } // First chance - target cell is empty; Second chance - target cell contains the letter if (board.Letters[currY, currX] != null && board.Letters[currY, currX] != thisChar) { rc = false; break; // won't fit } // Looks like it will fit so far - add Point ... solution.Points.Add(new PuzzlePoint(currX, currY)); } // Verify there is no overlay inside another word placement if (rc) { rc = !board.Solutions.Any( s => s != null && solution.Word.Length <= s.Word.Length && solution.Points.Intersect(s.Points).SequenceEqual(solution.Points) ); } return(rc); }
private WordSolution PlaceWord(PuzzleBoard board, string word, bool verbose) { if (verbose) { Logger.LogDebug($"Placing word={word}"); } var rc = new WordSolution { Word = word, Placed = false, WordSlope = WordSlope.S, Origin = new PuzzlePoint(), Points = new List <PuzzlePoint>() }; var tries = 0; for (; tries < MaxTries; tries++) { var x = board.Width.Random(); var y = board.Height.Random(); // Is the first cell a probable match if (board.Letters[y, x] == null || board.Letters[y, x] == word[0].ToString()) { // Iterate over directions in random order var dirIdxs = Enumerable.Range(0, Directions.Length).ToArray(); dirIdxs.Shuffle(); foreach (var idx in dirIdxs) { // get the selected direction deltas var wordSlope = Directions[idx]; var dirOffsets = DirectionOffsets[wordSlope]; // Make sure the cells for word are empty, contain matching char // and are not contained inside another solution if (WordWillFit(rc, board, dirOffsets, x, y)) { WordCopyToBoard(word, board, dirOffsets, x, y); if (verbose) { Logger.LogDebug($"{word} was placed @ ({x},{y}) via {wordSlope} for puzzle={board.Puzzle.Id} in {tries} tries"); } rc.Placed = true; rc.WordSlope = wordSlope; rc.Origin = new PuzzlePoint(x, y); return(rc); } } } } if (verbose) { Logger.LogDebug($"{word} was not placed in {tries} tries"); } return(rc); }