/// <summary> /// A Digit in one of his peers is set. /// </summary> /// <remarks> /// Check if digit is possible in this house. /// </remarks> /// <param name="digit"></param> /// <param name="sudokuResult"></param> /// <returns></returns> internal override bool SetDigit(int digit, SudokuLog sudokuResult) { var sudokuEvent = new SudokuEvent { Value = digit, SolveTechnik = "SetDigit", ChangedCellBase = this, Action = CellAction.SetDigitInt }; var ok = true; var newBaseValue = Consts.BASESTART; var m = new HashSet <int>(); foreach (var cell in _cells) { if (cell.Digit > 0) { if (m.Contains(cell.Digit)) { ok = false; break; } else { m.Add(cell.Digit); newBaseValue -= (1 << (cell.Digit - 1)); } } } if (!ok) { var resultError = sudokuResult.CreateChildResult(); resultError.EventInfoInResult = sudokuEvent; resultError.Successful = false; resultError.ErrorMessage = "Digit " + digit + " is in CellContainer not possible"; return(true); } _candidateValueInternal = newBaseValue; var result = sudokuResult.CreateChildResult(); result.EventInfoInResult = new SudokuEvent { ChangedCellBase = this, Action = CellAction.SetDigitInt, SolveTechnik = "None", Value = digit, }; foreach (var cell in _cells) { cell.RemoveCandidate(digit, result); } return(true); }
public void CheckLastDigit_returns_false_when_not_last_candidate_after_create_Test() { var target = new Cell(0); SudokuLog sudokuResult = null; var expected = false; var actual = target.CheckLastDigit(sudokuResult); Assert.AreEqual(expected, actual); }
public SudokuLog CreateChildResult() { SudokuLog child = new SudokuLog { ParentSudokuResult = this }; this.ChildSudokuResult.Add(child); return(child); }
public void SetDigit_return_true_when_digit_was_set_Test() { var target = new Cell(0); var digitFromOutside = 1; var sudokuResult = new SudokuLog(); var expected = true; bool actual; actual = target.SetDigit(digitFromOutside, sudokuResult); Assert.AreEqual(expected, actual); }
public void RemoveCandidate_BaseValue_changes_when_candidate_removes_Test() { var target = new Cell(0); var digit = 1; var sudokuResult = new SudokuLog(); var expected = true; bool actual; actual = target.RemoveCandidate(digit, sudokuResult); Assert.AreEqual(expected, actual); }
/// <summary> /// Solves Sudoku with SolveTechniques (no Backtracking). /// </summary> /// <param name="sudokuResult">Log</param> public bool Solve(SudokuLog sudokuResult) { var tmpSudokuResult = sudokuResult; if (tmpSudokuResult == null) { tmpSudokuResult = new SudokuLog(); } do { _keepGoingWithChecks = false; for (var containerIdx = 0; containerIdx < Consts.DIMENSIONSQUARE; containerIdx++) { for (var containerType = 0; containerType < 3; containerType++) { if (_container[containerIdx][containerType].IsComplete()) { continue; } if (_solveTechniques != null && _solveTechniques.Length > 0) { foreach (var st in _solveTechniques) { if (st.IsActive) { if (!_container[containerIdx][containerType].ReCheck && st.CellView == ECellView.OnlyHouse) { continue; } try { st.SolveHouse(this, _container[containerIdx][containerType], tmpSudokuResult); } catch { return(false); } if (!tmpSudokuResult.Successful) { return(false); } } } } _container[containerIdx][containerType].ReCheck = false; } } } while (_keepGoingWithChecks); return(tmpSudokuResult.Successful); }
public SudokuLog Backtracking() { var tmpSudokuResult = new SudokuLog(); if (!BacktrackingContinue((Board)Clone())) { tmpSudokuResult.Successful = false; tmpSudokuResult.ErrorMessage = "Sudoku hat keine Lösung"; } return(tmpSudokuResult); }
public void CheckLastDigit_returns_false_when_not_last_candidate_Test() { var target = new Cell(0); SudokuLog sudokuResult = null; var expected = false; target.CheckLastDigit(sudokuResult); for (var x = 0; x < Consts.DIMENSIONSQUARE - 3; x++) { for (var y = x + 1; y < Consts.DIMENSIONSQUARE - 2; y++) { var newBaseValue = (1 << x) | (1 << y); target.CandidateValue = newBaseValue; var actual = target.CheckLastDigit(sudokuResult); Assert.AreEqual(expected, actual); } } }
public void RemoveCandidate_checks_lastcandidate_Test() { var id = 0; var target = new Cell(id) { CandidateValue = 7 }; var sudokuResult = new SudokuLog(); var expected = true; bool actual; actual = target.RemoveCandidate(1, sudokuResult); Assert.AreEqual(expected, actual); actual = target.RemoveCandidate(2, sudokuResult); Assert.AreEqual(expected, actual); expected = false; actual = target.RemoveCandidate(3, sudokuResult); Assert.AreEqual(expected, actual); Assert.AreEqual(3, target.Digit); }
public void Solve_Sudoku_solved_with_3_solvetechniques_and_without_backtracking_Test() { var board = new Board(_solveTechniques); var simpleSudoku = @"030050040 008010500 460000012 070502080 000603000 040109030 250000098 001020600 080060020"; var lines = simpleSudoku.Split('\n'); for (var y = 0; y < 9; y++) { var line = lines[y]; for (var x = 0; x < 9; x++) { var currChar = line[x]; if (currChar.Equals('0')) { continue; } var result = board.SetDigit(y, x, Convert.ToInt32(currChar) - 48); Assert.IsTrue(result.Successful); } } var sudokuResult = new SudokuLog(); Assert.IsFalse(board.IsComplete()); Assert.IsTrue(sudokuResult.Successful); board.Solve(sudokuResult); Assert.IsTrue(board.IsComplete()); Assert.IsTrue(sudokuResult.Successful); }
/// <summary> /// Set a digit at cell. /// </summary> /// <param name="cellID">ID of cell</param> /// <param name="digitToSet">Set Digit to Cell</param> /// <param name="withSolve">true = Start solving with every solvetechnique (without backtrack) after digit was set.</param> public SudokuLog SetDigit(int cellID, int digitToSet, bool withSolve) { var sudokuResult = new SudokuLog { EventInfoInResult = new SudokuEvent { ChangedCellBase = null, Action = CellAction.SetDigitInt, SolveTechnik = "SetDigit", } }; if (cellID < 0 || cellID > _cells.Length) { sudokuResult.Successful = false; sudokuResult.ErrorMessage = "Cell " + cellID + " is not in range"; return(sudokuResult); } sudokuResult.EventInfoInResult.ChangedCellBase = _cells[cellID]; _cells[cellID].SetDigit(digitToSet, sudokuResult); if (sudokuResult.Successful) { _cells[cellID].IsGiven = true; if (withSolve) { Solve(sudokuResult); } _history.Add(new SudokuHistoryItem(this, _cells[cellID], sudokuResult)); } else { SetHistory(_history.Count - 1); _cells[cellID].RemoveCandidate(digitToSet, sudokuResult); } return(sudokuResult); }
public void TestHardestData_Test() { IBoard <Cell> board = new Board(new DE.Onnen.Sudoku.SolveTechniques.HiddenPairTripleQuad <Cell>(), new DE.Onnen.Sudoku.SolveTechniques.LockedCandidates <Cell>(), new DE.Onnen.Sudoku.SolveTechniques.NakedPairTrippleQuad <Cell>()); var source = TestRessources.top95; var i = 0; for (i = 0; i < 2; i++) { IList <string> boards = source.Split('\n'); var emh = new int[3]; var total = 0; foreach (var line in boards) { if (line.Length < 81) { continue; } total++; var currentLine = "---"; try { currentLine = line.Substring(0, 81).Replace('.', '0'); board.SetCellsFromString(currentLine); } catch (Exception ex) { Assert.Fail($"Error in line{total} : {currentLine} " + ex.Message); continue; } if (board.IsComplete()) { emh[0] += 1; } else { var result = new SudokuLog(); board.Solve(result); if (board.IsComplete()) { emh[1] += 1; } else { result = board.Backtracking(); if (!board.IsComplete() || !result.Successful) { Assert.Fail("Board is not solved"); } else { emh[2] += 1; } } } } source = TestRessources.HardestDatabase110626; board = new Board(); Assert.AreEqual(total, emh.Sum(x => x)); Assert.IsTrue(total > 10); } Assert.AreEqual(i, 2); }