public PuzzleGrid InitGrid() { PuzzleGrid tempGrid = new PuzzleGrid { }; int row = 0; int col = 0; int newVal; List <int> valueSet = new List <int>(Enumerable.Range(-9, 9)); List <int> valueSet2 = new List <int>(); Random rnd = new Random(); int randIndex = 0; newVal = valueSet[randIndex]; tempGrid.InitSetCell(row, col, newVal); valueSet.Remove(newVal); for (row = 1; row < 9; row++) { randIndex = rnd.Next(0, valueSet.Count); newVal = valueSet[randIndex]; valueSet2.Add(newVal); valueSet.Remove(newVal); tempGrid.InitSetCell(row, col, newVal); } row = 0; for (col = 1; col < 3; col++) { randIndex = rnd.Next(0, valueSet.Count); newVal = valueSet2[randIndex]; while ((newVal == tempGrid.Grid[1, 0] || (newVal == tempGrid.Grid[2, 0]))) { randIndex = rnd.Next(0, valueSet2.Count); newVal = valueSet2[randIndex]; } valueSet2.Remove(newVal); } for (col = 3; col < 9; col++) { randIndex = rnd.Next(0, valueSet2.Count); newVal = valueSet2[randIndex]; valueSet2.Remove(newVal); tempGrid.InitSetCell(row, col, newVal); } for (col = 3; col < 9; col++) { randIndex = rnd.Next(0, valueSet2.Count); newVal = valueSet2[randIndex]; valueSet2.Remove(newVal); tempGrid.InitSetCell(row, col, newVal); } do { puzzleSolver = new PuzzleSolver(); puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), false); SolutionGrid = puzzleSolver.SolutionGrid; } while (SolutionGrid == null || SolutionGrid.IsBlank()); PermaGrid = Blanker(SolutionGrid); return(PermaGrid); }
public PuzzleGrid Blanker(PuzzleGrid solveGrid) { PuzzleGrid tempGrid; PuzzleGrid saveCopy; bool unique = true; int totalBlanks = 0; int tries = 0; int desiredBlanks; int symmetry = 0; tempGrid = (PuzzleGrid)solveGrid.Clone(); Random rnd = new Random(); switch (difficulty) { case Difficulty.Easy: desiredBlanks = 40; break; case Difficulty.Medium: desiredBlanks = 45; break; case Difficulty.Hard: desiredBlanks = 50; break; default: desiredBlanks = 40; break; } symmetry = rnd.Next(0, 2); do { saveCopy = (PuzzleGrid)tempGrid.Clone(); tempGrid = RandomlyBlank(tempGrid, symmetry, ref totalBlanks); puzzleSolver = new PuzzleSolver(); unique = puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), true); if (!unique) { tempGrid = (PuzzleGrid)saveCopy.Clone(); tries++; } } while ((totalBlanks < desiredBlanks) && (tries < 1000)); solveGrid = tempGrid; solveGrid.Finish(); return(solveGrid); }
/// <summary> /// SolveGrid attempts to solve a puzzle by checking through all /// possible values for each cell, discarding values that do not lead /// to a valid solution. On a try, it recursively calls itself to /// maintain previous states of the grid to back track to if the /// current path fails. It creates a local version of the grid to /// facilitate this. It also checks if the puzzle is uniquely solvable. /// </summary> /// <param name="g">Current state of the grid</param> /// <param name="checkUnique">Do we care if it has unique soln?</param> /// <returns></returns> public bool SolveGrid(PuzzleGrid g, bool checkUnique) { PuzzleGrid grid = new PuzzleGrid(); grid = (PuzzleGrid)g.Clone(); //Copy the input grid int i, choice, r, c, numChoices; bool done, got_one, solved, result; got_one = false; recursions++; FillSingleChoices(grid); //First, fill in all single choice values if (IsSolved(grid)) //If it's already solved { if (numSolns > 0) //If another soln already found { stoplooking = true; //Don't look for more result = false; //Return false, no UNIQUE soln } else //If no other soln found yet { numSolns++; final[numSolns] = (PuzzleGrid)g.Clone(); //Save found soln result = true; SolutionGrid = grid; } } else //If not solved yet { if (!FindFewestChoices(grid, out r, out c, out numChoices)) { result = false; //Invalid solution } else //Current grid still valid { i = 1; done = false; got_one = false; while (!done && i <= numChoices) { choice = PickOneTrue(); //Pick a possible value list[choice] = false; //Won't want to use it again grid.UserSetCell(r, c, choice); if (recursions < MaxDepth) { //-----------We must go deeper. SUDCEPTION!-----------// solved = (SolveGrid(grid, checkUnique)); //Recurse } else { solved = false; } if (stoplooking == true) { done = true; got_one = true; } else { got_one = (got_one || solved); if (!checkUnique) //If not looking for unique soln { done = got_one; //Then we have a solution } } i++; } result = got_one; } } return(result); }