private void FillSingleChoices(PuzzleGrid grid) { bool anyChanges = false; int numChoices; do { anyChanges = false; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (grid.Grid[i, j] == 0) { numChoices = ListPossible(i, j, grid); if (numChoices == 1) { grid.UserSetCell(i, j, FirstTrue()); anyChanges = (grid.Grid[i, j] != 0); } } } } } while (anyChanges == true && !IsSolved(grid)); }
private bool FindFewestChoices(PuzzleGrid grid, out int r, out int c, out int numChoices) { bool[] minList = new bool[10]; int numCh, minR, minC, minChoice, i, j; bool bad, result; minChoice = 10; minR = 0; minC = 0; for (i = 1; i < 10; i++) { minList[i] = false; } bad = false; i = 0; while (!bad && i < 9) { j = 0; while (!bad && j < 9) { if (grid.Grid[i, j] == 0) { numCh = ListPossible(i, j, grid); if (numCh == 0) { bad = true; } else { if (numCh < minChoice) { minChoice = numCh; list.CopyTo(minList, 0); minR = i; minC = j; } } } j++; } i++; } if (bad || minChoice == 10) //If bad solutn or minChoice never set { result = false; //No fewest possible choices r = 0; c = 0; numChoices = 0; } else { result = true; //Valid cell found, return information to caller r = minR; c = minC; numChoices = minChoice; minList.CopyTo(list, 0); } return(result); }
static void Main(string[] args) { // use File Handler to load save files FileHandler fh = new FileHandler(); string filename = "board.txt"; PuzzleGrid grid; if (File.Exists(filename)) { grid = fh.OpenFile("filename"); } else { grid = new PuzzleGrid(); // fix } do { //File.Open("filename", GameBoard); PrintBoard(grid); Console.ReadKey(); } while (true); // control code: // while the game is not over: // print out the board // let the user type in a row/column and number // change the board // check if they won the game }
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 bool IsPossible(PuzzleGrid g, int row, int col, int value) { bool result; result = (!IsInRow(g, row, value) && !IsInCol(g, col, value) && !IsIn3X3(g, row, col, value)); return(result); }
private bool IsInCol(PuzzleGrid grid, int col, int value) { bool result = false; for (int i = 0; i < 9; i++) { result = result || (Math.Abs(grid.Grid[i, col]) == value); } return(result); }
private bool IsInRow(PuzzleGrid grid, int row, int value) { bool result = false; for (int i = 0; i < 9; i++) { result = result || (Math.Abs(grid.Grid[row, i]) == value); } return(result); }
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> /// This clones the object. /// </summary> /// <returns>A clone of itself.</returns> public object Clone() { //enable cloning for safe copying of the object PuzzleGrid p = new PuzzleGrid(); for (int i = 0; i < Max; i++) { for (int j = 0; j < Max; j++) { p.InitSetCell(i, j, Grid[i, j]); } } return(p); }
static void PrintBoard(PuzzleGrid grid) { int numRows = grid.Grid.GetLength(0); int numColumns = grid.Grid.GetLength(1); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { Console.Write(grid.Grid[i, j]); } Console.WriteLine(); } }
public PuzzleGrid RandomlyBlank(PuzzleGrid tempGrid, int sym, ref int blankCount) { Random rnd = new Random(); int row = rnd.Next(0, 8); int column = rnd.Next(0, 8); while (tempGrid.Grid[row, column] == 0) { row = rnd.Next(0, 8); column = rnd.Next(0, 8); } tempGrid.InitSetCell(row, column, 0); blankCount++; switch (sym) { case 0: if (tempGrid.Grid[row, 8 - column] != 0) { blankCount++; } tempGrid.InitSetCell(row, 8 - column, 0); break; case 1: if (tempGrid.Grid[column, row] != 0) { blankCount++; } tempGrid.InitSetCell(column, row, 0); break; case 2: if (tempGrid.Grid[column, row] != 0) { blankCount++; } tempGrid.InitSetCell(column, row, 0); break; default: if (tempGrid.Grid[row, 8 - column] != 0) { blankCount++; } tempGrid.InitSetCell(column, row, 0); break; } return(tempGrid); }
private bool IsSolved(PuzzleGrid grid) { bool result = true; int r, c; r = 0; while (result == true && r < 9) { c = 0; while (result == true && c < 9) { result = (result && grid.Grid[r, c] != 0); c++; } r++; } return(result); }
/// <summary> /// This function opens a game. /// </summary> public PuzzleGrid OpenFile(String fileName) { PuzzleGrid openedPuzzle = new PuzzleGrid(); int i = 0; //mnemonic: row int j = 0; //mnemonic: column int cellVal = 0; bool eOF = false; using (StreamReader reader = new StreamReader(fileName)) { for (i = 0; i < 9; i++) { string currentLine; if ((currentLine = reader.ReadLine()) != null) { for (j = 0; j < 9; j++) { cellVal = (int)currentLine[2 * j] - '0'; if (currentLine[(2 * j) + 1] == '+') { openedPuzzle.InitSetCell(i, j, cellVal); } else if (currentLine[(2 * j) + 1] == '-') { openedPuzzle.InitSetCell(i, j, -(cellVal)); } } } else { eOF = true; } } } if (eOF) { return(null); } else { return(openedPuzzle); } }
private int ListPossible(int row, int col, PuzzleGrid g) { int count = 0; ClearList(); for (int i = 1; i < 10; i++) { if (IsPossible(g, row, col, i) == true) { list[i] = true; count++; } else { list[i] = false; } } return(count); }
private bool IsIn3X3(PuzzleGrid g, int row, int col, int value) { int rLow; int cLow; rLow = 3 * GroupNum(row); cLow = 3 * GroupNum(col); bool result = false; for (int i = rLow; i < rLow + 3; i++) { for (int j = cLow; j < cLow + 3; j++) { if (Math.Abs(g.Grid[i, j]) == value) { result = true; } } } return(result); }
{/// <summary> /// This function saves a game. /// </summary> public bool SaveFile(PuzzleGrid board, String fileName, bool unsolved = false) { int i = 0; //mnemonic: row int j = 0; //mnemonic: column TextWriter writer = new StreamWriter(fileName); int cellVal; for (i = 0; i < 9; i++) { string currentLine = ""; for (j = 0; j < 9; j++) { cellVal = board.Grid[i, j]; if (cellVal < 0) { currentLine += Math.Abs(cellVal).ToString(); currentLine += "-"; } else { if (unsolved) { currentLine += "0"; } else { currentLine += cellVal.ToString(); } currentLine += "+"; } } writer.WriteLine(currentLine); } writer.Close(); return(true); }
/// <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); }