public static void Main(string[] args) { Console.WriteLine("Start..."); int rowcount = 9; int columncount = 9; SudokuGrid theGrid = new SudokuGrid(rowcount, columncount); SudokuEngine engine = new SudokuEngine(theGrid); SudokuGrid gameGrid = engine.initializeGrid(theGrid); engine.loadGrid(gameGrid, 0, 2, 4); engine.loadGrid(gameGrid, 0, 5, 7); engine.loadGrid(gameGrid, 0, 6, 5); engine.loadGrid(gameGrid, 0, 7, 1); engine.loadGrid(gameGrid, 1, 2, 7); engine.loadGrid(gameGrid, 1, 4, 4); engine.loadGrid(gameGrid, 1, 7, 9); engine.loadGrid(gameGrid, 1, 8, 8); engine.loadGrid(gameGrid, 2, 1, 6); engine.loadGrid(gameGrid, 2, 3, 1); engine.loadGrid(gameGrid, 2, 5, 9); engine.loadGrid(gameGrid, 3, 0, 4); engine.loadGrid(gameGrid, 3, 3, 9); engine.loadGrid(gameGrid, 3, 4, 3); engine.loadGrid(gameGrid, 3, 8, 5); engine.loadGrid(gameGrid, 4, 0, 9); engine.loadGrid(gameGrid, 4, 1, 7); engine.loadGrid(gameGrid, 4, 7, 6); engine.loadGrid(gameGrid, 4, 8, 3); engine.loadGrid(gameGrid, 5, 0, 1); engine.loadGrid(gameGrid, 5, 4, 7); engine.loadGrid(gameGrid, 5, 5, 2); engine.loadGrid(gameGrid, 5, 8, 4); engine.loadGrid(gameGrid, 6, 3, 2); engine.loadGrid(gameGrid, 6, 5, 3); engine.loadGrid(gameGrid, 6, 7, 5); engine.loadGrid(gameGrid, 7, 0, 6); engine.loadGrid(gameGrid, 7, 1, 5); engine.loadGrid(gameGrid, 7, 4, 9); engine.loadGrid(gameGrid, 7, 6, 7); engine.loadGrid(gameGrid, 8, 1, 2); engine.loadGrid(gameGrid, 8, 2, 1); engine.loadGrid(gameGrid, 8, 3, 7); engine.loadGrid(gameGrid, 8, 6, 6); engine.displaySudokuGrid(gameGrid); Console.WriteLine("...Finish."); }
public override bool Equals(object obj) { SudokuGrid other_grid = obj as SudokuGrid; if (other_grid == null) { return(false); } for (int y = 0; y < 9; y++) { for (int x = 0; x < 9; x++) { if (this._grid_cells[x, y]._value != other_grid._grid_cells[x, y]._value) { return(false); } var firstNotSecond = this._grid_cells[x, y]._possible_values.Except(other_grid._grid_cells[x, y]._possible_values).ToList(); var secondNotFirst = other_grid._grid_cells[x, y]._possible_values.Except(this._grid_cells[x, y]._possible_values).ToList(); if (firstNotSecond.Any() || secondNotFirst.Any() || this._grid_cells[x, y]._possible_values.Count != other_grid._grid_cells[x, y]._possible_values.Count) { return(false); } } } return(true); }
public MainWindow() { MemoryStream iconstream = new MemoryStream(); Properties.Resources.sudokusolver.Save(iconstream); iconstream.Seek(0, SeekOrigin.Begin); this.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconstream); InitializeComponent(); DataContext = new SudokuGrid(); foreach (var square in (DataContext as SudokuGrid).Squares) { TextBox sudokuSquare = new TextBox(); sudokuSquare.DataContext = square; sudokuSquare.SetBinding(TextBox.TextProperty, new Binding("Value") { Converter = new StringToNullableIntConverter(), Mode = BindingMode.TwoWay }); sudokuSquare.Width = 25; sudokuSquare.FontFamily = new System.Windows.Media.FontFamily("Tahoma"); sudokuSquare.FontSize = 14; sudokuGrid.Children.Add(sudokuSquare); sudokuSquare.SetValue(Grid.RowProperty, square.Row); sudokuSquare.SetValue(Grid.ColumnProperty, square.Column); double bottomThickness = (square.Row == 2 || square.Row == 5) ? 2 : 0; double rightThickness = (square.Column == 2 || square.Column == 5) ? 2 : 0; sudokuSquare.Margin = new Thickness(0, 0, rightThickness, bottomThickness); sudokuSquare.SetBinding(TextBox.ToolTipProperty, "PossibleValuesString"); } }
public static SudokuGrid solve_grid(SudokuGrid grid) { _logger.Info("Started solve_grid"); SudokuGrid prev_grid = (SudokuGrid)grid.Clone(); bool grid_changed = true; grid.set_possible_values_of_all_cells(); //grid.display_all_possible_values(); while (!grid.is_grid_solved() && grid_changed) { grid._grid_cells = set_value_for_naked_singles(grid._grid_cells); //Console.WriteLine(grid.ToStringFormatted()); //grid.display_all_possible_values(); // if naked singles didn't change anything, then try the techniques grid_changed = !grid.Equals(prev_grid); if (!grid_changed) { grid = apply_solving_techniques(grid); } grid_changed = !grid.Equals(prev_grid); prev_grid = (SudokuGrid)grid.Clone(); //grid.display_all_possible_values(); //Console.WriteLine($"End of while loop, not solved={!grid.is_grid_solved()} grid changed = {grid_changed}"); } return(grid); }
private TimeSpan runTestCase(testCase test, int count) { TimeSpan sum = TimeSpan.Zero; for (int i = 0; i < count; i++) { currentGrid = new SudokuGrid(); System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); for (int j = 0; j < test.X.Length; j++) { currentGrid.setKnownValue(test.X[j], test.Y[j], test.n[j]); } if (checkBoxAuto.Checked) { timer.Start(); currentGrid.solve(); //TODO: ?call solve after each number to better represent user solve times? Add debug gui Choice? timer.Stop(); } sum += timer.Elapsed; } refreshDisplay(); labelDebugInfo.Text = "Elapsed:" + sum.ToString(); return(sum); }
private void textBoxXY_TextChanged(object sender, EventArgs e) { TextBoxXY curr = (TextBoxXY)sender; if (!curr.handleTextChange) { return; } String text = curr.Text; if (text.Length < 1) //test for text entered //TODO: redo this section with refreshDisplay { if (currentGrid[curr.X, curr.Y] == 0) //no text, no value, nothing to do. { return; } else //not text, but should be a known value { curr.Text = "" + currentGrid[curr.X, curr.Y]; //just reset text. No need to refreshDisplay return; } } //make sure a valid digit was entered. char digit = text[0]; if (!Char.IsDigit(digit) || digit == '0') { curr.Text = ""; //not a digit, delete text. No need to refreshDisplay return; } //see if just setting it to the value it is already known to be if (Char.GetNumericValue(digit) == currentGrid[curr.X, curr.Y]) { curr.Text = "" + currentGrid[curr.X, curr.Y]; //no change, just reset the text. No need to refreshDisplay return; } SudokuGrid undoTemp = new SudokuGrid(currentGrid); //attempt to apply the new digit if (!currentGrid.setKnownValue(curr.X, curr.Y, (int)Char.GetNumericValue(digit))) { curr.Text = ""; //change rejected, clear the text. No need to refreshDisplay return; } undoStack.Push(undoTemp); buttonUndo.Enabled = true; labelDebugInfo.Text = listPossibilities(curr.X, curr.Y); //force update possibilty list for this cell, since this cell has focus //change accepted, check entire grid, if autosolve is on if (checkBoxAuto.Checked) { currentGrid.solve(); } refreshDisplay(); }
private void buttonUndo_Click(object sender, EventArgs e) { currentGrid = undoStack.Pop(); refreshDisplay(); if (undoStack.Count < 1) { buttonUndo.Enabled = false; } }
/// <summary> /// Creates a grid based on an input string, then solves and prints the grid. /// </summary> /// <param name="start">The 81-character string representing the starting grid. Blank spaces are represented by the character '0'.</param> public static void SolveAndPrint(string start) { try { SudokuGrid grid = new SudokuGrid(start); grid.SolveAndPrint(); } catch { Console.WriteLine("Invalid grid: {0}", start); } }
private static IList <SudokuCell> GetDiagonal(SudokuGrid grid, Direction vertical, Direction horizontal) { List <SudokuCell> cellList = new List <SudokuCell>(); for (int i = 0; i < grid.size; i++) { cellList.Add(grid.activeCell); grid.Shift(vertical); grid.Shift(horizontal); } return(cellList); }
private static IList <SudokuCell> GetCells(SudokuGrid grid, Direction dir) { List <SudokuCell> cellList = new List <SudokuCell>(); for (int i = 0; i < grid.size; i++) { // Add and shift the active cell. cellList.Add(grid.activeCell); grid.Shift(dir); } return(cellList); }
public static SudokuGrid apply_solving_techniques(SudokuGrid grid) { grid = set_value_from_instructions(grid, find_hidden_singles(grid._grid_cells), SudokuGrid.tech_hidden_single); grid = narrowing_possible_values_from_instructions(grid, find_pointing_pairs(grid._grid_cells), SudokuGrid.tech_pointing_pair); grid = narrowing_possible_values_from_instructions(grid, find_block_block_interactions(grid._grid_cells), SudokuGrid.tech_block_block); grid = narrowing_possible_values_from_instructions(grid, find_x_y_wing(grid._grid_cells), SudokuGrid.tech_xy_wing); return(grid); }
private void buttonPopSnapshot_Click(object sender, EventArgs e) { currentGrid = new SudokuGrid(snapshotStack.Pop()); refreshDisplay(); if (snapshotStack.Count <= 0) { buttonRestore.Enabled = false; buttonPopSnapshot.Enabled = false; } buttonPopSnapshot.Text = "Pop Snapshot (" + snapshotStack.Count + ")"; }
public Form1() { InitializeComponent(); InitializeComponentDynamic(); currentGrid = new SudokuGrid(); snapshotStack = new Stack <SudokuGrid>(); undoStack = new Stack <SudokuGrid>(); refreshDisplay(); numericUpDown1.Maximum = testCases.Length - 1; }
//public SudokuHelper(ILogger logger) //{ // _logger = logger; //} public static Cell[,] set_value_for_naked_singles(Cell[,] grid) { //Console.WriteLine("set_value_for_naked_singles begin"); CoordinateList singles = SudokuGrid.find_cells_with_a_quantity_of_possible_values(grid, 1, 1); foreach ((int x, int y) in singles) { //Console.WriteLine($" ({x},{y}) to {c._possible_values[0]}"); grid = SudokuGrid.set_cell_value_and_update_possible_values(grid, x, y, grid[x, y]._possible_values[0]); } //Console.WriteLine("set_value_for_naked_singles end"); return(grid); }
public object Clone() { SudokuGrid cloned_grid = new SudokuGrid(""); for (int y = 0; y < 9; y++) { for (int x = 0; x < 9; x++) { cloned_grid._grid_cells[x, y] = (Cell)this._grid_cells[x, y].Clone(); } } return(cloned_grid); }
/// <summary> /// Solves the grids given in input.txt, in the same folder as the executable. /// </summary> /// <param name="args">Parameters. Not used.</param> static void Main(string[] args) { DateTime start = DateTime.Now; string[] grids = System.IO.File.ReadAllLines("input.txt"); foreach (string grid in grids) { SudokuGrid.SolveAndPrint(grid); } Console.WriteLine("Execution took {0} seconds.", DateTime.Now.Subtract(start).TotalSeconds); Console.ReadLine(); }
/// <summary> /// Suspend the visuals of the gamePanel until a board has been generated and is ready to view. /// </summary> /// <param name="size"></param> private void CreateGame(int size, int width, int height) { // Hide the game panel. gamePanel.Visible = false; gamePanel.Controls.Clear(); // Get the flags (settings) for the new game. BlockFlag gameMode = GetFlags(); grid = new SudokuGrid(width, height, size, gameMode); ConnectCells(); // Show the game panel after cells are connected again. gamePanel.ResumeLayout(); gamePanel.Visible = true; }
public void displaySudokuGrid(SudokuGrid sgrid) { Console.WriteLine(); Console.WriteLine(); int delimiterRowCount = 0; for (int r = 0; r < sgrid.Rows; r++) { int delimiterColumnCount = 0; for (int c = 0; c < sgrid.Columns; c++) { delimiterColumnCount += 1; if (delimiterColumnCount > 3) { Console.Write("|"); delimiterColumnCount = 1; } var sCell = (SudokuCell)sgrid.Cells[r, c]; if (sCell.PossibleValues.Count > 1) { Console.Write("*"); continue; } foreach (var value in sCell.PossibleValues) { Console.Write(value); } } Console.WriteLine(); delimiterRowCount += 1; if (r < 7 && delimiterRowCount > 2) { Console.WriteLine("-----------"); delimiterRowCount = 0; } } Console.WriteLine(); Console.WriteLine(); }
public static IList <SudokuCell> GetBox(SudokuCell cell, SudokuGrid grid) { List <SudokuCell> cellList = new List <SudokuCell>(); int x = cell.X; int y = cell.Y; int width = grid.width; int height = grid.height; // Check boxes don't have duplicates. // Ex: go from 5 - (2) to 5 - (2) + 3 for (int i = x - (x % width); i < x - (x % width) + width; i++) { for (int j = y - (y % height); j < y - (y % height) + height; j++) { cellList.Add(grid.cells[i, j]); } } return(cellList); }
/// <summary> /// Copy constructor. Does a deep copy. /// </summary> /// <param name="toCopy">instance to copy</param> public SudokuGrid(SudokuGrid toCopy) { solveGrid = new gridSquare[9, 9]; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { solveGrid[i, j] = new gridSquare(toCopy.solveGrid[i, j]); } } unsolvedValues = new HashSet <int> [3, 9]; //3 types of section (row, col, box), nine of each type for (int i = 0; i < 9; i++) { unsolvedValues[(int)iterateBy.Box, i] = new HashSet <int>(toCopy.unsolvedValues[0, i]); unsolvedValues[(int)iterateBy.Row, i] = new HashSet <int>(toCopy.unsolvedValues[1, i]); unsolvedValues[(int)iterateBy.Col, i] = new HashSet <int>(toCopy.unsolvedValues[2, i]); } }
private void buttonTestCase_Click(object sender, EventArgs e) { int test = (int)numericUpDown1.Value; if (test >= 0) { runTestCase(testCases[test], 1); return; } TimeSpan sum = TimeSpan.Zero; for (int i = 0; i < testCases.Length; i++) { sum += runTestCase(testCases[i], 100); } currentGrid = new SudokuGrid(); refreshDisplay(); labelDebugInfo.Text = "Elapsed:" + sum.ToString(); }
public void TestGridConstructor() { SudokuGrid testGrid = new SudokuGrid(testDimension1, testSymbols1, testPuzzle1); for (int i = 0; i < testDimension1; i++) { SudokuGridComponent row = testGrid.GetRow(i); SudokuGridComponent column = testGrid.GetColumn(i); SudokuGridComponent box = testGrid.GetBox(i); for (int j = 0; j < testDimension1; j++) { Assert.AreEqual(testPuzzle1[i][j * 2], row[j].Value); Assert.AreEqual(testPuzzle1[j][i * 2], column[j].Value); int r = 3 * (i / 3) + (j / 3); int c = ((j % 3) + ((i % 3) * 3)) * 2; Assert.AreEqual(testPuzzle1[r][c], box[j].Value); } } for (int col = 0; col < testDimension1; col++) { SudokuGridComponent column = testGrid.GetRow(col); for (int index = 0; index < testDimension1; index++) { } } SudokuGrid invalidGrid = null; try { invalidGrid = new SudokuGrid(testInvalidDimension, testSymbols1, testPuzzle1); Assert.Fail(); } catch (ArgumentException arg) { Assert.AreEqual("Dimension of the grid must be a perfect square", arg.Message); } Assert.IsNull(invalidGrid); }
private void OutputSudokuToTextBoxes(SudokuGrid inputGrid) { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { textBoxArray[i, j].Text = Convert.ToString(inputGrid.sudokuArray[i, j]); } } }
public static SudokuGrid RecursiveSolve(SudokuGrid gridToSolve) { if (!gridToSolve.IsValid) { return null; } if (gridToSolve.IsComplete) { return gridToSolve; } // So we have a grid that's incomplete and might have solutions, so: var nextPosTuple = gridToSolve.NextPositionToPopulate(); foreach (var possibleEntry in nextPosTuple.Item3) { var sudokuGridToAmend = new char[9, 9]; Array.Copy(gridToSolve.sudokuArray, sudokuGridToAmend, 81); sudokuGridToAmend[nextPosTuple.Item1, nextPosTuple.Item2] = possibleEntry; // Recursion is magic! var newGridToSolve = new SudokuGrid(sudokuGridToAmend); var solvedGrid = RecursiveSolve(newGridToSolve); if (solvedGrid != null) { return solvedGrid; } } // Otherwise the grid we've been given has no solutions, so return null; }
private void buttonSave_Click(object sender, EventArgs e) { savedSudoku = GetSudokuGridFromTextBoxes(); }
private SudokuGrid GetSudokuGridFromTextBoxes() { var formCharArray = new char[9, 9]; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (textBoxArray[i, j].Text == "") { formCharArray[i, j] = ' '; } else { formCharArray[i, j] = textBoxArray[i, j].Text[0]; } } } var mySudokuGrid = new SudokuGrid(formCharArray); return mySudokuGrid; }
public static IList <SudokuCell> BottomLeftToTopRight(SudokuGrid grid) => GetDiagonal(grid, Direction.Up, Direction.Right);
private void buttonReset_Click(object sender, EventArgs e) { currentGrid = new SudokuGrid(); refreshDisplay(); }
/// <summary> /// Get a list of sudoku cells with matching X as activeCell. /// </summary> public static IList <SudokuCell> GetHorizontal(SudokuGrid grid) => GetCells(grid, Direction.Right);
public void TestStaticGridMembers() { int dimension = 9; int firstColumn = 0; int middleColumn = dimension / 2; int LastColumn = dimension - 1; int firstRow = 0; int middleRow = dimension / 2; int lastRow = dimension - 1; Assert.AreEqual(0, SudokuGrid.GetBoxOrder(dimension, firstRow , firstColumn)); Assert.AreEqual(4, SudokuGrid.GetBoxOrder(dimension, middleRow, middleColumn)); Assert.AreEqual(8, SudokuGrid.GetBoxOrder(dimension, lastRow, LastColumn)); Assert.AreEqual(7, SudokuGrid.GetBoxOrder(dimension, lastRow, middleColumn)); Assert.AreEqual(3, SudokuGrid.GetBoxOrder(dimension, middleRow, firstColumn)); SudokuGrid testGrid = new SudokuGrid(testDimension1, testSymbols1, testPuzzle1); int counter = 0; foreach (SudokuCell cell in testGrid) { int compareTo = 3 * ((counter / 9) % 3) + (counter % 9) % 3; Assert.AreEqual(compareTo, SudokuGrid.GetBoxOrder(cell)); counter++; } }
private static SudokuGrid set_value_from_instructions(SudokuGrid grid, HashSet <(int, int, int)> instructions, int setting_method)
/// <summary> /// Get a list of sudoku cells with matching Y as activeCell. /// </summary> public static IList <SudokuCell> GetVertical(SudokuGrid grid) => GetCells(grid, Direction.Down);
public static CoordinateList find_cells_with_a_quantity_of_possible_values(Cell[,] grid, int min_values, int max_values) { return(find_cells_with_a_quantity_of_possible_values(grid, min_values, max_values, SudokuGrid.get_all_coordinates_for_grid())); }
public static IDictionary <SudokuCell, IEnumerable <SudokuCell> > FindNeighbors(SudokuGrid grid, BlockFlag gameMode) { Dictionary <SudokuCell, IEnumerable <SudokuCell> > keyValuePairs = new Dictionary <SudokuCell, IEnumerable <SudokuCell> >(); foreach (var cell in grid.cells) { // Focus on the cell under inspection. grid.activeCell = cell; // Always get horizontal and vertical neighbors. IEnumerable <SudokuCell> region = GetHorizontal(grid).Union(GetVertical(grid)); // Usually get nearby neighbors. if (gameMode.Boxes) { region = region.Union(GetBox(cell, grid)); } if (gameMode.XSudoku) { // Only look at true diagonals in XSudoku. if (grid.activeCell.X + grid.activeCell.Y == grid.size - 1) { region = region.Union(BottomLeftToTopRight(grid)); } if (grid.activeCell.X == grid.activeCell.Y) { region = region.Union(TopLeftToBottomRight(grid)); } } // Add region to dictionary for easy access later. keyValuePairs[cell] = region; } return(keyValuePairs); }
public static IList <SudokuCell> TopLeftToBottomRight(SudokuGrid grid) => GetDiagonal(grid, Direction.Down, Direction.Right);