diff --git a/SudoScript.Core.Test/SolverTests.cs b/SudoScript.Core.Test/SolverTests.cs
index 5797310..a0281b4 100644
--- a/SudoScript.Core.Test/SolverTests.cs
+++ b/SudoScript.Core.Test/SolverTests.cs
@@ -6,17 +6,7 @@ namespace SudoScript.Core.Test;
internal sealed class SolverTests
{
- [Test()]
- public void CanSolveEmptySudoku()
- {
- Board board = Util.CreateStandardEmpty();
- Assert.DoesNotThrow(() => board = Solver.Solve(board));
- Assert.IsTrue(board.ValidateRules());
- Assert.IsFalse(board.Cells().Any(c => c.Digit == Cell.EmptyDigit));
- }
-
- [Test]
- public void CanSolveGeneratedSudoku()
+ public Board CreateEasyBoard()
{
Board board = Util.CreateStandardEmpty();
// Sudoku givens generated by https://sudoku.com/
@@ -39,6 +29,7 @@ public void CanSolveGeneratedSudoku()
board[8, 4].Digit = 8;
board[3, 5].Digit = 4;
+ board[4, 7].Digit = 2;
board[3, 6].Digit = 6;
board[5, 6].Digit = 7;
@@ -50,6 +41,7 @@ public void CanSolveGeneratedSudoku()
board[8, 7].Digit = 3;
board[9, 7].Digit = 5;
+ board[3, 9].Digit = 1;
board[2, 8].Digit = 9;
board[4, 8].Digit = 7;
board[5, 8].Digit = 4;
@@ -59,6 +51,23 @@ public void CanSolveGeneratedSudoku()
board[7, 9].Digit = 9;
board[8, 9].Digit = 7;
+ return board;
+ }
+
+ [Test()]
+ public void CanSolveEmptySudoku()
+ {
+ Board board = Util.CreateStandardEmpty();
+ Assert.DoesNotThrow(() => board = Solver.Solve(board));
+ Assert.IsTrue(board.ValidateRules());
+ Assert.IsFalse(board.Cells().Any(c => c.Digit == Cell.EmptyDigit));
+ }
+
+ [Test]
+ public void CanSolveGeneratedSudoku()
+ {
+ Board board = CreateEasyBoard();
+
Console.WriteLine(board.ToString());
Console.WriteLine("-------------------------------------------------");
@@ -68,4 +77,21 @@ public void CanSolveGeneratedSudoku()
Console.WriteLine(board.ToString());
}
+
+ [Test]
+ public void IsSatisfactoryTest()
+ {
+ Board board = CreateEasyBoard();
+
+ Assert.IsTrue(Solver.IsSatisfactory(board));
+ }
+
+ [Test]
+ public void IsNotSatisfactoryTest()
+ {
+ Board board = Util.CreateStandardEmpty();
+
+ Assert.IsFalse(Solver.IsSatisfactory(board));
+ }
+
}
diff --git a/SudoScript.Core/Solver.cs b/SudoScript.Core/Solver.cs
index ffcccf0..4bc9726 100644
--- a/SudoScript.Core/Solver.cs
+++ b/SudoScript.Core/Solver.cs
@@ -20,7 +20,7 @@ public static Board Solve(Board board)
private static bool SolveRec(Board board, [NotNullWhen(true)] out Board? solvedBoard)
{
- // Eliminate candidates from all rules untill nothing changes.
+ // Eliminate candidates from all rules until nothing changes.
while (board.EliminateCandidates()) ;
// We hit an invalid state, and must backtrack.
@@ -42,14 +42,14 @@ private static bool SolveRec(Board board, [NotNullWhen(true)] out Board? solvedB
orderedCells = orderedCells.SkipWhile(c => c.CandidateCount <= 1);
// The first cell contains the smallest amount of candidates.
int lowestCandidateCount = orderedCells.FirstOrDefault()?.CandidateCount ?? 1;
- // Take all cells with the least amount of candidates.
- orderedCells = orderedCells.TakeWhile(c => c.CandidateCount == lowestCandidateCount);
// If there are no cells with more than 1 candidate, the board is solved.
if (lowestCandidateCount == 1)
{
solvedBoard = board;
return true;
}
+ // Take all cells with the least amount of candidates.
+ orderedCells = orderedCells.TakeWhile(c => c.CandidateCount == lowestCandidateCount);
Cell cell = orderedCells.First();
foreach (int candidate in cell.Candidates())
@@ -76,9 +76,17 @@ public static Board GenerateSolveable(Board board)
throw new NotImplementedException();
}
- public static bool IsSatisfactory(Board board)
+ ///
+ /// Checks if the board can be solved by just using the EliminateCandidates methods from units.
+ ///
+ ///
+ /// True if the board can be solved without trial and error guessing.
+ public static bool IsSatisfactory(Board board) // Certain methods for eliminating candidates using inference are not currently implemented. Implementing them would make this function more acurate.
{
- throw new NotImplementedException();
+ // Eliminate candidates from all rules untill nothing changes.
+ while (board.EliminateCandidates());
+ // If the board is solved, it does not require trial and error.
+ return board.IsSolved();
}
public static bool IsProper(Board board)