// CONSTRUCTORS internal SudokuCell(SudokuPuzzle puzzle, int number) { this.Number = number; this.IsEditable = false; this.HasError = false; this.puzzle = puzzle; }
public void LockedCandidatesClaimingTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Intersection_Removal { 0, 1, 6, 0, 0, 7, 8, 0, 3 }, { 0, 9, 0, 8, 0, 0, 0, 0, 0 }, { 8, 7, 0, 0, 0, 1, 2, 6, 0 }, { 0, 4, 8, 0, 0, 0, 3, 0, 0 }, { 6, 5, 0, 0, 0, 9, 0, 8, 2 }, { 0, 3, 9, 0, 0, 0, 6, 5, 0 }, { 0, 6, 0, 9, 0, 0, 0, 2, 0 }, { 0, 8, 0, 0, 0, 2, 9, 3, 6 }, { 9, 2, 4, 6, 0, 0, 5, 1, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 4].CanBe, 2); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 3].CanBe, 2); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 4].CanBe, 2); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 6].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 8].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 6].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 8].CanBe, 4); }
private void Load_OnClick(object sender, RoutedEventArgs e) { SudokuPuzzle puzzle = null; try { using (FileStream fs = new FileStream(JsonPath.Text, FileMode.Open)) { using (StreamReader sr = new StreamReader(fs)) { string json = sr.ReadToEnd(); puzzle = JsonConvert.DeserializeObject <SudokuPuzzle>(json); } } } catch (Exception) { MessageBox.Show("Error while opening json"); } if (puzzle != null) { BoardView.Puzzle = puzzle; } }
public void SingleInCellsTest1() { var sudoku = new[, ] { { 0, 0, 0, 0, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 2, 0 }, { 0, 0, 0, 0, 0, 0, 0, 3, 0 }, { 0, 0, 0, 0, 0, 0, 0, 4, 0 }, { 0, 0, 0, 0, 0, 0, 0, 5, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 2, 3, 0, 5, 6, 8, 7, 9 }, { 4, 5, 9, 0, 0, 0, 0, 8, 0 }, { 6, 0, 8, 0, 0, 0, 0, 9, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); // SingleInRow Assert.That(sudokuPuzzle.Cells[6, 3].Value, Is.EqualTo(4)); // SingleInColumn Assert.That(sudokuPuzzle.Cells[5, 7].Value, Is.EqualTo(6)); // SingleInBlock Assert.That(sudokuPuzzle.Cells[8, 1].Value, Is.EqualTo(7)); }
public void NakedQuadTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Naked_Candidates // Contains one naked quad in block, and after that, one naked quad in row { 0, 0, 0, 0, 3, 0, 0, 8, 6 }, { 0, 0, 0, 0, 2, 0, 0, 4, 0 }, { 0, 9, 0, 0, 7, 8, 5, 2, 0 }, { 3, 7, 1, 8, 5, 6, 2, 9, 4 }, { 9, 0, 0, 1, 4, 2, 3, 7, 5 }, { 4, 0, 0, 3, 9, 7, 6, 1, 8 }, { 2, 0, 0, 7, 0, 3, 8, 5, 9 }, { 0, 3, 9, 2, 0, 5, 4, 6, 7 }, { 7, 0, 0, 9, 0, 4, 1, 3, 2 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 1].CanBe, 1); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 1].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 2].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 8); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 2].CanBe, 6); }
public void NakedQuadTest2() { var sudoku = new[, ] { // From: http://www.manifestmaster.com/jetsudoku/nakedQuad.html // Naked quad in column - must first use LockedCandidatesPointing to eliminate some candidates { 0, 0, 0, 0, 9, 0, 0, 0, 0 }, { 0, 0, 0, 0, 3, 1, 6, 0, 0 }, { 0, 0, 0, 0, 4, 8, 0, 9, 0 }, { 7, 1, 9, 8, 6, 3, 4, 5, 2 }, { 6, 0, 0, 0, 7, 0, 0, 3, 0 }, { 2, 0, 0, 0, 1, 0, 7, 6, 0 }, { 1, 0, 0, 0, 2, 0, 0, 8, 6 }, { 8, 6, 0, 0, 5, 9, 2, 0, 0 }, { 0, 0, 0, 1, 8, 6, 0, 4, 5 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, new LockedCandidatesPointing()); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 2].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 2].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 2].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 2].CanBe, 8); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 8); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 2].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 2].CanBe, 5); }
public SingleStepSolution SolveSingleStep(SudokuPuzzle sudokuPuzzle) { var cellCandidatePairsPerRow = new List <Tuple <Cell, int> >(); var cellCandidatePairsPerColumn = new List <Tuple <Cell, int> >(); foreach (var row in sudokuPuzzle.Rows) { cellCandidatePairsPerRow.AddRange(GetCellCandidatePairsWhichAppearOnlyInSingleBlock( row.Cells, x => x.ColumnIndex)); } foreach (var column in sudokuPuzzle.Columns) { cellCandidatePairsPerColumn.AddRange(GetCellCandidatePairsWhichAppearOnlyInSingleBlock( column.Cells, x => x.RowIndex)); } var eliminations = new List <SingleStepSolution.Candidate>(); eliminations.AddRange(GetEliminations(cellCandidatePairsPerRow, true, sudokuPuzzle)); eliminations.AddRange(GetEliminations(cellCandidatePairsPerColumn, false, sudokuPuzzle)); return(eliminations.Count > 0 ? new SingleStepSolution(eliminations.Distinct().ToArray(), StrategyName) : null); }
private IEnumerable <SingleStepSolution.Candidate> GetEliminations( IEnumerable <Tuple <Cell, int> > cellCandidatePairs, bool perRow, SudokuPuzzle sudokuPuzzle) { var eliminations = new List <SingleStepSolution.Candidate>(); foreach (var cellCandidatePair in cellCandidatePairs) { var cell = cellCandidatePair.Item1; var candidate = cellCandidatePair.Item2; var blockIndex = sudokuPuzzle.GetBlockIndex(cell); var block = sudokuPuzzle.Blocks[blockIndex.RowIndex, blockIndex.ColumnIndex]; foreach (var blockCell in block.Cells) { // Ignore the same cell, or block cells that do not contain candidate if (blockCell == cell || !blockCell.CanBe.Contains(candidate)) { continue; } // If outside cells are part of the same row, // ignore block cells that are part of that same row (similar for columns) if ((perRow && cell.RowIndex == blockCell.RowIndex) || (!perRow && cell.ColumnIndex == blockCell.ColumnIndex)) { continue; } eliminations.Add(new SingleStepSolution.Candidate( blockCell.RowIndex, blockCell.ColumnIndex, candidate)); } } return(eliminations); }
public void LockedCandidatesPointingTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Intersection_Removal { 0, 1, 7, 9, 0, 3, 6, 0, 0 }, { 0, 0, 0, 0, 8, 0, 0, 0, 0 }, { 9, 0, 0, 0, 0, 0, 5, 0, 7 }, { 0, 7, 2, 0, 1, 0, 4, 3, 0 }, { 0, 0, 0, 4, 0, 2, 0, 7, 0 }, { 0, 6, 4, 3, 7, 0, 2, 5, 0 }, { 7, 0, 1, 0, 0, 0, 0, 6, 5 }, { 0, 0, 0, 0, 3, 0, 0, 0, 0 }, { 0, 0, 5, 6, 0, 1, 7, 2, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); // must first use NakedQuad to eliminate some candidates SolveUsingStrategy(sudokuPuzzle, new NakedQuad()); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 0].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 1].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 2].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 1].CanBe, 2); }
public void LockedCandidatesClaimingTest2() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Intersection_Removal { 0, 2, 0, 9, 4, 3, 7, 1, 5 }, { 9, 0, 4, 0, 0, 0, 6, 0, 0 }, { 7, 5, 0, 0, 0, 0, 0, 4, 0 }, { 5, 0, 0, 4, 8, 0, 0, 0, 0 }, { 2, 0, 0, 0, 0, 0, 4, 5, 3 }, { 4, 0, 0, 3, 5, 2, 0, 0, 0 }, { 0, 4, 2, 0, 0, 0, 0, 8, 1 }, { 0, 0, 5, 0, 0, 4, 2, 6, 0 }, { 0, 9, 0, 2, 0, 8, 5, 0, 4 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[3, 2].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 2].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[5, 2].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 1].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[8, 2].CanBe, 3); }
public ISudokuPuzzle Generate(SudokuDifficulty config, int?seed = null) { if (seed == null) { seed = new Random().Next(); } SudokuPuzzle puzzle = new SudokuPuzzle((int)seed); m_AvailableNumbers.Clear(); int i = 0; while (i < 81) { if (!TryGetNextNumber(i, (int)seed, out int val)) { puzzle.Cells[i].Value = 0; i--; continue; } puzzle.Cells[i].Value = val; if (m_Validator.ValidateSudoku(puzzle)) { i++; } } AdjustPuzzleToConfig(puzzle, config, (int)seed); return(puzzle); }
public void AssertCanSolvePuzzle003() { SudokuPuzzle puzzle = SudokuFactory.Create(new[, ] { { 0, 0, 0, 7, 1, 6, 0, 0, 0 }, { 6, 0, 0, 9, 0, 2, 0, 0, 7 }, { 0, 0, 8, 0, 0, 0, 9, 0, 0 }, { 2, 0, 1, 0, 0, 0, 5, 0, 6 }, { 0, 8, 0, 0, 0, 0, 0, 1, 0 }, { 4, 0, 5, 0, 0, 0, 8, 0, 2 }, { 0, 0, 3, 0, 0, 0, 1, 0, 0 }, { 1, 0, 0, 4, 0, 9, 0, 0, 3 }, { 0, 0, 0, 1, 3, 5, 0, 0, 0 }, }); SudokuPuzzle solution = SudokuFactory.Create(new[, ] { { 5, 3, 9, 7, 1, 6, 2, 4, 8 }, { 6, 1, 4, 9, 8, 2, 3, 5, 7 }, { 7, 2, 8, 5, 4, 3, 9, 6, 1 }, { 2, 7, 1, 8, 9, 4, 5, 3, 6 }, { 3, 8, 6, 2, 5, 7, 4, 1, 9 }, { 4, 9, 5, 3, 6, 1, 8, 7, 2 }, { 9, 4, 3, 6, 7, 8, 1, 2, 5 }, { 1, 5, 7, 4, 2, 9, 6, 8, 3 }, { 8, 6, 2, 1, 3, 5, 7, 9, 4 }, }); AssertIsSolved(puzzle, solution); }
public void HiddenPairTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Hidden_Candidates { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 9, 0, 4, 6, 0, 7, 0, 0, 0 }, { 0, 7, 6, 8, 0, 4, 1, 0, 0 }, { 3, 0, 9, 7, 0, 1, 0, 8, 0 }, { 0, 0, 8, 0, 0, 0, 3, 0, 0 }, { 0, 5, 0, 3, 0, 8, 7, 0, 2 }, { 0, 0, 7, 5, 0, 2, 6, 1, 0 }, { 0, 0, 0, 4, 0, 3, 2, 0, 8 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 2); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 7].CanBe, 9); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 8].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 8].CanBe, 4); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 8].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 8].CanBe, 9); }
public void NakedTripleTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Naked_Candidates { 0, 7, 0, 4, 0, 8, 0, 2, 9 }, { 0, 0, 2, 0, 0, 0, 0, 0, 4 }, { 8, 5, 4, 0, 2, 0, 0, 0, 7 }, { 0, 0, 8, 3, 7, 4, 2, 0, 0 }, { 0, 2, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 3, 2, 6, 1, 7, 0, 0 }, { 0, 0, 0, 0, 9, 3, 6, 1, 2 }, { 2, 0, 0, 0, 0, 0, 4, 0, 3 }, { 1, 3, 0, 6, 4, 2, 0, 7, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 0].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 0].CanBe, 9); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 2].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 2].CanBe, 9); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 6].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 6].CanBe, 8); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 6].CanBe, 9); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 7].CanBe, 5); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 7].CanBe, 8); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 7].CanBe, 9); }
public void TestEquals() { SudokuDifficulty newDifficulty = SudokuPuzzleTest.Difficulty == SudokuDifficulty.None ? SudokuDifficulty.Easy : SudokuDifficulty.None; SudokuPuzzle puzzle = new SudokuPuzzle(this.Sudoku.Size, newDifficulty); SudokuGenerator.AddNumbers(puzzle); for (int i = 0; i < this.Sudoku.Size; i++) { for (int j = 0; j < this.Sudoku.Size; j++) { this.Sudoku[i, j] = puzzle[i, j]; } } Assert.AreEqual(this.Sudoku, puzzle); Assert.IsTrue(this.Sudoku.Equals(puzzle)); Assert.IsTrue(this.Sudoku == puzzle); Assert.IsFalse(this.Sudoku != puzzle); Assert.IsFalse(this.Sudoku == null); Assert.IsFalse(null == this.Sudoku); SudokuPuzzle nullPuzzle = null; Assert.IsTrue(null == nullPuzzle); this.Sudoku[0, 0] = 0; Assert.AreNotEqual(this.Sudoku, puzzle); }
static SudokuPuzzleTest() { try { if (File.Exists("vars.txt")) { SudokuPuzzleTest.ParseFile("vars.txt"); } else if (File.Exists("Variables.txt")) { SudokuPuzzleTest.ParseFile("Variables.txt"); } else { throw new Exception(); } } catch { SudokuPuzzleTest.Difficulty = SudokuPuzzleTest.DefaultDifficulty; SudokuPuzzleTest.Size = SudokuPuzzleTest.DefaultSize; } Assert.AreNotEqual(SudokuPuzzleTest.Difficulty, SudokuDifficulty.None, "Difficulty must not be None"); Assert.IsTrue(SudokuPuzzle.VerifySize(SudokuPuzzleTest.Size), "Size must be a positive, square integer"); }
public void LockedCandidatesPointingInColumnTest() { var sudoku = new[, ] { // From: https://sudoku9x9.com/locked_candidates.html { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 3, 0, 0, 0 }, { 0, 5, 6, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[3, 0].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[4, 0].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[5, 0].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 0].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 0].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[8, 0].CanBe, 3); }
public async Task <IHttpActionResult> DeleteSudokuPuzzle(int id) { SudokuPuzzle sudokuPuzzle = await db.SudokuPuzzles.FindAsync(id); if (sudokuPuzzle == null) { return(NotFound()); } db.SudokuPuzzles.Remove(sudokuPuzzle); try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { return(StatusCode(HttpStatusCode.InternalServerError)); } catch (Exception) { return(StatusCode(HttpStatusCode.InternalServerError)); } return(Ok(sudokuPuzzle)); }
public bool HasSudokuUniqueSolution(SudokuPuzzle sudoku) { // sudokus with 16 or less determinded fields cannot have a unique solution // source: https://www.technologyreview.com/s/426554/mathematicians-solve-minimum-sudoku-problem/ bool ret = (sudoku.GetSetFields()?.Count > 16); if (ret) { // solve sudoku (gets one solution out of possibly many solutions) var solution = SolveSudoku(sudoku); ret = (solution != null); if (ret) { var temp = (SudokuPuzzle)sudoku.Clone(); // go through all empty fields (filled out fields are ignored) while (ret && !temp.IsSolved()) { // choose a free field with a minimum amount of remaining possibilities int minPossibleValuesCount = temp.GetFreeFields().Select(x => x.GetPossibleValuesCount()).Min(); var field = temp.GetFreeFields().Where(x => x.GetPossibleValuesCount() == minPossibleValuesCount).ChooseRandom(); // check if the field is determined; if not, there is a second solution => return false ret = isFieldDetermined(temp, solution, field); // apply the determined value to the sudoku => less possibilities field.SetValue(solution.Fields[field.RowIndex, field.ColumnIndex].Value); } } } return(ret); }
protected SudokuPuzzle guessNextField(SudokuPuzzle sudoku, SudokuField field) { SudokuPuzzle result = null; foreach (int value in field.GetPossibleValues().Shuffle()) { // make copy of sudoku and try out possibility var copy = (SudokuPuzzle)sudoku.Clone(); copy.Fields[field.RowIndex, field.ColumnIndex].SetValue(value); if (copy.IsValid()) { // go to next recursion level result = solveSudokuRecursive(copy); // pass correct solution to lower recursion levels if (result != null) { break; } } } return(result); }
public async Task <IHttpActionResult> PostSudokuPuzzle(SudokuPuzzle sudokuPuzzle, int userId) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } RegisterUser user = await db.RegisterUsers.FindAsync(userId); if (user == null) { return(StatusCode(HttpStatusCode.NotFound)); } sudokuPuzzle.RegisterUsers.Add(user); db.SudokuPuzzles.Add(sudokuPuzzle); try { await db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { return(StatusCode(HttpStatusCode.InternalServerError)); } catch (Exception) { return(StatusCode(HttpStatusCode.InternalServerError)); } return(StatusCode(HttpStatusCode.OK)); }
public void NakedPairTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Naked_Candidates { 4, 0, 0, 0, 0, 0, 9, 3, 8 }, { 0, 3, 2, 0, 9, 4, 1, 0, 0 }, { 0, 9, 5, 3, 0, 0, 2, 4, 0 }, { 3, 7, 0, 6, 0, 9, 0, 0, 4 }, { 5, 2, 9, 0, 0, 1, 6, 7, 3 }, { 6, 0, 4, 7, 0, 3, 0, 9, 0 }, { 9, 5, 7, 0, 0, 8, 3, 0, 0 }, { 0, 0, 3, 9, 0, 0, 4, 0, 0 }, { 2, 4, 0, 0, 3, 0, 7, 0, 9 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 3].CanBe, 1); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 4].CanBe, 1); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 4].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 5].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 0].CanBe, 1); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 0].CanBe, 7); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 4].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 4].CanBe, 7); }
public void NakedPairTest2() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Naked_Candidates { 0, 8, 0, 0, 9, 0, 0, 3, 0 }, { 0, 3, 0, 0, 0, 0, 0, 6, 9 }, { 9, 0, 2, 0, 6, 3, 1, 5, 8 }, { 0, 2, 0, 8, 0, 4, 5, 9, 0 }, { 8, 5, 1, 9, 0, 7, 0, 4, 6 }, { 3, 9, 4, 6, 0, 5, 8, 7, 0 }, { 5, 6, 3, 0, 4, 0, 9, 8, 7 }, { 2, 0, 0, 0, 0, 0, 0, 1, 5 }, { 0, 1, 0, 0, 5, 0, 0, 2, 0 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[0, 3].CanBe, 7); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 3].CanBe, 7); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 5].CanBe, 1); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[1, 5].CanBe, 2); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[2, 3].CanBe, 7); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 2].CanBe, 7); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 4].CanBe, 3); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 4].CanBe, 7); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[8, 2].CanBe, 7); }
private static SudokuPuzzle getEasyTestSudoku() { var sudoku = new SudokuPuzzle(); sudoku.Fields[0, 6].SetValue(1); sudoku.Fields[0, 7].SetValue(9); sudoku.Fields[1, 0].SetValue(2); sudoku.Fields[1, 1].SetValue(3); sudoku.Fields[1, 6].SetValue(6); sudoku.Fields[2, 3].SetValue(2); sudoku.Fields[2, 4].SetValue(4); sudoku.Fields[3, 6].SetValue(9); sudoku.Fields[3, 7].SetValue(6); sudoku.Fields[4, 3].SetValue(1); sudoku.Fields[4, 4].SetValue(6); sudoku.Fields[4, 7].SetValue(7); sudoku.Fields[5, 1].SetValue(4); sudoku.Fields[5, 2].SetValue(8); sudoku.Fields[5, 4].SetValue(7); sudoku.Fields[6, 2].SetValue(7); sudoku.Fields[6, 5].SetValue(3); sudoku.Fields[6, 6].SetValue(4); sudoku.Fields[6, 8].SetValue(5); sudoku.Fields[7, 2].SetValue(9); sudoku.Fields[7, 5].SetValue(8); sudoku.Fields[8, 2].SetValue(6); sudoku.Fields[8, 5].SetValue(5); sudoku.Fields[8, 6].SetValue(8); return(sudoku); }
public SingleStepSolution SolveSingleStep(SudokuPuzzle sudokuPuzzle) { foreach (var row in sudokuPuzzle.Rows) { var rowSolution = GetHiddenSingle(sudokuPuzzle, row.Cells); if (rowSolution != null) { return(rowSolution); } } foreach (var column in sudokuPuzzle.Columns) { var columnSolution = GetHiddenSingle(sudokuPuzzle, column.Cells); if (columnSolution != null) { return(columnSolution); } } foreach (var block in sudokuPuzzle.Blocks) { var blockSolution = GetHiddenSingle(sudokuPuzzle, block.Cells.OfType <Cell>().ToArray()); if (blockSolution != null) { return(blockSolution); } } return(null); }
public SudokuPuzzle GenerateSudoku(SudokuDifficuty difficulty, int length = 9) { // get randomly filled out sudoku SudokuPuzzle solution = SolveSudoku(new SudokuPuzzle()); SudokuPuzzle sudoku = (SudokuPuzzle)solution.Clone(); // check how many fields need to be removed (depending on desired difficulty) int fieldsToRemove = ((length * length) - (int)difficulty); while (fieldsToRemove > 0) { int freeFieldsCount = sudoku.GetFreeFields().Count; foreach (var field in sudoku.GetSetFields().Shuffle()) { if (fieldsToRemove > 0 && isFieldDetermined(sudoku, solution, field.RowIndex, field.ColumnIndex)) { field.SetValue(0); fieldsToRemove--; } } // check if progress was made (if not => try with another sudoku puzzle) if ((freeFieldsCount - sudoku.GetFreeFields().Count) == 0) { sudoku = GenerateSudoku(difficulty, length); break; } } // check if the generated sudoku is unique. if not create a new one. return((HasSudokuUniqueSolution(sudoku)) ? sudoku : GenerateSudoku(difficulty, length)); }
/// <summary> /// <see cref="ISearchAgent"/> ProcessVariables event handler. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <inheritdoc /> protected override void OnProcessVariables(object sender, ProcessVariablesEventArgs e) { ISudokuPuzzle candidate = new SudokuPuzzle(); // In this case we know that there is a Single Aspect. var aspect = Aspects.SingleOrDefault(); Assert.NotNull(aspect); for (var row = MinimumValue; row < MaximumValue; row++) { for (var col = MinimumValue; col < MaximumValue; col++) { // ReSharper disable once PossibleNullReferenceException candidate[row, col] = (int)aspect.Cells[row, col].Value(); } } /* If we're here processing variables, it should be because we are processing the next * solution. However, in the event we still do not have a solution, then simply return. */ // TODO: TBD: we really should never land here I don't think... if (candidate.IsSolved) { Solution = candidate; // False is the default, so only mark whether ShouldBreak when we have one. e.ShouldBreak = true; } base.OnProcessVariables(sender, e); }
public void HiddenQuadTest1() { var sudoku = new[, ] { // From: http://www.sudokuwiki.org/Hidden_Candidates { 6, 5, 0, 0, 8, 7, 0, 2, 4 }, { 0, 0, 0, 6, 4, 9, 0, 5, 0 }, { 0, 4, 0, 0, 2, 5, 0, 0, 0 }, { 5, 7, 0, 4, 3, 8, 0, 6, 1 }, { 0, 0, 0, 5, 0, 1, 0, 0, 0 }, { 3, 1, 0, 9, 0, 2, 0, 8, 5 }, { 0, 0, 0, 8, 9, 0, 0, 1, 0 }, { 0, 0, 0, 2, 1, 3, 0, 0, 0 }, { 1, 3, 0, 7, 5, 0, 0, 9, 8 } }; var sudokuPuzzle = new SudokuPuzzle(sudoku); SolveUsingStrategy(sudokuPuzzle, _strategy); // manual adaptation of CanBe so HiddenQuad can be applied sudokuPuzzle.Cells[2, 6].CanBe.Remove(9); sudokuPuzzle.Cells[4, 6].CanBe.Remove(2); sudokuPuzzle.Cells[4, 6].CanBe.Remove(9); sudokuPuzzle.Cells[6, 6].CanBe.Remove(2); sudokuPuzzle.Cells[6, 6].CanBe.Remove(4); sudokuPuzzle.Cells[8, 6].CanBe.Remove(4); SolveUsingStrategy(sudokuPuzzle, _strategy); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[6, 6].CanBe, 6); CollectionAssert.DoesNotContain(sudokuPuzzle.Cells[7, 6].CanBe, 6); }
public SingleStepSolution SolveSingleStep(SudokuPuzzle sudokuPuzzle) { var eliminations = new List <SingleStepSolution.Candidate>(); foreach (var row in sudokuPuzzle.Rows) { var cells = row.Cells; eliminations.AddRange(GetEliminations(cells)); } foreach (var column in sudokuPuzzle.Columns) { var cells = column.Cells; eliminations.AddRange(GetEliminations(cells)); } foreach (var block in sudokuPuzzle.Blocks) { var cells = block.Cells.OfType <Cell>().ToArray(); eliminations.AddRange(GetEliminations(cells)); } return(eliminations.Count > 0 ? new SingleStepSolution(eliminations.Distinct().ToArray(), StrategyName) : null); }
private void SaveSudokuUsingSeparator(int[,] sudoku, string separator, string filePath) { var sudokuToString = new SudokuPuzzle(sudoku).ToString(); var sudokuToStringWithSeparator = sudokuToString.Replace(" ", separator); File.AppendAllText(filePath, sudokuToStringWithSeparator); }
static bool CheckPuzzle(SudokuPuzzle puzzle) { foreach(SudokuItem[] row in puzzle.Item){ foreach (SudokuItem item in row) { if (item.Val == 0) return false; } } return true; }
static SudokuPuzzle SolvePuzzle(SudokuPuzzle puzzle, int startRow, int startColumn) { // 开始解谜题 while (true) { if (puzzle.IsSolved) break; int j = startColumn; for (int i = startRow; i < 9; i++) { for (; j < 9; j++) { if (puzzle.Item[i][j].IsConfirmed) continue; List<int> possibleVals = puzzle.Item[i][j].GetPossibleVals(); for (int k = 0; k < possibleVals.Count; k++) { puzzle.Item[i][j].IsConfirmed = true; puzzle.Item[i][j].Val = possibleVals[k]; puzzle.PrintPuzzle(); if (!CheckPuzzle(puzzle)) { puzzle.Item[i][j].IsConfirmed = false; puzzle.Item[i][j].Val = 0; puzzle.PrintPuzzle(); if (k == possibleVals.Count - 1) return puzzle; continue; } int nextRow = startRow; int nextColumn = startColumn + 1; if (nextColumn >= 9) { nextRow = nextRow + 1; nextColumn = 0; } if (nextRow < 9) { puzzle = SolvePuzzle(puzzle, nextRow, nextColumn); } } } j = 0; } } return puzzle; }
static List<SudokuPuzzle> LoadPuzzles() { List<SudokuPuzzle> puzzles = new List<SudokuPuzzle>(); string str = FileReader.ReadFile("p096_sudoku.txt"); string[] strArray = str.Split('\n'); for (int i = 0; i < strArray.Length; i += 10) { if (!strArray[i].Contains("Grid")) { continue; } SudokuPuzzle puzzle = new SudokuPuzzle(); puzzle.Item = new SudokuItem[9][]; for (int j = 0; j < 9; j++) { puzzle.Item[j] = new SudokuItem[9]; int lineIndex = j + i + 1; for (int k = 0; k < 9; k++) { puzzle.Item[j][k] = new SudokuItem(); puzzle.Item[j][k].ColumnIndex = k; puzzle.Item[j][k].RowIndex = j; int val = int.Parse(strArray[lineIndex].Substring(k, 1)); puzzle.Item[j][k].IsConfirmed = (val != 0); puzzle.Item[j][k].Val = val; if (puzzle.Item[j][k].IsConfirmed) continue; for (int n = 1; n < 10; n++) { puzzle.Item[j][k].AddPossibleVal(n); } } } puzzles.Add(puzzle); } return puzzles; }
static SudokuPuzzle ClearPossiblesForACell(int i, int j, SudokuPuzzle puzzle) { // 读取一个值,如果此值为0,则继续下一个 int currVal = puzzle.Item[i][j].Val; if (currVal == 0) return puzzle; // 清除根据此值可以排除的值 // 清除同行的值 int row = i; int col = 0; for (col = 0; col < 9; col++) { if (col == j) continue; SudokuItem tempItem = puzzle.Item[row][col]; if (tempItem.Val == currVal) throw new Exception("同一行有相同值"); if (tempItem.IsConfirmed) continue; tempItem.RemoviePossibleVal(currVal); } // 清除同列的值 col = j; for (row = 0; row < 9; row++) { if (row == i) continue; SudokuItem tempItem = puzzle.Item[row][col]; if (tempItem.Val == currVal) throw new Exception("同一列有相同值"); if (tempItem.IsConfirmed) continue; tempItem.RemoviePossibleVal(currVal); } // 清除同块的值 col = j / 3; row = i / 3; int rowTml = (row + 1) * 3; int colTml = (col + 1) * 3; for (int tr = row * 3; tr < rowTml; tr++) { for (int tc = col * 3; tc < colTml; tc++) { if (tr == i && tc == j) continue; SudokuItem tempItem = puzzle.Item[tr][tc]; if (tempItem.Val == currVal) throw new Exception("同一框有相同值"); if (tempItem.IsConfirmed) continue; tempItem.RemoviePossibleVal(currVal); } } return puzzle; }
private void Solve(SudokuPuzzle puzzle, string input, string expected) { var state = SudokuState.Parse(input); var solver = new SudokuSolver(puzzle); var sw = Stopwatch.StartNew(); var actual = solver.Solve(state); sw.Stop(); Console.WriteLine("Elapsed: {0:#,##0.#####} ms", sw.Elapsed.TotalMilliseconds); Assert.IsTrue(actual.IsSolved, "The puzzle is not solved."); Assert.AreEqual(SudokuState.Parse(expected), actual); }
private SudokuPuzzle internalGenerate(int desiredRatingLevel, long initialSeed) { // validate the passed-in desired rating level: if ((desiredRatingLevel < 0) && (desiredRatingLevel >= RatingsByLevel.Length)) desiredRatingLevel = 0; RatingLimits RL = RatingsByLevel[desiredRatingLevel]; SudokuPuzzle p = new SudokuPuzzle(); p.DesiredRatingLevel = desiredRatingLevel; p.Seed = initialSeed; p.NumHints = 0; // Find a Sudoku having a rating within a specified rating interval. // Do it by generating multiple samples and examining them. // Continue until an appropriate puzzle is found. // Sometimes we need to iterate over multiple sets of puzzles. // Iteration doesn't make sense though, if there is an initialSeed // provided. So we set the loopLimit appropriately. int loopLimit = (initialSeed == 0) ? MaxGenerateLoops : 1; for (int tries = 0; tries < loopLimit; tries++, System.Threading.Thread.Sleep(20)) { long actualSeed = (initialSeed == 0) ? System.DateTime.Now.Ticks : initialSeed; string[] puzzles = _generator.GeneratePuzzleSet((int)actualSeed, SampleSetSize); for (var i = 0; i < SampleSetSize; i++) { // get the rating long rating = _generator.Rate(puzzles[i].Replace("\n", string.Empty).Trim()); if ((i == 0) || RL.Delta(rating) < p.Delta) { p.ActualRating = rating; p.StringRep = puzzles[i]; p.Seed = actualSeed; p.Delta = RL.Delta(rating); } } if (RL.WithinRange(p.ActualRating)) { return p; } } return p; }