public static SudokuPuzzle generatePuzzle(int size) { SudokuPuzzle puzzle = new SudokuPuzzle(size); var rand = new Random(); while (true) { int[] UnsolvedCellIndexes = puzzle.Cells .Select((cands, index) => new { cands, index }) //Project to a new sequence of candidates and index (an anonymous type behaving like a tuple) .Where(t => t.cands.Length >= 2) //Filter to cells with at least 2 candidates .Select(u => u.index) //Project the tuple to only the index .ToArray(); int cellIndex = UnsolvedCellIndexes[rand.Next(UnsolvedCellIndexes.Length)]; int candidateValue = puzzle.Cells[cellIndex][rand.Next(puzzle.Cells[cellIndex].Length)]; SudokuPuzzle workingPuzzle = puzzle.PlaceValue(cellIndex, candidateValue); if (workingPuzzle != null) { var Solutions = MultiSolve(workingPuzzle, 2); switch (Solutions.Count) { case 0: continue; case 1: return(Solutions.Single()); default: puzzle = workingPuzzle; break; } } } }
public static List <SudokuPuzzle> MultiSolve(SudokuPuzzle input, int MaximumSolutions = -1) { var Solutions = new List <SudokuPuzzle>(); input.Solve(p => { Solutions.Add(p); return(Solutions.Count() < MaximumSolutions || MaximumSolutions == -1); }); return(Solutions); }
public virtual object Clone() { var clone = new SudokuPuzzle(this.Length); clone.Cells = new int[this.Cells.Length][]; for (int i = 0; i < this.Cells.Length; i++) { clone.Cells[i] = new int[this.Cells[i].Length]; Buffer.BlockCopy(this.Cells[i], 0, clone.Cells[i], 0, Buffer.ByteLength(this.Cells[i])); } return(clone); }
public static List <int> FindSingularizedCells(SudokuPuzzle puzzle1, SudokuPuzzle puzzle2, int cellIndex) { Debug.Assert(puzzle1.Length == puzzle2.Length); var result = new List <int>(); foreach (int i in puzzle1.Peers(cellIndex)) { if (puzzle1.Cells[i].Length > 1 && puzzle2.Cells[i].Length == 1) { result.Add(i); } } return(result); }
private void generateButton_Click(object sender, EventArgs e) { generateButton.IsAccessible = false; String origText = generateButton.Text; generateButton.Text = "Getting your sudoku, stay put"; Sudoku.DifficultyLevel diffLevel = (Sudoku.DifficultyLevel)diffLevelComboBox.SelectedValue; SudokuPuzzle generator = SudokuPuzzle.generatePuzzle(9); sudoku = generator.getSudoku(diffLevel); solvedSudoku = generator.getSudoku(Sudoku.DifficultyLevel.None); sudokuBoardViewController.updateBoardView(sudoku); generateButton.IsAccessible = true; generateButton.Text = origText; }
public static int[] CreateClues(SudokuPuzzle input, int maxClues = 0) { //Get a unique solution for the input puzzle, in case it wasn't already var puzzle = input.Solve(); if (puzzle == null) { throw new ArgumentException("Can't create clues from an unsolvable puzzle!"); } //This is the list of clues we work on. It can be reconstituted into a new puzzle object by way of a constructor int[] Clues = puzzle.Cells.Select(c => c[0]).ToArray(); var rand = new Random(); while (true) { //Pick a random cell to blank int ClueCell = rand.Next(Clues.Length); if (Clues[ClueCell] == 0) { continue; } var workingClues = Clues.ToArray(); workingClues[ClueCell] = 0; if (MultiSolve(new SudokuPuzzle(workingClues), 2).Count() > 1) { if (maxClues == 0) { return(Clues); } else { continue; } } Clues = workingClues; if (Clues.Count(c => c != 0) <= maxClues) { return(Clues); } } }
public virtual SudokuPuzzle ApplyConstraints(int cellIndex, int value) { SudokuPuzzle puzzle = (SudokuPuzzle)this.Clone(); //Standard Sudoku constraint logic: Set this cell to one and only one candidate, and remove this value from the candidate list of all its peers puzzle.Cells[cellIndex] = new int[] { value }; foreach (int peerIndex in puzzle.Peers(cellIndex)) { var newPeers = puzzle.Cells[peerIndex].Except(new int[] { value }).ToArray(); if (!newPeers.Any()) { return(null); } puzzle.Cells[peerIndex] = newPeers; } return(puzzle); }
public static void Output(SudokuPuzzle puzzle) { System.Console.Write(puzzle.ToString()); }