/// <summary> /// Create a puzzle solution out of the Dlx result. /// </summary> /// <param name="rows">The remaining Dlx nodes containing the solution values.</param> private void SolutionFound(IEnumerable <DlxNode> rows) { var size = _puzzleSize.ToInt32(); var newSolution = new Dictionary <PuzzleCoordinate, int>(); foreach (var rowNode in rows) { if (rowNode != null) { var value = rowNode.Coordinate.Row - 1; var digit = value % size + 1; value /= size; var col = value % size; value /= size; var row = value % size; var coord = new PuzzleCoordinate(row, col); newSolution[coord] = digit; } } var solvedPuzzle = new Puzzle(_puzzleSize); foreach (var coord in newSolution.Keys.OrderBy(k => k)) { solvedPuzzle[coord] = Convert.ToByte(newSolution[coord]); } SolutionList.Add(solvedPuzzle); }
public PuzzleCoordinate?FindCellWithFewestPossibilities(Puzzle puzzle, BitArray[,] possibilities) { PuzzleCoordinate?bestIndex = null; var bestScore = -1; for (var row = 0; row < puzzle.Size.ToInt32(); row++) { for (var col = 0; col < puzzle.Size.ToInt32(); col++) { var cellCoord = new PuzzleCoordinate(row, col); var cell = puzzle[cellCoord]; if (!cell.HasValue) { var score = possibilities[row, col].CountSetBits(); if (bestScore < 0 || score < bestScore) { bestIndex = cellCoord; bestScore = score; } } } } return(bestIndex); }
public void SeedThirdBox() { var boxSize = PuzzleGrid.Size.BoxSize(); var size = PuzzleGrid.Size.ToInt32(); for (var row = 0; row < boxSize; row++) { var remainingValues = new BitArray(size, true); // Remove the values used in this row for (var col = 0; col < 2 * boxSize; col++) { var coordinate = new PuzzleCoordinate(row, col); var cellValue = PuzzleGrid[coordinate] ?? throw new Exception($"Cell at {coordinate} is null"); remainingValues[cellValue - 1] = false; } // Set the remaining values in the last boxes row for (var col = 2 * boxSize; col < size; col++) { var value = PickRandomValueFromBitArray(remainingValues); PuzzleGrid[new PuzzleCoordinate(row, col)] = Convert.ToByte(value); remainingValues[value - 1] = false; } } }
/// <summary> /// Ctor /// </summary> /// <param name="coord">The coordinate for this node</param> public DlxNode(PuzzleCoordinate coord) { Coordinate = coord; Header = null; Left = this; Right = this; Up = this; Down = this; }
private void AddRandomGivens(Puzzle puzzle) { var random = new RandomHelper(); var puzzleSize = puzzle.Size.ToInt32(); for (byte n = 1; n <= puzzleSize; n++) { PuzzleCoordinate coordinate; do { var x = random.GetRandomNumber(1, puzzleSize); var y = random.GetRandomNumber(1, puzzleSize); coordinate = new PuzzleCoordinate(x, y); }while (puzzle[coordinate].HasValue); puzzle[coordinate] = n; } }
/// <summary> /// Generates a list of MaximumClueCells clue coordinates. /// </summary> /// <param name="puzzleSolution">A solved puzzle to get the clues from</param> /// <returns></returns> public IEnumerable <PuzzleCoordinateAndValue[]> GenerateRandomClueCoordinates(Puzzle puzzleSolution) { var sourceList = new List <PuzzleCoordinateAndValue>(); var puzzleSize = puzzleSolution.Size.ToInt32(); for (var row = 0; row < puzzleSize; row++) { for (var col = 0; col < puzzleSize; col++) { var coordinate = new PuzzleCoordinate(row, col); var value = puzzleSolution[coordinate]; sourceList.Add(new PuzzleCoordinateAndValue(coordinate, value)); } } // just truncate at half way and app the points and their symmetric counterparts var pairList = new List <PuzzleCoordinateAndValue[]>(); foreach (var cell in sourceList.Take(sourceList.Count / 2).ToList()) { var symRow = puzzleSize - cell.Coordinate.Row - 1; var symCol = puzzleSize - cell.Coordinate.Col - 1; var symCoordinate = new PuzzleCoordinate(symRow, symCol); var symValue = puzzleSolution[symCoordinate]; var symCell = new PuzzleCoordinateAndValue(symCoordinate, symValue); pairList.Add(new[] { cell, symCell }); } // Add center coordinate, if any, as a single if (puzzleSolution.Size.IsOdd()) { var centerCoordinate = puzzleSolution.Size.GetCenterCoordinate(); var centerValue = puzzleSolution[centerCoordinate]; pairList.Add(new[] { new PuzzleCoordinateAndValue(centerCoordinate, centerValue) }); } // return a stack of randomized pairs return(new Stack <PuzzleCoordinateAndValue[]>(pairList .OrderBy(x => Random.GetRandomNumber()))); }